Local-first Wi-Fi flight recorder

Know why Wi-Fi failed — even after it recovered.

The outage ends before you get to the keyboard, and every tool you own now reports that the network is fine. RadioChron was already recording. It keeps a continuous chronicle of radio, association, addressing and path state, then hands you the minute it broke and the reason it broke.

radiochron — recording
$ npx radiochron record --label office
[i] core 0.6 · ring buffer 512 MiB · retention 72h
[i] iface wlan0 · Office_AP_5G · ch 149 · -62 dBm
[i] chronicle open: ~/.radiochron/2026-09-08_11-42-11
$ radiochron verdict --at 11:53
VERDICT roam_failure (confidence 0.91)
11:52:58 RSSI -84 dBm on Office_AP_5G, no candidate scan
11:53:04 assoc request to Office_AP_6E → timeout ×3
11:53:12 DHCP renew failed, gateway unreachable 41s
11:53:53 reassociated, service restored
[i] 4 evidence rows · bundle: radiochron bundle --at 11:53

Verdict

A named cause, with the rows that prove it

"The Wi-Fi dropped" is not a diagnosis. The verdict engine correlates the radio layer with association, addressing and path evidence across the same timestamps, and reports the single most likely cause — plus what it ruled out and why.

  • Confidence is reported, never implied.
  • Every claim links to the chronicle rows behind it.
  • Alternate hypotheses are kept, ranked and explained.
  • Insufficient evidence is a valid, stated outcome.

Verdict report · 2026-09-08 11:53 UTC

Roam failure at cell edge

Confidence
0.91 — high
Trigger
RSSI -84 dBm sustained 6s with no scan result set
Failure
3 association timeouts to Office_AP_6E (ch 37)
Impact
41s without a usable default route
Ruled out
DHCP exhaustion, DNS, upstream ISP loss, host sleep
Suggested
Lower roam threshold; check 6 GHz min-RSSI on controller

Chronicle

Always recording, at a cost you can leave running

A flight recorder is only useful if it was already on. The chronicle is a fixed-size ring buffer of structured events on local disk — bounded bytes, bounded CPU, no background uploads, and no decision required from you before the incident happens.

Bounded by design

You set the size and retention window. The recorder never grows past it, so it can run for weeks on a laptop.

Structured, not raw

Events are typed rows with monotonic timestamps, so two layers can be compared without guessing clock drift.

Local by default

The chronicle is a directory on your disk. Export is an explicit command, not a background service.

What the chronicle records
LayerRecorded evidence
RadioRSSI, noise, channel, band, BSSID, roam attempts, per-frame retry counts
Associationauth, assoc, 4-way handshake timing, deauth reason codes
AddressingDHCP DISCOVER/OFFER/REQUEST/ACK, lease change, IPv6 RA, DNS resolve latency
Pathgateway and off-net reachability, RTT, loss bursts, MTU black holes
Hostinterface up/down, sleep/wake, VPN state, power source transitions

Surfaces

One recorder, six ways to reach it

CLI

npm radiochron 0.7

One binary-ish npm package. Start a recording, tail the chronicle, ask for a verdict, export a bundle.

Rust core

core 0.6

The recorder and verdict engine. Fixed-size ring buffer, deterministic parsing, no network calls of its own.

Agent

agent

A long-running collector for machines you do not sit in front of. Same chronicle format, same verdicts.

Desktop

Electron

A timeline you can scrub, with verdicts attached to the moment they happened. Signed builds per platform.

Fleet

fleet

Roll up verdicts across many recorders without shipping raw captures anywhere you did not choose.

MCP server

radiochron-mcp 0.7

Expose the chronicle and verdict engine as tools so an agent can investigate the outage with you.

MCP · radiochron-mcp 0.7

Let an agent read the evidence with you

The MCP server exposes the chronicle and the verdict engine as a small, stable tool surface. The agent runs on your machine, reads your local recordings, and cites the rows it used — the same rows you can open yourself.

chronicle.query
Return the recorded window around a timestamp, at the resolution you ask for.
verdict.explain
Name the most likely cause with confidence and the evidence rows behind it.
session.list
Enumerate recordings on this machine with duration and outcome.
bundle.export
Produce a redactable evidence bundle for a ticket or a vendor.
mcp client config
{
"mcpServers": {
"radiochron": {
"command": "npx",
"args": ["-y", "radiochron-mcp@0.7"],
"env": { "RADIOCHRON_HOME": "~/.radiochron" }
}
}
}
$ radiochron-mcp --list-tools
chronicle.query · verdict.explain · session.list · bundle.export

Straight talk

What RadioChron is not

It is not a packet capture tool.

RadioChron records state and events at a low fixed cost so it can run for days. If you need every byte on the air, use a sniffer — and RadioChron will tell you which minute to point it at.

A verdict is a hypothesis, not a court ruling.

Every verdict ships with confidence and the rows that produced it. When the evidence is thin, it says so instead of inventing a cause.

It cannot see inside your access point.

RadioChron watches from the client. Controller-side misconfiguration shows up as its symptom, not as its config diff.

There is no account and no telemetry.

Recordings stay on disk on the machine that made them. Nothing is uploaded unless you export a bundle yourself.

Roadmap

Where the versions are going

Shipping now

  • Rust core 0.6: ring-buffer recorder and verdict engine
  • CLI radiochron 0.7 on npm
  • radiochron-mcp 0.7 with four stable tools
  • Electron desktop app with scrubable timeline

In progress

  • Agent hardening for headless and always-on hosts
  • Fleet verdict roll-up without raw capture upload
  • 802.11 frame decode coverage for 6 GHz roaming edge cases
  • Signed and notarized builds on all three desktop platforms

Considered

  • Wired and cellular chronicles in the same timeline
  • Verdict plugins written in WASM
  • Optional self-hosted fleet dashboard

Start recording before the next outage

Install the CLI in a minute, or run the desktop app and leave it open. Either way the next failure comes with evidence.