Skip to content

Roadmap

This document is forward-looking, not normative: unlike the rest of docs/ (which describes shipped behavior and moves with the code), this file describes work not yet done and the order to do it in. When a workstream lands, its behavior moves into the normative docs and the entry here is checked off. History of what already shipped lives in the normative docs and git log — this file no longer re-narrates it.

Design companions (forward-looking, non-normative):

The access-cell spine, TCP federation backbone, identity tiers, signed admin, DCC transfer stack, chaos harness, VirtualRadio PHY harness, fuzzer, and the ircII TUI are built and host-tested (870 host tests + smoke + firmware CI as of the v2 freeze). LPP v2 is open: the Edge Routing Block and asymmetric multi-SF return lane are already in the v2 layout. What remains from the previous roadmap is genuinely RF/hardware-gated — each row is a radio driver, TX path, or validation campaign needing physical radios and human sign-off (AGENTS.md rule 5), not more host logic:

RF-gated remainder Unlocks
RF backbone radio transport (selection seam built) federation beyond TCP links
RF standby failover hardware validation full RF auto-rerouting
Broader mutating Admin RF/TX/lane policy remote RF administration
Multi-radio/burst RF driver adapters (planner built) concurrent presets per node
DCC burst board-driver wiring stock-client bulk transfer on burst lanes

Node profiles (unchanged, normative once shipped): one core, three download targets — A field hotspot (USB-ECM/SoftAP → IRC :6667, client), B uplink router (WiFi + TCP backbone, router), C serial-only (CDC console + TUI). Profiles change transports/defaults, never wire behavior.

Known scaling walls (recorded, not 1.0 work): lrcd is single-threaded poll() — shard by region before reaching for io_uring; a Linux radio edge needs the spidev RadioLib HAL (same seams as firmware). Both are documented in ENGINEERING_DEEP_DIVE.md §scaling.

The LPP v2 window — close it deliberately, then freeze

Section titled “The LPP v2 window — close it deliberately, then freeze”

Status (2026-07-01): the window is CLOSED — v2 is FROZEN. All five batch items landed via /lrc-wire-change (AC replaces TH; ERB layout frozen; RACK frame host side; BEACON region id; EXT_ADDR explicitly re-reserved for v3 with written rationale in PROTOCOL.md; fresh v2 goldens beside the retained v1 set), and the gate below passed — constants frozen against sweep evidence in docs/research/traces/credit-freeze/. From here: additive changes only until a v3.

Nothing has shipped, so v2 is the moment every wanted breaking change lands as one batched, documented version event — after it freezes, additive changes only until a v3. The batch (each item runs /lrc-wire-change):

  1. AC replaces TH — the airtime-credit byte (CREDIT_ROUTING.md). TTL and hops-taken leave the wire; loop-guard = dedup + gradient descent, width = suppression, resource bound = credit. More hops where hops are cheap (dozens on fast lanes), honest cost where they aren’t.
  2. ERB layout freeze — finish routing-redesign Phase 2 (2.1 field freeze, 2.2 RACK frame, 2.3 observed-delivery mechanism) so the v2 golden vectors can pin the final shape.
  3. Region id in BEACON — one byte naming the regulatory region row (WS-REGION); mixed-region hearing fails safe (ignore, count).
  4. EXT_ADDR decision — either spec the v2 16-byte-UID extended addressing block now or explicitly re-reserve it; do not leave it vague across the freeze.
  5. Fresh v2 golden vectors in test_packet.cpp beside the retained v1 set (v1 remains the blind-relay compatibility record).

Gate: v2 does not freeze until the credit/contention constants pass the scenario-testbed sweeps (WS-SIM) — the constants land in PROTOCOL.md with their sweep traces committed. ✅ Passed 2026-07-01 (unit 50 ms, budgets 100/120/60/0, min-debit 1, reorig floor 8, LBT prior 16, duty normalization changed to fraction-of-own-cap by sweep verdict).

Tags: [HOST] host-testable (agent-executable), [WIRE] golden-byte event, [RF] needs radios + human sign-off, [WEB] browser/site code, [OPS] CI/infra. Every workstream lands with tests and moves its docs in the same commit (AGENTS.md rules 3–4).

WS-SIM — Scenario testbed (lrcsim) [HOST] ✅ (Mode A + 9-scenario canonical library + CI landed; Mode B multi-process bed remains open)

Section titled “WS-SIM — Scenario testbed (lrcsim) [HOST] ✅ (Mode A + 9-scenario canonical library + CI landed; Mode B multi-process bed remains open)”

