docs(spec): the backbone is a gateway property - #485
Merged
Merged
Conversation
The gateway contract's backbone section said "between gateways, the wide-area carrier is Reticulum" and stated the Verdict rule for "a Reticulum gateway". The device never touches a backbone: it speaks the daemon contract over local IP, stores the tokens the gateway advertises, and reads none of them on any decision. Restate the section as what any backbone owes a gateway (gateway-to-gateway presence, arbitrary-size framing, a provisioned peer list, a declared rate class), with Reticulum as the reference backbone in a subsection of its own. The token becomes the family backbone_<kind>_v1: a client ignores a kind it does not know, a gateway may advertise none, and the token is advisory and never a routing input. backbone_reticulum_v1 keeps its spelling as the first member. A device attaches to one gateway daemon at a time, because every gateway answer is recorded against the one daemon carrier and a second daemon would overwrite the first one's facts. ADR 0026 records the decision and why two daemons need two transport types. The reticulum_* entry points, the transport variant and the manager files keep their names; their doc comments now say what they name, the gateway daemon carrier after its reference backbone. Threat model R10's abuse-budget argument is per rate class. No frame, verb or token changes.
bahdotsh
force-pushed
the
docs/headless-backbone-gateway-property
branch
from
September 30, 2026 15:36
e6fa61b to
0dbe34b
Compare
…mments The table pins the definition's SHA-256, and this branch rewords two comments in it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The gateway contract's backbone section was written for one backbone. It opened with "between gateways, the wide-area carrier is Reticulum", stated the Verdict rule for "a Reticulum gateway", and had one backbone token with no rule for a second. The device does none of that: it speaks the daemon contract over local IP, stores whatever tokens the gateway advertises, and reads none of them on any decision.
This PR restates the backbone as the gateway's property and records the decision in ADR 0026. No frame, verb or token spelling changes.
docs/spec/gateway-contract.md.## The backbonenow states what any backbone owes a gateway: gateway-to-gateway presence, arbitrary-size framing, a provisioned peer list, and a declared rate class (scarceorbroad, a property of the kind; an unknown kind isscarce). Reticulum is the reference backbone in a subsection of its own, with the MDU, link-with-resources and one-destination-per-gateway mechanism moved there. Gateway-owned destinations are split into the kind-independent invariant (a gateway is reachable on the backbone under its own identity and only under it; no gateway holds a device key) and the Reticulum mechanism. The opener and the Verdict rule no longer name a backbone.backbone_<kind>_v1. A gateway advertises each backbone it reaches as one token. A client ignores a kind it does not know and keeps the session. A gateway may advertise no backbone token and is a conforming gateway. The token is advisory and never a routing input.backbone_reticulum_v1is the first member, unchanged.GatewayCarrier::Reticulumvariant, the transport module and type, the media fallback comment insend.rs, the FFI section banner and tworeticulum_*headers, and their plain//twins in the UDL (which uniffi ignores, so no binding is regenerated) now say what they name: the gateway daemon carrier, after its reference backbone. Thereticulum_*entry points, the transport variant and the manager file names keep their spelling.docs/reticulum.mdgets the same sentence in its callout.What was verified against the tree, not just restated
mailbox_v1behaviour is driven by thestoredandpushedflags on each verdict.send.rs) and presence answers (session.rs) are recorded throughReachabilityFacts::recordkeyed byTransportType, where the newest claim for a carrier replaces the last. The transport manager holds one transport per type and the FFI oneReticulumState.select_media_transportpins to the current transport when it is available and leaves Reticulum out of the fallback order only. Retries are forced onto the pin (pinned_media_transport_for_messagein the retry loop). The chapter says exactly that, makes the exclusion the gateway's obligation, and says what a scarce gateway's refusal does to the pinned transfer: each chunk gets a plain-failure verdict (budget_exceededorframe_too_large, neverrecipient_unreachable) and the transfer fails on its retry ladder.Validation
cargo fmt --all -- --check,cargo clippy --workspace -- -D warningsandRUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-depspass locally (the Rust changes are doc comments only).#attach,#gateway-daemon-contract-v1) still resolves; the new anchors (#the-backbone,#the-backbone-token,#what-a-backbone-owes-a-gateway,#the-reticulum-backbone) are the headings as written.Not in this PR
reticulum_*API or the manager files. About forty source guards pin them by path and spelling, and the rename is a three-binding API break for no behaviour.docs/spec/README.mdanddocs/README.mdscope text for the chapter still says "and the backbone", which remains accurate, so the rows are untouched.Notes for reviewers
broadrate class has no member kind in this revision. It exists so that the table has a second value to name and so that "an unknown kind isscarce" is a rule rather than the only case.select_media_transport, and the forced pin in the retry loop), and the earlier text ("Media MUST be excluded") read as a device-side guarantee it never was. The obligation is placed on the gateway, where it always was enforceable, and the device's cost of not knowing the class is named rather than hidden.//comments only../scripts/generate-bindings.shwas deliberately not run: uniffi ignores them, and the generated bindings carry none of their text.