RADIOCHRON v0.4
//: RADIO DIAGNOSTICS FOR MACHINES THAT CAN'T EXPLAIN THEMSELVES

The chronicle
of your radio_

RadioChron is a Rust Wi-Fi diagnostics and BLE history engine with an unattended agent, streaming Node API, MCP and desktop surfaces. It records what the radio actually did — associations, roams, drops, reason codes — and returns verdicts, not data dumps. A snapshot says “−58 dBm, fine”. The chronicle says why it wasn't fine ten minutes ago.

3DEPENDENCIES
13CRATES, WHOLE TREE
~1.9 MBSERVER BINARY
0C TOOLCHAIN NEEDED
# Rust library
$ cargo add radiochron

# Standalone Node library
$ npm install radiochron

# Unattended durable collector
$ cargo install radiochron-agent

# Separate MCP server package
$ claude mcp add radiochron -- npx -y radiochron-mcp
//: 01 — WHY IT DROPPED

History in, verdict out

RadioChron reads the Windows WLAN event log as structured, locale-independent data — numeric event IDs and reason codes, never localized message text — and separates roams from faults by ConnectionId continuity: a roam reuses the session id, a genuine reconnect allocates a new one. Security rekeys, resume-from-sleep and same-network roaming are suppressed instead of counted as failures.

{
  "id": "reconnect_loop",
  "severity": "critical",
  "title": "5 connection attempts and 5 failures in 120s",
  "detail": { "attempts": 5, "failures": 5, "successes": 0,
              "reason_codes": [229396, 229396, 229378] },
  "caveat": "Roams and rekeys are excluded by requiring distinct
             ConnectionIds and real failures. Reason codes are
             undocumented observations; treat unfamiliar ones as
             unknown rather than meaningful."
}
//: 02 — RECORD CHANGE, NOT POLLS

The chronicle recorder

A stable link polled every 2 seconds is 43,200 identical log lines a day. The chronicle writes one associated line and goes quiet until something changes: a roam, a drop, a signal shift beyond dB-hysteresis, a reason code in the event log. Storage is versioned append-only JSONL with built-in rotation — greppable, deduplication-safe, and a hard disk ceiling of ~4 MiB by default, sized for embedded flash, not workstations.

// pluggable Sink trait — the shipped sink is JSONL + rotation.
// a SQLite sink is ~30 lines in *your* crate; bundling one would
// drag in a C compile and break the bare-rustup build.
let sink = JsonlSink::open("chronicle.jsonl", RotationPolicy::default())?;
let mut rec = Recorder::new(sink, RecorderOptions::default());
rec.run_for(Duration::from_secs(3600))?;   // or own the loop: rec.step()

Change detector

Pure state machine, no OS calls. Roam ≠ drop-and-return; hysteresis absorbs driver noise. The same recorder runs on Windows, Linux and macOS.

Sink trait

NLog-style pluggable targets. JSONL ships; your database is your 30 lines. The core never grows a storage dependency.

Survives restarts

Appends, never truncates. Power loss costs the unflushed tail — not a database recovering mid-transaction.
//: 03 — BUILT FOR DEVICES

The IoT gap is the point

Field devices lose Wi-Fi constantly and can't say why. The Rust options that exist either shell out to netsh/iw and parse localized text, or resolve to a 51-crate tree that doesn't build on a bare rustup toolchain at all — its transitive dependencies want mingw or the Visual C++ build tools. On an embedded image that's the difference between adding a dependency and rebuilding the OS.

RadioChron hand-writes its FFI and resolves system libraries at runtime. No binding crates, no import libraries, no C. A device that only needs association state compiles just that: features are granular by capability. Linux talks to nl80211 over Generic Netlink directly — no iw parsing.

RADIOCHRON
13 crates
NEAREST EQUIVALENT
51 crates + C toolchain
# a sensor that only reports link state pulls exactly that:
radiochron = { version = "0.4", default-features = false, features = ["status"] }
# portable no_std BLE history; ESP-IDF can add the real NimBLE collector:
radiochron = { version = "0.4", default-features = false, features = ["embedded", "ble"] }
radiochron-esp-idf = { version = "0.2", features = ["nimble"] }
# status · scan · analyze · sample · history · record · connectivity · ble

Native on all three OS families

Windows Native WLAN, Linux nl80211 and macOS CoreWLAN collectors feed the same portable analysis and recorder APIs.

Beyond association

Radio, AP authentication, DHCP versus static IP, gateway, DNS, service TCP, captive portal, certificate validity, packet loss/jitter and Internet are separate stages. No public probe is contacted unless configured.
//: 04 — FIVE WAYS IN

One engine, five focused surfaces

Rust library