The laboratory everything else is tuned in: SCENARIO_TESTBED.md. In-process Mode A (N lrc::Nodes + geometric field model, virtual clock, seeded) and multi-process Mode B (real lrcd binaries over a lrcbridge UDP frame bus with the same field model — the unix-native bed for process-kill persistence torture and TCP+RF mixed topologies). Asymmetry is a first-class citizen — per-node power/height and per-pair directional overrides. Canonical library in tests/scenarios/: hilltop_asym (heard-by-200/hears-5), router_death, roam_walk, partition_heal, metro_500, eu868_duty_starve, multi_sf_share, credit_depth, reboot_storm. JSONL traces feed CI artifacts, tuning sweeps, and the observatory’s replay view. Gate for: v2 freeze, WS-CREDIT constants, WS-SPECTRUM claims.

WS-CREDIT — Credit routing, TTL retired [HOST→WIRE] ✅ (decision layer + AC on the v2 wire + constants frozen by sweeps)

Section titled “WS-CREDIT — Credit routing, TTL retired [HOST→WIRE] ✅ (decision layer + AC on the v2 wire + constants frozen by sweeps)”

CREDIT_ROUTING.md. Host decision layer first (debit function, class budgets, gradient-descent forwarding predicate, region-coupled re-origination) behind a seam beside routing_policy.h; then the AC byte in the v2 batch; then testbed sweeps pick the unit and budgets. Delivers the “remove max-hops/TTL entirely” goal with three provable bounds instead of one overloaded nibble.

WS-REGION — Worldwide regions + compliance engine [HOST] ✅ (15-region engine, duty/dwell/LBT enforced on the TX path; on-air spot-checks are Wave 4)

Section titled “WS-REGION — Worldwide regions + compliance engine [HOST] ✅ (15-region engine, duty/dwell/LBT enforced on the TX path; on-air spot-checks are Wave 4)”

Source of truth: REGULATORY_SURVEY.md. The survey’s design-forcing findings, in build order:

  • Replace the flat BandPlan row with multi-sub-band region rows (EU868/KR920/RU864/MY_919 need per-sub-band duty/power inside one region); duty moves from uint8_t percent to basis points (EU g2 = 0.1%).
  • AirtimeLedger keyed per sub-band, enforcing duty as a legal budget; dwell time (US915/AU915/AS923 400 ms) enforced per-transmission, independent of duty.
  • LBT policy objects where legally mandatory (JP: ≥128 µs carrier sense at −80 dBm + <4 s continuous TX; KR; CN) wired through the existing CAD seam — Meshtastic ships none of this; we will not copy that gap.
  • EIRP-vs-ERP unit tags per row and antenna-gain accounting (conducted clamp = ceiling − gain_dbi, operator-configured gain).
  • Region rows as constexpr codegen from a reviewed table; region id enum in BEACON (v2 batch); region must be set before tx on (extends the ship-OFF invariant); countries with multiple legal regimes (RU, NZ) get explicit multi-row mappings.
  • UI localization (string tables, UTF-8 audit) is deliberately post-1.0; regulatory localization is the 1.0 requirement.

WS-SPECTRUM — Multi-SF channel sharing [HOST + RF] — host half ✅ (rejection model + multi_sf_share quantified: break-even = desired + rejection − capture); RF measurement open

Section titled “WS-SPECTRUM — Multi-SF channel sharing [HOST + RF] — host half ✅ (rejection model + multi_sf_share quantified: break-even = desired + rejection − capture); RF measurement open”

Make the most of the band: co-channel SF layering (different SFs share a frequency with ~−16 dB mutual rejection — imperfect, so it’s a measured power-discipline design, not an assumption), lane packing across region sub-bands, and promotion-ladder pressure tuned so the anchor stays a dial tone. multi_sf_share in the testbed quantifies the win first [HOST]; on-air validation is [RF]. The asymmetric return lane (built) already exploits SF asymmetry; this workstream generalizes it to lane placement.

WS-PRESETS — Preset terminology ✅ (landed with this roadmap)

Section titled “WS-PRESETS — Preset terminology ✅ (landed with this roadmap)”

The locomotion ladder is renamed to link-role terminology — ANCHOR, FRINGE, REACH, FIELD, CRUISE, LOCAL, TRUNK, BURST (RADIO.md §Preset ladder). Display/config change only; the preset id on the wire is the index.

WS-SCOPE — chirpscope, the web observatory [WEB][HOST] ✅ (SSE feed + topology/inspector/lanes/timeline/replay views)

Section titled “WS-SCOPE — chirpscope, the web observatory [WEB][HOST] ✅ (SSE feed + topology/inspector/lanes/timeline/replay views)”

