1.1.0 2026-08-20
Added
- Per-hop MTR reaches the cloud. Each hop carries its loss classification as part of the row rather than as a rendering decision: whether a hop's loss persists downstream is a property of the whole trace, so a reader holding one row cannot recompute it. A hop arriving unclassified is refused at ingest, because the only thing left to render would be a bare percentage - the reading that gets an innocent transit provider blamed. Only the first propagating hop is marked as the culprit; everything downstream inherits the loss.
- Diurnal profile - a 7x24 weekday-hour grid. Cells recombine from counts, never from averaged rates, so a 12-probe window does not weigh as much as a 600-probe one, and bucketing happens in the subscriber's local zone, because a fixed offset is wrong twice a year in every DST zone and moves the evening peak into the wrong column. The worst hour is a ratio against the line's own median and is left unnamed below a coverage floor.
- Per-application usage on Windows, collected via ETW.
- Target packs - mode-specific host sets selected by id. The list is compiled in and the type deliberately does not implement
Deserialize, because constructing one from bytes is exactly the ability to name a host from outside the binary. Pack targets never join outage consensus, so a Discord outage is not reported as the subscriber's line going down. - On-site CDN and IP-transit checks, with HTTPS health checks alongside ICMP and MTR. One catalogue entry records that
www.netflix.comblocks ICMP by policy, so its ping failure is not read as a fault. - DoH resolver catalogue with filtering levels and a lowest-latency pick.
- User-defined watched hosts, labelled, visible on the desktop and in the cloud.
- Tiered providers and ticketing - bilateral
provider_linksinvited by the customer and accepted by the provider, escalation as a forward rather than a move, attach-time redaction against an allowlist, and an SLA clock that runs in business hours. - Crash reporting for the desktop app. Reports stay on the machine.
- The app now opens maximised.
POST /v1/admin/releases/fetchregisters a release by downloading it from its published URL and measuring it, rather than hashing a copy placed on the server by hand. Cutting a release no longer needs shell access to production. The digest still describes bytes the server received rather than a claim the caller made, which is the property that matters while the installer is unsigned.
Changed
- Dark is unconditional; light is an explicit opt-out. There is no
prefers-color-scheme: lightblock anywhere, so a visitor whose OS prefers light still gets the intended theme. The theme control lost its third "auto" state in the same change, because with the media query gone "auto" and "dark" selected identical pixels. - The chart palette is six series, not eight. The shipped values were measured against a CVD simulation rather than read: two of them sat adjacent at roughly half the required separation under deuteranopia - indistinguishable to about one man in twelve, and the exact defect the code comment claimed the ordering prevented. No seven-hue set clears all-pairs separation inside the required lightness band, so both palettes are now generated rather than chosen. A seventh series folds into an "Other" bucket or a second encoding channel.
- Installs to
C:\Program Files\Helix Internet Monitor, with a branded installer. - Gauges are determinate only when the wire carries a real fraction. The loss gauge refuses to draw an arc below 300 probes and shows counts instead; latency is graded against the line's own baseline, never an absolute scale.
- Release downloads are served from GitHub. The counted, rate-limited
/v1/downloads/himURL is unchanged - only what it redirects to moved.
Fixed
- A cross-organisation ticket could leak an internal article. The read predicate compared author and reader organisation without a non-null guard, and JavaScript's
null === nullis true where SQL'sNULL = NULLis not, so the two halves of the check disagreed. Unreachable in practice only because subscribers cannot author internal articles. - Loopback traffic was counted as internet usage by the ETW collector.
- Recovery notices were swallowed by the packet-loss cooldown, so a line coming back could go unannounced.
- Hop tables are never cropped. A
58vhcap on the desktop hid exactly the row nearest the fault. - The sign-in pages now say which password they want.
- Every
/v1/adminroute in the download area was unreachable. They callrequireSuperAdmin(), which reads a principal that only therequireUserpreHandler sets, and none of them registered it -- so release registration and the whole download console answered 401 to a valid super-admin token, looking exactly like a bad one. No behavioural test could have caught it: an anonymous request gets 401 either way, so the wiring is now pinned structurally and a missing principal raises a named error instead of impersonating an authentication failure. - The published release body began with a byte order mark, and its unsigned-installer warning was absorbed into the table above it by markdown, so the one paragraph that has to be seen rendered as a table row.
Security
- The subscriber sign-in identifier uses
autocomplete="username", which is what makes a password manager offer the saved Helix password rather than leaving the user to type a remembered - and often reused - one. - Release redirect targets are validated against a compiled-in host allowlist, on write and again on read.
/v1/downloads/himis public and unauthenticated and it hands out executables, so a free-text target would be an open redirect wearing the product's own domain.
Known limitations
- The installer is not code-signed. SmartScreen will show "Windows protected your PC" and Chrome will warn on download. Signing is blocked on a certificate whose key must live on FIPS 140-2 Level 2 hardware, a CA/Browser Forum requirement since June 2023. The published SHA-256 is the honest mitigation until then.
Method::SetTargetsis refused by the service pending an elevated confirmation flow.