reticiulum-specification/agent.md
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

12 KiB
Raw Blame History

AGENT.md — Instructions for AI agents working on this repository

This file tells AI coding agents (Claude Code, Codex, Cursor, Copilot Workspace, etc.) how to maintain this repository responsibly. The goal of this repo is to be the canonical, verifiable byte-level reference for the Reticulum protocol. Speculation is acceptable as a starting point but must be clearly marked as such until tested against the upstream Python implementation.

If you are an AI agent reading this: follow these rules. If you are a human reviewing an agent's PR: enforce these rules.


1. Verification is mandatory

Every claim in this repository falls into one of three states:

State Marker Meaning
Verified (no marker, or [verified]) Claim has been tested against the upstream RNS Python stack with a runnable test, OR is a direct citation of upstream source code with file + line.
Unverified > ⚠️ **UNVERIFIED:** callout Plausible from source-reading or other-implementation behavior, but not directly tested against upstream Python. May be wrong.
Speculation > 🔮 **SPECULATION:** callout Hypothesis based on reasoning about how the protocol probably works, with no source citation OR runtime test. Must be resolved (verified or removed) before any release.

Do not silently promote a claim from unverified to verified without doing the actual verification. The marker exists so a future reader can trust unmarked content.

What counts as verification

In rough order of strength:

  1. Round-trip with upstream Python RNS. A small script in tools/ that loads the relevant RNS module, performs the operation in both directions, and compares bytes. Strongest evidence.
  2. Direct upstream source citation. File path and line number in the standard pip install rns lxmf install layout (RNS/, LXMF/). Acceptable for behaviors that are hard to test (e.g. multi-hop forwarding rules).
  3. Wire capture with byte-level diff. Capturing actual upstream emission (e.g. tcpdump on rnsd) and showing it matches the spec.

What does NOT count as verification:

  • "It worked on my Sideband install" without a script anyone can re-run
  • "The webclient does it this way" — webclient may have the same bug
  • "Reading this code, I think it does X" — that's source-reading, which is acceptable as a citation but only if the citation is included
  • "GPT/Claude/Gemini said so" — no

2. Workflow for adding a new claim

  1. Draft the claim in the relevant section of SPEC.md (or the future per-layer file).
  2. Mark it > 🔮 **SPECULATION:** if it's pure reasoning, or > ⚠️ **UNVERIFIED:** if there's a source citation but no runtime test.
  3. Write a verifier in tools/:
    • For byte-level claims: a Python script that produces the expected upstream bytes and compares to a literal expected = bytes.fromhex(...).
    • For behavioral claims (e.g. "originator inserts transport_id at offset 2 for >1-hop paths"): a script that exercises RNS.Transport with a known path table and dumps process_outgoing calls.
  4. Run the verifier. If it confirms, remove the marker and add a (verified by tools/<script>.py) parenthetical to the claim.
  5. If the verifier disproves, EITHER fix the claim AND the verifier, OR delete the claim entirely. Do not commit a verifier that hand-waves away a discrepancy.

PRs must include the verifier scripts. Don't commit a "verified" claim without the script that backs it.


3. Required tools

Agents working on this repo should have access to:

  • A working Python 3 install with rns and lxmf packages: pip install rns lxmf
  • The RNS/ and LXMF/ source trees (typically at ~/AppData/Roaming/Python/Python3xx/site-packages/RNS/ on Windows or ~/.local/lib/python3.x/site-packages/RNS/ on Linux/macOS).
  • Optional but very useful: a packet-trace tool. tcpdump -i lo -A -X port 4242 works for TCPServerInterface; for BLE you need ADB + an RNode-aware capture tool.

Hardware (RNode, RatDeck, etc.) is NOT required for most verification — most byte-level claims can be checked entirely in Python RNS without any radio.


4. Marking convention

Use these GitHub-flavored Markdown blockquote forms so they render distinctly:

> ⚠️ **UNVERIFIED:** This is plausible from reading `RNS/Transport.py:1485` but I have not run a test that demonstrates the behavior end-to-end. Specifically need to confirm that a HEADER_1 packet from a TCP client to a sibling TCP client is forwarded after the rnsd auto-fills `transport_id`.

> 🔮 **SPECULATION:** The path-request payload may include the requester's own transport_id when issued from a transport-enabled originator. The `RNS/Transport.py::request_path` source suggests this but I have not decoded a captured upstream emission to confirm.

When you verify a previously-marked claim, delete the entire blockquote and (if helpful) append (verified by tools/<script>.py) to the claim's prose. Do not just remove the emoji — the structure should disappear so a future reader doesn't have to wonder.


5. Audit pass — initial state of SPEC.md

The bootstrap SPEC.md was assembled from the working notes of two reverse-engineering efforts (webclient and mobile-app). Some sections are already strongly verified by working code in those repos; some are source-cited but not directly tested in this spec repo's tools; some are observational claims that need formal verification.

Before any v1.0 release, every section needs an explicit verification status. The first task for the next agent is to walk SPEC.md section by section and mark each claim per §1 above.

Initial confidence assessment (subjective, not authoritative — re-do this audit independently):