radiochron — collectors, 802.11 analysis, BLE identity/history detectors and the chronicle. What an IoT agent, ESP-IDF adapter, exporter or CLI embeds. The BLE model remains no_std + alloc. MIT/Apache-2.0. Source.

MCP server

radiochron-mcp — seventeen portable typed tools + six resources over stdio; Windows adds WLAN AutoConfig history. diagnose_incident orchestrates the chain and ble_scan observes native WinRT, BlueZ, or CoreBluetooth radio. MIT licensed. Source.

Node/npm library

The standalone package is the application API over the Rust core for Windows x64, Linux x64/ARM64, Intel Mac and Apple Silicon. It provides CommonJS and ESM, cancelable Wi-Fi/BLE/chronicle async streams, native scanning, a revision-checked adapter, and remains independent of MCP. Install from npm.

Unattended agent

radiochron-agent — an opt-in native Wi-Fi/BLE collector for gateways and edge boxes. It writes every versioned event to a durable offline spool before MQTT QoS 1 or OTLP export, exposes Prometheus health, and supports signed configuration/OTA without adding transport dependencies to core. Install and configure.

Desktop app

RadioChron Desktop — Windows/macOS baselines, shared Wi-Fi/Bluetooth RF map, 1/7/30-day presence patterns, OS-confirmed connected/paired links, unlinked radio observations, rich PDF evidence, channel pressure and network inventory. It imports radiochron-js; builds cover Windows x64, Intel Mac and Apple Silicon. Downloads and details.
//: 05 — RADIOCHRON DESKTOP

The radio evidence, on screen

Capture a baseline, inspect Wi-Fi and Bluetooth radios through the same pan/zoom/fullscreen RF map, merge radio evidence with paired or connected OS devices, correlate rotating private addresses with explicit confidence, and explore exact retained scans and 1/7/30-day patterns without sending telemetry anywhere.

RadioChron Desktop overview with synthetic Wi-Fi data
RadioChron Desktop relative RF map with synthetic access points
Relative RF map
RadioChron Desktop Wi-Fi evidence timeline, pulse watch and signal matrices
Wi-Fi Analytics
RadioChron Desktop Wi-Fi 1, 7 and 30-day sampled presence patterns
Wi-Fi presence patterns
RadioChron Desktop network controls with documentation-only addresses
Network evidence
RadioChron Desktop Bluetooth RF map with synthetic devices
Bluetooth RF map
RadioChron Desktop local Bluetooth node with connected and paired links
Confirmed Bluetooth links
RadioChron Desktop Bluetooth inventory with a connected mock mouse
Bluetooth devices
RadioChron Desktop Bluetooth evidence timeline and recurrence matrix
Bluetooth Analytics
RadioChron Desktop Bluetooth 1, 7 and 30-day presence patterns
Bluetooth presence patterns
RadioChron Desktop channel pressure view with synthetic access points
Channel pressure

All screenshots use invented SSIDs and beacons, locally administered MAC addresses and documentation-only IP ranges.

//: 05 — MCP SURFACE

Seventeen portable typed tools, honest about effects

toolanswers
diagnose_incidentone compact Wi-Fi, connectivity, history, chronicle and optional native BLE incident report
wifi_history“why did it drop earlier” — reconnect loops, an AP failing key exchange, credential mismatch // the headline
wifi_analyzefindings, not records: contention, weak signal, band-steering candidates — 802 bytes where the raw list costs 41 KB
wifi_sample“is it stable” — RSSI swing, roam count, drops over a bounded window
wifi_statusthe association right now: SSID, BSSID, PHY, rates, RSSI
wifi_networksnearby BSS with band, channel, dBm and security flags; summary by default
wifi_scanask the driver for a fresh scan
connectivity_diagnoseseparate radio, authentication, IP/DHCP, DNS, TCP and explicitly configured Internet reachability
chronicle_startstart the rotating local change-only recorder
chronicle_stopstop and flush the recorder
chronicle_statusrecorder state, path and latest error
chronicle_recentrecent changes across active and rotated JSONL files
ble_identify / ble_observeopaque identity, history and caveated persistence, co-travel, clone or flood evidence from caller-supplied observations
ble_scanbounded native advertisement scan without GATT connection; updates the same process-local history
ble_histories / ble_evaluateprocess-local recurrence and explicit disappearance evaluation
ble_tracker_resetclear local BLE history and apply allowlist, expected-device and detector policy

Deliberately absent: saved Wi-Fi keys, MAC changes, adapter restarts, LAN sweeps. An autonomous model must not be able to leak a credential or drop you off the network. Calling them returns -32601.

//: 06 — STRAIGHT TALK

What we don't claim

//: 07 — ROADMAP

Where this goes