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 honestUnknown— with a test-onlyforce_relayto 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
| Criterion | Verdict for this layer |
|---|---|
| Inspect what it sees | Mostly holds. Path receipts are honest; frames are small strict JSON. Relay metadata exposure (G3) is real but not yet documented to the user. |
| Fork permissions | Blunt. AuthorityMode::Single means one authority key governs succession; members cannot attenuate or delegate. Recovery/quorum (FROST) is reserved, not built. |
| BYO models + keys | Holds 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 memory | Not this layer’s surface (app data single-homing is a site-wide finding; see Part IV). |
| Auditable actions | Holds in-plane. Hash-chained document, append-only revocations, canonical encoding. (Site-wide: grant/trust journals outside the hash chain — Part IV.) |
| Exit without loss | Partial. 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
- v1 vs v2 group document — is
crates/xe-sync(v2: Device/Companion kinds, endpoint bindings) the intended canonical membership layer for shipped serving, or iscrates/net/group(v1: what gossip and the membership gate compile against) the line? This blocks G4. - Relay trust — run Agent54 relays pinned in the signed head, or accept number0’s public relays with direct-preferred + relay-fallback documented? (G3)
- 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.)