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

The chronicle
of your radio_

RadioChron is a pure-Rust Wi-Fi diagnostics library and MCP server. 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
~724 KBSERVER BINARY
0C TOOLCHAIN NEEDED
# library — crates.io publish pending; straight from git today
$ cargo add radiochron --git https://github.com/sergii-ziborov/radiochron

# MCP server — build once, point your client at the binary
$ git clone https://github.com/sergii-ziborov/radiochron && cd radiochron
$ cargo build --release      # → target/release/radiochron.exe
$ claude mcp add radiochron -- ./target/release/radiochron.exe
//: 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 append-only JSONL with built-in rotation — greppable, schema-free, 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. Ports to Linux and cellular unchanged.

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.

RADIOCHRON
13 crates
NEAREST EQUIVALENT
51 crates + C toolchain
# a sensor that only reports link state pulls exactly that:
radiochron = { git = "…", default-features = false, features = ["status"] }
# status · scan · analyze · sample · history · record
//: 04 — FOUR WAYS IN

One engine, four surfaces

Rust library

radiochron — collectors, 802.11 analysis, the chronicle. What an IoT agent, exporter or CLI embeds. MIT, three dependencies.

MCP server

radiochron-mcp — six read-only tools + resources over stdio. Point Claude, Codex or any MCP client at one binary. No config, no arguments.

npm package PLANNED

radiochron on npm via napi-rs with prebuilt binaries — import from Node.js without a Rust toolchain. Name reserved-checked, build pending.

Desktop app

RadioChron Desktop — evidence timelines, baseline runs and network inventory on the same engine. Source.
//: 05 — MCP SURFACE

Six tools, all read-only

toolanswers
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

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