Find a file
Rob 95823ad840 Add §10 Resource fragmentation + send-resource flow
Closes Tier 1 #2. Without this, a client can't send any LXMF body
larger than LINK_PACKET_MAX_CONTENT ≈ 360 B, can't receive a NomadNet
page that doesn't fit in one MTU, and can't transfer files via rncp.

SPEC.md §10 (new): full Resource fragmentation protocol with citations
to RNS/Resource.py. 13 sub-sections covering preparation pipeline
(metadata prefix → optional bz2 → random_hash prefix → SHA-256 over
data||random_hash → link.encrypt of the WHOLE blob → part-split into
SDU-sized chunks → 4-byte map_hash hashmap with collision guard within
COLLISION_GUARD_SIZE = 2*WINDOW_MAX + HASHMAP_MAX_LEN), wire context
inventory (RESOURCE_ADV / RESOURCE / RESOURCE_REQ / RESOURCE_HMU /
RESOURCE_PRF / RESOURCE_ICL / RESOURCE_RCL), the msgpack dict for the
advertisement (t/d/n/h/r/o/i/l/q/f/m), the request payload format with
the hashmap_exhausted sentinel, the lazy-hashmap RESOURCE_HMU
continuation that lets large hashmaps avoid breaking small-MTU links,
the proof body
   resource_hash(32) || full_proof = SHA256(data||hash) (32)
returned in a PROOF-type packet, the sliding window dynamics
(WINDOW=4 → WINDOW_MAX_FAST=75 / WINDOW_MAX_VERY_SLOW=4 with rate
detection), multi-segment cutover at MAX_EFFICIENT_SIZE = 1 MiB - 1
with the lazy `__prepare_next_segment` pattern, and the
encryption-before-split layering that means a missing part can't be
decrypted in isolation.

flows/send-resource.md: 10-step chronology from RNS.Resource()
construction through advertise → req/parts loop → HMU continuation →
final RESOURCE_PRF → multi-segment fan-out, with a wire-byte ladder
diagram and a per-step source map.

Side fixes found while drafting:
  - SPEC.md §2.5 contexts table was wildly incomplete and had a real
    bug: KEEPALIVE was listed as 0xFD; upstream is 0xFA per
    RNS/Packet.py:87. 0xFD is actually LINKPROOF (the regular
    DATA-receipt context, §6.5). Replaced with the full upstream
    context inventory: NONE, RESOURCE_*, CACHE_REQUEST, REQUEST,
    RESPONSE, PATH_RESPONSE, COMMAND, COMMAND_STATUS, CHANNEL,
    KEEPALIVE, LINKIDENTIFY, LINKCLOSE, LINKPROOF, LRRTT, LRPROOF.
  - SPEC.md §6.5 reworded: "send back a PROOF packet (no context
    byte specifics)" → "send back a PROOF-type packet with
    context = LINKPROOF (0xFD)" for clarity.
  - The previously-numbered §10 "Test vectors" and §11 "Source map"
    are renumbered to §11 / §12 so the new Resource section lands in
    its correct protocol-stack position. agent.md §5 audit table
    updated accordingly.

flows/README.md status table updated; receive-resource.md added as
the next pending flow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 11:08:40 -04:00
flows Add §10 Resource fragmentation + send-resource flow 2026-05-03 11:08:40 -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 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
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 §10 Resource fragmentation + send-resource flow 2026-05-03 11:08:40 -04:00
todo.md Add §10 Resource fragmentation + send-resource flow 2026-05-03 11:08:40 -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.