meshtrack’s job (live command-and-monitoring for a mesh), reborn as a web app fed by chIRpChat’s own plumbing — troubleshoot, track, and analyze:

  • Feeds: a new lrcd SSE/WebSocket event stream (packet events, registrations, lane occupancy, RTRSYNC/federation state) beside the existing Prometheus /metrics; lrclog history replay; lrcsim JSONL traces (same viewer debugs live networks and simulations).
  • Views: topology graph (routers/clients/links weighted by SNR, observed ERB TRAIL paths, asymmetry rendered as one-way edges); packet inspector (live LPP decode + filters); lanes/airtime dashboard (per-sub-band duty headroom — the compliance view of WS-REGION); CHANSYNC/gap-heal and boot-id timeline; identity/registration browser; federation/RTT view; OTA rollout view (WS-OTA counters); trace replay with time scrubbing.
  • Stance: no geolocation on the wire, ever (charter) — node positions are operator-side local config; the SPA ships as a prebuilt static bundle embedded in lrcd (no runtime deps for the daemon, its own toolchain in web/, dependency discussion per AGENTS rule 6).

WS-SITE — Public website [WEB][OPS] ✅ built in-tree under site/ (repo split + Cloudflare deploy = human runbook, site/DEPLOY.md)

Section titled “WS-SITE — Public website [WEB][OPS] ✅ built in-tree under site/ (repo split + Cloudflare deploy = human runbook, site/DEPLOY.md)”

Execute WEBSITE_PLAN.md: new private GitHub repo, Astro + Starlight on Cloudflare Pages; docs synced from this repo via pinned submodule with research-tier docs auto-badged non-normative; landing messaging on the three grounded differentiators (any IRC client — no app; cellular architecture, not flood mesh; asymmetric multi-SF routing); comparison page vs Meshtastic/MeshCore; browser flasher via esptool-js; launch blog seeds drawn from real engineering docs. Repo goes public at launch, not before.

WS-REL — Release engineering + user updates [OPS] ✅ (workflows + signed-manifest tool; humans must provision signing secrets, RELEASING.md §7)

Section titled “WS-REL — Release engineering + user updates [OPS] ✅ (workflows + signed-manifest tool; humans must provision signing secrets, RELEASING.md §7)”
  • Tag-driven release workflow: build matrix (boards × profiles) → artifacts (firmware bins, merged-flash images, SHA-256 sums, signed manifests per OTA_DESIGN §3) → GitHub Release; stable/beta channels; nightly canaries. Release signing key in an environment-protected secret.
  • CI grows: scenario-suite job (WS-SIM, artifacts on failure), fuzz smoke, the existing size-budget gate, flash/PSRAM budget report per PR.
  • User update paths, documented in USERGUIDE.md + the site: web flasher (Chrome/Edge WebSerial) as the primary “update your device” story, CLI (esptool/pio) fallback, and the ESP32-S3 native-USB BOOT-button first-flash quirk written down where users will actually find it.

WS-OTA — Remote fleet updates [HOST→RF-adjacent] — host side ✅ (staging machine, DCC path, admin keys); on-hardware apply is Wave 4

Section titled “WS-OTA — Remote fleet updates [HOST→RF-adjacent] — host side ✅ (staging machine, DCC path, admin keys); on-hardware apply is Wave 4”

OTA_DESIGN.md: release-key-signed manifests, transfer as a DCC stream (chunks, RESUME bitmaps, whole-image SHA-256 — all built machinery) staged to SD/PSRAM/otastage with a persisted resume bitmap, A/B slots + health-gated commit + automatic rollback, canary→fleet waves via quorum-gateable signed Admin, ota.* telemetry into the observatory. Host-side (manifest codec, staging state machine, admin keys, resume persistence) is agent-executable now; the on-hardware apply path needs human sign-off (a bricked router is a dead cell).

WS-UX — Onboarding and smoothness [HOST]

Section titled “WS-UX — Onboarding and smoothness [HOST]”

The “user keys etc.” polish that makes the power visible instead of sharp: first-run wizard on serial/TUI/web console (region → identity generation → phonetic-hex + QR seed backup (built) → join defaults); key verification/fingerprint UX between users; guided federation peering (pin exchange flow instead of hand-edited configs); an error-message audit (every refusal names its reason and its fix); IRC client compatibility matrix (irssi/WeeChat/Textual/Halloy…) as a smoke suite; USERGUIDE.md restructured per profile. Plus the two cosmetic OTA-chat follow-ups still open from the bench (client-originated scope stamp; UID-derived nick rendering).

Execution program — how the agent team runs this

Section titled “Execution program — how the agent team runs this”