SPEC.md section Confidence Notes
§1 Identity & destination hashes High Round-tripped against upstream in both reverse-engineering repos
§2.1, §2.2 Packet header bit layout High Matches upstream RNS/Packet.py; fixed test vectors round-trip
§2.3 Originator HEADER_1 → HEADER_2 conversion Source-cited but not test-verified in this repo. Mark as such until a tools/ script confirms by exercising upstream Transport.outbound with a known multi-hop path table.
§3 Token crypto High Test vectors pass; both reference repos interop with upstream Sideband
§4 Announce wire format High Test vectors round-trip; signature verification works against upstream emissions
§4.3 app_data format Mostly high. The [name_bytes, stamp_cost, [capability_flags]] 3-element variant is observed but not formally verified for this repo.
§5 LXMF wire format High
§5.6 Dual msgpack-variant signature verification High — fixed an interop bug in the webclient when added
§6 Reticulum Link protocol High Both initiator and responder are working in the reference repos
§7.1, §7.2 Path requests Recently surfaced bug-fix. §7.2 (responding to inbound path requests) is verified end-to-end on BLE in the mobile-app. §7.1's claim that path requests always precede LXMF DATA needs verification — may only happen on stale paths.
§7.3 Ratchet rotation requirement Verified end-to-end. Pre-fix the controlled receiver logged path-not-found; post-fix it logged distinct ratchet hashes per rotation.
§7.4 Ratchet ring (inbound decrypt tolerance) UNVERIFIED in current implementations. The reference repos discard old ratchet privkeys on rotation. Upstream's "8 ratchets" default needs source citation.
§7.6 TCPServerInterface.OUT override Source-cited; matches behavior observed in the mobile-app's local-transport experiments.
§8 KISS / HDLC framing High — both work in production on the reference clients
§9.1§9.8 Implementation gotchas Each was a real bug that bit a real implementation. High confidence each is real; some lack formal test scripts.
§10 Resource fragmentation Source-cited from RNS/Resource.py against RNS 1.2.0; not yet runtime-verified in this repo's tools/.
§11 Test vectors The vectors themselves are verified; the test-vectors/ directory needs to be populated in this repo (currently partially populated).
§12 Source map High

Concrete next-task list for the agent picking this up:

  1. Run the audit — re-evaluate the table above with your own reasoning, don't just trust it.
  2. Populate test-vectors/ with at least: identity material, a signed announce, an opportunistic-LXMF round-trip, a Link handshake.
  3. Write tools/verify_announce.py that loads a test vector and verifies bytes against upstream RNS.
  4. For each > ⚠️ or > 🔮 callout you add, write the verifier alongside.
  5. Open issues for any claim you can't verify and tag them needs-verification.

6. PR rules

For any PR touching SPEC.md:

  • Every new claim has a verification marker OR is unmarked because it has a (verified by tools/...) reference.
  • Every removed marker has a corresponding new tools/ script in the same PR.
  • No "I tested this manually and it worked" — capture the test as a runnable script.
  • Reviewers should reject PRs that quietly remove markers without including the verifier.

For PRs adding to test-vectors/:

  • Include the script that generated the vector (so it can be regenerated against future upstream RNS).
  • Include the upstream RNS version the vector was generated against (pip show rns output is fine).
  • The test vector should round-trip in both directions (build+sign AND parse+verify) when run through upstream RNS.

7. What to do when upstream changes

RNS evolves. When a future RNS version changes the wire format (or the in-source behavior cited in this spec):

  1. Don't silently update the spec. The old behavior may still be in production deployments and matter for interop.
  2. Add a versioned note: As of RNS x.y.z this changed to .... Keep the prior behavior described too.
  3. Update tools/ verifiers to test against both the old and new behavior if possible.
  4. Bump a last-verified-against-rns: x.y.z line in SPEC.md's frontmatter.

The goal is for this spec to be useful even when run against an RNS version a year out of date — that's the worst-case in heterogeneous mesh deployments.


8. Don't

  • Don't paste large blocks of upstream code into this repo (license & churn). Cite by file + line + small inline snippet only.
  • Don't add claims based purely on what some other client does. Other clients have bugs too.
  • Don't remove a ⚠️ or 🔮 marker without doing the verification work.
  • Don't commit a verifier that swallows discrepancies (if expected != actual: print("close enough")). Either it matches or it doesn't.
  • Don't trust your own training data on this — Reticulum-specific protocol details are sparse on the public web and most LLM knowledge is wrong or out of date. Verify everything.

9. Repo layout (current and aspirational)

reticulum-specifications/
├── README.md              Project intro
├── LICENSE                CC BY 4.0
├── agent.md               This file
├── SPEC.md                Combined spec (will be split into per-layer files as it grows)
├── tools/                 Verifier scripts (Python, callable against upstream RNS)
│   ├── verify_announce.py        (TODO)
│   ├── verify_packet_header.py   (TODO)
│   ├── verify_lxmf_roundtrip.py  (TODO)
│   └── verify_link_handshake.py  (TODO)
└── test-vectors/          Known-good byte sequences
    ├── README.md          (TODO — describe vector format)
    ├── identities.json    (TODO)
    ├── announces.json     (TODO)
    └── ...

Tools are Python because Python RNS is the reference. Verifiers should be self-contained scripts that print PASS/FAIL plus a diagnostic on mismatch. Exit code 0 on PASS, non-zero on FAIL.