Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Review: Transport & identity

This review takes the layer as described and asks three questions: what verifiably holds, what is built but idle, and what still needs design. The lens throughout is the sovereignty litmus (inspect what it sees · fork permissions · BYO models + keys · movable memory · auditable actions · exit without loss). Verdicts cite code at xenon-launcher main @56e94575; gap IDs (G3, G4) are this beat’s register and feed Part IV.

What verifiably holds

  • One key, honest receipts. The device identity and the network address are the same Ed25519 key, and every connection reports its real path — Direct, Relay, or an honest Unknown — with a test-only force_relay to prove relay carriage rather than assume it (iroh_provider.rs:307-317, :98-100).
  • Membership is enforced where wired, actively. Inbound and outbound connections are authorized against the signed head, and revocation closes live connections immediately with a named QUIC error (0x5845, xenon: membership revoked; iroh_provider.rs:200-226, :242-245). Removal is a disconnect, not a hope.
  • The chain refuses the sharp edges. Succession is exactly-one-version, prior-hash-named; gaps, rollbacks, and forks are rejected; a persisted low-water mark refuses pre-seen documents across restarts (group/mod.rs:11-16, :473-509). Canonical binary encoding makes hashes implementation-independent (canonical.rs).
  • The join ceremony burns before it mints. Single-use invite + Ed25519 proof-of-possession, with the invite durably consumed before the member is added (group/protocol.rs:321-368) — a crash cannot leave a replayable invite behind.
  • Gossip validates every step. One verified successor at a time, each re-checked against the chain rules (run_sync, :422-479).

Built, but idle

  • Recovery statements (successor / takeover / counter / freeze / rotation, 72 h challenge window, FROST types reserved; group/recovery.rs) have no ceremony, UX, or networking driving them. This is designed headroom — valuable — but the honest status is: there is no working key-recovery lifecycle today. A lost device key is currently an unrecoverable identity.
  • The membership plane itself is the biggest idle asset: fully built, signed, revocation-capable — and the serving path does not consult it. That is G4, below.

Gap register (this beat — transport slice)

G3 — Relay trust model

Exists: with no relays configured, RelayMode::Default selects the iroh/number0 public relay set (iroh_provider.rs:84-85, presets::N0). Group documents can pin relay_endpoints under the authority signature (:74-83), but peer-serve takes relays from CLI arguments only (cli.rs:485-488) — unsigned.

Why this needs design: relays see connection metadata (who talks to whom, when, how much) and are an availability dependency operated by a third party. No fallback policy is stated anywhere.

Options: (a) Agent54-run relay(s), pinned in the signed head; (b) explicitly document acceptance of n0’s relays, direct-preferred with relay fallback; (c) relay-optional (hole-punch-only) mode for LAN-local fleets.

Decides: Luke — infrastructure plus a trust boundary.

G4 — Device identity & membership lifecycle for serving

Exists: a rich lifecycle in crates/net/group — enrollment (invite + proof-of-possession), removal (append-only revocation with live-connection closure), recovery statement families. The serving tunnel bypasses all of it: peer_serve.rs builds IrohProvider::new, never with_membership (:435, :591).

Why this needs design: a device removed from the group can still serve and consume so long as it holds a live ticket. Enrollment and authorization-to-serve are different graphs today, and the sovereignty story (“my devices, my group, my rules”) only refers to one of them.

Compounding fork: two group-document lineages exist — v1 in crates/net/group (what everything compiles against) and v2 in crates/xe-sync (MemberKind{Device, Companion}, endpoint bindings, v2 signing domains). Which is canonical for shipped serving is undecided, and Companion has no serving semantics at all.

Options: (a) gate the serve ALPN on membership — small change, pass a MembershipRegistry into publish/consume, and group revocation cuts serving tunnels for free; (b) keep bearer tickets for the “share to a non-member” case and add membership as an additional gate; (c) settle the v1-vs-v2 canonical document first, then wire.

Decides: Luke — this is the sovereignty spine of the whole beat. See also G1/G5 in the peer-serving review, which collapse if option (a) lands.

Sovereignty litmus check

CriterionVerdict for this layer
Inspect what it seesMostly holds. Path receipts are honest; frames are small strict JSON. Relay metadata exposure (G3) is real but not yet documented to the user.
Fork permissionsBlunt. AuthorityMode::Single means one authority key governs succession; members cannot attenuate or delegate. Recovery/quorum (FROST) is reserved, not built.
BYO models + keysHolds for keys — device keys are locally generated, never escrowed. Relays are BYO-able in the signed doc for the group plane, but only via unsigned CLI for serving (G3).
Movable memoryNot this layer’s surface (app data single-homing is a site-wide finding; see Part IV).
Auditable actionsHolds in-plane. Hash-chained document, append-only revocations, canonical encoding. (Site-wide: grant/trust journals outside the hash chain — Part IV.)
Exit without lossPartial. Leaving a group costs nothing held here; but a lost device key has no recovery lifecycle yet, which is a loss with no exit.

Questions for the Luke + Jan session

  1. v1 vs v2 group document — is crates/xe-sync (v2: Device/Companion kinds, endpoint bindings) the intended canonical membership layer for shipped serving, or is crates/net/group (v1: what gossip and the membership gate compile against) the line? This blocks G4.
  2. Relay trust — run Agent54 relays pinned in the signed head, or accept number0’s public relays with direct-preferred + relay-fallback documented? (G3)
  3. Companion semantics — should MemberKind::Companion (v2) be allowed to consume but never publish? No serving semantics exist for it today.

(The unify-serving-with-membership question itself is held in the peer-serving review, where the bearer-ticket alternatives live.)