Find a file
Rob 366825c7a0 Add §17 implementation taxonomy: who needs which sections
Surfaced from real interop testing: a clean-room implementation
hit the §2.3 HEADER_1->HEADER_2 conversion bug, while category-1
clients (Sideband, MeshChat, NomadNet) couldn't have hit it
because they inherit upstream Python RNS's Transport.outbound
which does the conversion automatically.

The spec previously left this implicit. Without explicit guidance,
a reader could over-engineer (re-implementing things their
category-1 platform already handles) or under-engineer (assuming
'Sideband works, so my clean-room implementation works the same
way' when in fact Sideband works *because* upstream RNS handles
§2.3).

Four sub-sections:

  §17.1  The three categories of Reticulum app:
           Cat 1: Upstream-RNS-based (import RNS) — Sideband,
                  NomadNet, MeshChat, rncp, rnsh, rnstatus
           Cat 2: Wrappers / language bindings via FFI or
                  subprocess to upstream
           Cat 3: Clean-room implementations — microReticulum,
                  the Faketec repeater, anything from-scratch in
                  C++/Rust/JS/Kotlin/Swift

  §17.2  Section-relevance table by category. Wire formats are
         reference for cat 1/2, must-implement for cat 3.
         Behavioural guidance (§7, §12, §13, §14, §15, §16) is
         critical for cat 3, mostly informational for cat 1/2.

  §17.3  §2.3 worked example. Cat 1/2: don't write §2.3 code —
         upstream's Transport.outbound at line 1074-1083 does
         it automatically. Cat 3: implement it yourself or your
         packets get silently dropped by transit relays per
         line 1497 (which only forwards HEADER_2 with matching
         transport_id).

  §17.4  Pragmatic implication: a quick .claude/settings.local.json:      "Bash(python -c \"import RNS, LXMF; print\\('RNS:', RNS.__version__\\); print\\('LXMF:', LXMF.__version__\\)\")",
SPEC.md:| **1: Upstream-RNS-based** | Python application that does `import RNS` and uses upstream's `Reticulum` / `Transport` / `Identity` / `Destination` / `Packet` / `Link` directly. Inherits all wire-level behavior from upstream. | Sideband (Mark Qvist's flagship), NomadNet, [`liamcottle/reticulum-meshchat`](https://github.com/liamcottle/reticulum-meshchat), `rncp`, `rnsh`, `rnstatus`, anything in `pip show rns` example code |
SPEC.md:If you're not sure which category you're in: `grep -r "import RNS" your_codebase` is a quick check. Any hit means cat 1 (or cat 2 if it's behind an FFI wall). No hits means cat 3.
tools/regen_identities.py:import RNS
tools/verify_announce_app_data.py:import RNS
tools/verify_announce_app_data.py:import RNS.vendor.umsgpack as umsgpack
tools/verify_announce_roundtrip.py:import RNS
tools/verify_destination_hash.py:import RNS
tools/verify_link_handshake.py:import RNS
tools/verify_lxmf_opportunistic.py:import RNS
tools/verify_msgpack_quirk.py:import RNS
tools/verify_msgpack_quirk.py:import RNS.vendor.umsgpack as umsgpack
tools/verify_packet_header.py:import RNS
tools/verify_path_request.py:import RNS
tools/verify_proof_packet.py:import RNS
tools/verify_stamps.py:import RNS
tools/verify_token_crypto.py:import RNS
         tells you which category you're in. cat 1/2 readers can
         skip the implementation-depth sections; cat 3 readers
         need everything plus the verifiers as a regression suite.

Test vectors moves to §18, Source map to §19.

The provisional understanding is that this categorisation is
correct; if real-world testing reveals a category boundary that
doesn't hold the way described, the section gets revised or
removed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 16:02:59 -04:00
flows Add four more verifiers + receive-propagated flow + frontmatter version 2026-05-03 12:54:34 -04:00
test-vectors Verify §2.3, §4.3, §7.1, §7.4 against upstream RNS 1.2.0 / LXMF 0.9.6 2026-05-03 10:14:51 -04:00
tools Add tools/verify_stamps.py — runtime-lock §5.7 2026-05-03 15:13:59 -04:00
agent.md Add §10 Resource fragmentation + send-resource flow 2026-05-03 11:08:40 -04:00
LICENSE Initial bootstrap: README, LICENSE, SPEC.md, agent.md, scaffolding 2026-05-03 09:38:46 -04:00
README.md Add flows/ directory with opportunistic-LXMF send sequence 2026-05-03 10:15:03 -04:00
SPEC.md Add §17 implementation taxonomy: who needs which sections 2026-05-03 16:02:59 -04:00
todo.md Add tools/verify_stamps.py — runtime-lock §5.7 2026-05-03 15:13:59 -04:00

Reticulum Specifications

Byte-level interoperability specifications for the Reticulum Network Stack and LXMF — the parts that aren't in the upstream manuals but are needed to build a working client from scratch.

Upstream Reticulum has excellent operator-facing documentation (config, deployment, design philosophy). What's missing — and what every alternative implementation has had to reverse-engineer from the Python source — is an authoritative wire-level spec: header bit layouts, msgpack field types, signature input formats, the exact behavior of Transport.outbound, and the long list of "would never guess from reading the manual" gotchas that cost hours of debugging each.

This repo collects those findings in one place. The hope is that future client authors (Kotlin, Swift, Rust, Go, embedded C — pick your stack) can read this instead of re-deriving everything from RNS/Transport.py.

Status

Early days, contributions welcome. Current content was bootstrapped from the working notes of two reverse-engineering efforts:

Each finding is grounded in upstream source citations (file + line) so it can be re-verified as RNS evolves.

What's here

  • SPEC.md — the single combined spec document, organized by protocol layer
  • flows/ — chronological end-to-end narratives (e.g. "send a message"), cross-referencing SPEC.md sections
  • tools/ — self-contained Python verifier scripts that test SPEC.md claims against upstream RNS / LXMF
  • test-vectors/ — known-good byte sequences each implementation should be able to round-trip (intent: grow into a compliance suite)

As content grows, SPEC.md will be split into per-layer files (packet header, identity, announce, token-crypto, LXMF, link, resource, transport).

Scope

In scope:

  • Wire formats: byte layouts, field encodings, framing
  • Signing inputs and what's hashed where
  • Cross-cutting behaviors required for interop (path requests, ratchet rotation, retransmit semantics)
  • "Gotchas" — things upstream code does that aren't obvious from the manual or RFC-style sketches
  • Test vectors that any implementation must be able to round-trip

Out of scope:

  • Operator/user documentation — see the official manual
  • API design choices for any specific implementation
  • Networking layer config (interfaces, transport modes) — already well documented

Source citations

Where a finding cites upstream Python code, the path is relative to a standard pip install rns lxmf installation, e.g. RNS/Transport.py, LXMF/LXMF.py. Where the bundled umsgpack is referenced, the path is RNS/vendor/umsgpack.py.

When upstream code changes such that a citation no longer matches, file an issue or PR — the goal is to track the de-facto wire spec as it actually behaves, not as it was at any single snapshot.

Contributing

If you've debugged a Reticulum interop problem and the answer wasn't in the upstream docs, please add it. Format:

### N.M Short description of the finding

**Symptom:** what you observed that prompted the investigation.

**What's happening:** the actual mechanism, ideally with upstream source citation (file + line).

**Implication / fix:** what an implementation must do to interop.

**Source:** upstream file paths and approximate line numbers.

Add a worked test vector to test-vectors/ if the finding is byte-level.

License

CC BY 4.0 — use freely, attribution appreciated.