Wave structure, honoring the two standing gotchas (worktree agents branch from the repo base, so integration is cherry-pick; ROADMAP.md is integrator-only) and the hard gates (wire events only via /lrc-wire-change; [RF] items are never closed by an agent):

  • Wave 1 [HOST], parallel, disjoint file ownership: WS-SIM steps 1–4 (field model → parser → Mode A → CI) ‖ WS-CREDIT host decision layer ‖ WS-REGION region rows + ledger/dwell/LBT primitives ‖ WS-SCOPE event feed + SPA skeleton ‖ WS-REL release workflow. Each agent runs the full verify loop; nothing in Wave 1 touches packet.h.
  • Wave 2 [WIRE], single owner: the LPP v2 batch (AC + ERB freeze + region id + EXT_ADDR decision + v2 goldens), then the testbed sweeps that license the freeze. One agent owns packet.h/PROTOCOL.md/goldens for the whole wave; everyone else stays out.
  • Wave 3 [WEB][OPS], parallel: WS-SITE repo + content; WS-SCOPE views on trace replay; WS-OTA host side; WS-UX wizard + compat matrix.
  • Wave 4 [RF], human-gated: routing-redesign Phase 4 bench campaign, WS-SPECTRUM co-channel measurements, WS-OTA on-hardware apply, region spot-checks on air. Agents prepare evidence templates and analysis only; humans key the radios and sign off.

Standing rules for every agent: read AGENTS.md first; docs move with code; every observable behavior gets a counter; breaking changes are welcome but never accidental; if you can’t test it on the host, refactor until you can.

Sustainability assessment (requested: “is the direction sustainable?”)

Section titled “Sustainability assessment (requested: “is the direction sustainable?”)”

What’s working — keep: the portable core + seams + host-first testing is the moat; it’s why 870 host tests (at the v2 freeze), a chaos harness, and a PHY harness exist without a bench, and why agents can do most of the work safely. The docs-move-with-code discipline has held. Telemetry-counter culture makes every feature observable. Greenfield breaking-change freedom is being spent deliberately (the v2 window) rather than leaking out over time.

Real risks, with mitigations baked into this program:

  1. Review bandwidth vs. agent code volume. The wave structure exists for this: disjoint ownership, one wire-owner, gates between waves. Volume without gates is how good codebases rot.
  2. RF-gated backlog compounding. Host work keeps outrunning bench time. Wave 4 needs calendar commitment (a recurring bench day), or the gap becomes the project’s defining debt. Nothing else on this list bricks the project if late; this one quietly can.
  3. Doc-surface growth. docs/research/ is healthy exhaust, but each landing workstream must either promote its doc to normative or mark it historical — the roadmap rewrite you’re reading practices this.
  4. Freeze discipline. After v2 freezes, the additive-only rule is what makes a public network possible. The EXT_ADDR decision belongs inside the window precisely so it can’t become a v3 excuse.
  5. Ecosystem gap (ALT_ROADMAP axis H): Meshtastic’s advantage is money, community, and time — not architecture. WS-SITE/WS-REL are the actual competitive work, not vanity; treat them with engineering seriousness.

Verdict: the direction is sustainable and the architecture holds under its own ambitions. The needed pivot — which this roadmap is — is from accumulating breadth to freezing v2 and productizing: laboratory, honest cost model, worldwide legality, observability, and a public face.

  • 0.9 “freeze candidate”: ✅ reached 2026-07-01. Waves 1–2 complete — lrcsim + scenario library in CI, credit routing validated and constants frozen, region engine enforcing duty/dwell/LBT/EIRP, LPP v2 golden bytes frozen, chirpscope MVP (live view + replay). ✅ preset terminology.
  • 1.0 “public”: Wave 3 complete — site launched with flasher + docs pipeline, release channels + signed artifacts, OTA host machinery, onboarding wizard, security review re-run (RELEASE_1.0_READINESS.md), field soak with scenario parity (every field incident becomes a .scn). Status 2026-07-01: every agent-executable item above is built and host-verified (site content in site/ + DEPLOY.md runbook; workflows + manifest tool awaiting secret provisioning; OTA host machinery ✅; wizard ✅; security re-run ✅ with two findings pending human risk decision). What remains for 1.0 is human-keyed: site deploy/launch, signing secrets, the B3/A7 security decisions, the RF bench ledger (docs/bench/SIGNOFF.md), and the field soak.
  • 1.x: OTA fleet rollouts on hardware, RF backbone lanes, multi-radio drivers, cross-federation DM transport, delta OTA, nRF52 OTA, UI string localization, Linux spidev radio edge.