You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
LIST 9 synthesis. Merge the ephemeral-data and relay investigations into messaging/relay protocol v1: low-latency data without a central server, the two data classes (ephemeral live vs chained permanent), relay rules, and the attestation hand-off points the match system needs. Specialist/Summit-grade synthesis.
Program: Drew's 2026-10-28 directive (full text: hatch-personal memory/topics/id-program-2026-10-28.md).
Working pattern: parallel investigations, then the named synthesis issue merges them into a full design. Route guidance: Workhorse by default; Specialist/Summit for synthesis and ramification-heavy work. A result that says "done" is not the endpoint — the orchestrator reviews it and may commission another round. Deliverables: a markdown design/investigation doc (mermaid/SVG diagrams welcome) linked from this issue, plus follow-up issues for anything buildable. Build a proof of concept where the design calls for one, but do NOT build the permanent feature on top of an unreviewed PoC.
Task: Relay-side input for this synthesis is done: the id: investigate: multi-hop relay and P2P media paths — bridging peers, optional privacy relay, large-message chunking #2035 investigation (relay model + chunking verdict) is in PR doc: multi-hop relay and P2P media investigation (#2035) #2246, doc doc/2026-10-29T11-05-00Z_investigation_multi_hop_relay_and_p2p_media/. Headlines for the synthesis: adopt iroh-gossip as the fan-out substrate with ID signing/membership/chaining on top; validity = origin signature only, hop chain is audit/loop control; media = direct mesh + member selective-forwarder, hairpin only in privacy-relay mode; no new wire-level chunking (QUIC streams segment; reuse welcome checked-chunking over the 1 MiB frame cap; large payloads by iroh-blobs reference).
Design record: ID messaging/relay protocol v1 (synthesis of #2034 + #2035)
Gate status: both inputs have landed — #2034 CLOSED (doc merged via PR #2239) and #2035 CLOSED (PR #2246 merged) — so this synthesis is ungated. Parent epic #2056.
The decision
Adopt protocol v1 as the union of the two investigation verdicts, with the open questions they left answered below. No new substrate and no new wire chunking: v1 is ID semantics layered on machinery that already exists in pkgs/id.
The protocol in one page
Two data classes over one fan-out.Chained/permanent traffic (identity, membership, documents, money, durable chat, match results) keeps per-event origin signatures on the signed hash chain (chain.rs:282-309). Ephemeral/live traffic (keystrokes, cursors, presence, live input) never enters the chain per-event: it rides a per-session stream authenticated by one session-header signature + a per-session MAC, closed by segment checkpoints. (Grounded today: web/collab.rs already carries steps/cursors as unsigned MessagePack frames; only the saved revision becomes a signed document.put — local_events.rs:1-18.)
Fan-out = iroh-gossip (already a dependency; today used only for peer-discovery announcements, pkgs/id/src/commands/peers.rs). A bridging member forwards to members the sender cannot reach. Validity = the origin signature alone (over content, prev-references, group, sequence); each relay appends a signed hop record outside the envelope (relay ID, previous hop, receipt time) as audit/loop control. A relay can delay or withhold — an availability fault, mitigated by duplicate paths and range-sync catch-up — but cannot forge or re-attribute. Receivers dedupe by message ID.
Segment checkpoints are ordinary graph events. A checkpoint attests: "this segment's ordered delta, from state Sₙ₋₁, produced state Sₙ; here is its root" — carrying session_id, segment_seq, prev_checkpoint, root, event_count, time bounds, signature, optional audit-blob reference (residue shape: id: investigate: ephemeral live data vs the chained event graph — retention and intermittent signing #2034 doc §7). Live views rebuild from the latest checkpoint + the ephemeral stream since it. Defaults: 256 events or 2 s, world-configurable in the WorldLimits style (world/mod.rs:59-99).
Media never goes through the gossip tree and never hairpins by default: direct QUIC mesh ≤ ~6, a member as selective forwarder of already-encrypted packets beyond that; a central hairpin exists only in opt-in privacy-relay mode. Protocol v1's duty here is only to not preclude it.
No wire-level chunking. QUIC streams segment; oversized single messages reuse the checked-chunking over the 1 MiB frame cap (frames.rs:16-19); large payloads go by iroh-blobs reference. Event payloads stay bounded (world_caps.rs:65, MAX_EVENT_BYTES = 64 KiB).
Checkpoint as graph event (chosen) vs parallel signed artifact (artifact.rs shape): the graph event inherits event_store ordering, the waiting pool, and fork proofs for free; an artifact duplicates all three. Artifact stays the right shape for identity/key material, which is not session traffic.
iroh-gossip fan-out (chosen) vs a new flooding protocol: PlumTree/HyParView already gives tree repair + duplicate suppression; the only new code is ID's envelope/hop-record layer.
Segment checkpoints (chosen) vs initial+final signatures only: initial+final lets a relay truncate the tail and proves nothing about timing; segments bound both at O(segments) signature cost.
Invariants the implementation must hold
A relayed message verifies identically regardless of path length; hop records are never a trust input.
Compaction never removes a checkpoint, a fork proof, or anything a waiting-pool after resolution needs (event_store/mod.rs:12-22).
Durable classes (identity/membership, money, durable documents) are never compacted and never move to checkpoint-only signing.
Metadata honesty: bridges/relays learn social-graph + timing metadata; v1 states this plainly — hop records are not a privacy feature.
Phased implementation packets (enqueued, in order)
Companion relay PoC #2249 (five-node bridge) is already filed and was gated on this record; it can proceed under phase 3's envelope. PoCs stay throwaway until reviewed (program rule).
Question for Drew (explicit, non-blocking — packets proceed either way)
What should a NEW chat channel default to: durable (per-message signed, kept) or live (checkpointed, 90-day bounded)? Options: (a) durable by default, live as an opt-in per channel — recommended: history loss is the failure users notice, and a channel can relax later but cannot retroactively keep what was dropped; (b) live by default for high-chatter rooms — cheaper, but silent history loss surprises. Recommendation: (a). The per-channel policy object itself is built in phase 1/3 scope regardless of the default chosen.
🤖 Agent note · triage task 5729 · lane B · 2026-11-01
Durable facts remain origin-signed chained events; live input uses a signed session header, MAC-authenticated frames, and signed checkpoints (256 events or 2 seconds by default).
One logical membership/relay policy uses gossip-style fan-out for chained facts and ordered per-session QUIC streams for live frames; live traffic is not queued offline.
Origin signatures establish message validity; signed hop records are audit/loop-control metadata, with a four-hop default cap.
Stock iroh-gossip's eager forwarding cannot rely on post-receive validation: phase 3 must gate forwarding on ID acceptance or use ID-controlled forwarding.
Match results and other dispute-grade outcomes remain durable and use mutual/per-transaction attestation; checkpoints alone are not verdicts.
Media stays off the gossip tree; prefer direct paths, use member selective forwarding when needed, and make privacy hairpin opt-in with address isolation.
Phased plan:#3794 session/checkpoint schema → #3795 live-stream PoC → #3796 chained relay envelope/hops → #3797 retention/compaction. Each phase has separate merge acceptance in the note; phases 2 and 3 can proceed independently after the shared schema lands.
Question for Drew: Should new chat channels default to (A) durable per-message signing/retention, with live/90-day-bounded mode opt-in (recommended), or (B) live/90-day-bounded for high-chatter rooms? Recommendation: A. No other Drew questions; relay validation, key handling, and compaction safety are implementation requirements with acceptance criteria in the note.
Agent: queue worker (repo-worker-code), lane code-i
Session / ID: task 7827
Outcome: triaged — the design deliverable for id: design: ID messaging/relay protocol v1 #2036 is complete and handed off; this issue stays OPEN as the protocol v1 parent until the remaining phases land. Nothing here is blocked except one explicitly non-blocking question for Drew (below).
The synthesis itself was delivered 2026-11-01 by triage task 5729: a decision-ready design record is posted on this issue (protocol v1 = chained/permanent vs ephemeral/live classes over iroh-gossip fan-out; origin-signature validity; segment checkpoints as graph events; no wire chunking), and the fuller design note merged via PR design(id): #2036 messaging/relay protocol v1 #3833 (MERGED 2026-11-02, doc/2026-11-01_design_id2036.md).
What should a NEW chat channel default to: (A) durable — per-message signed and kept, with live/90-day-bounded mode as a per-channel opt-in (the design record's recommendation: history loss is the failure users notice, and a channel can relax later but cannot retroactively keep what was dropped), or (B) live by default for high-chatter rooms — cheaper, but silent history loss surprises. The per-channel policy object is built in phase scope either way; packets proceed regardless of the answer.
Routing
No new follow-up needed from this triage: implementation continues under #3795–#3797 and their existing queue tasks. Close #2036 when phases 2–4 land, or earlier at Drew's direction when answering the default question.
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 30 (priority/none). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03
Agent: queue worker (repo-worker-code), lane code-l
Session / ID: task 8583
Outcome: triaged — this coverage triage (task 8583) confirms the earlier same-day triage by task 7827. Issue id: design: ID messaging/relay protocol v1 #2036 stays OPEN as the messaging/relay protocol v1 parent; the design deliverable is complete and implementation continues under the already-filed phase issues. No new follow-up is needed from this triage.
Evidence (fresh, 2026-11-03, re-verified this shift)
No drift, overlap, or superseding PR found against that routing.
Open question (Drew, non-blocking — already surfaced by task 7827, not re-escalated)
New chat channels default to (A) durable per-message signing/retention with live/90-day mode opt-in (recommended), or (B) live by default for high-chatter rooms? The per-channel policy object is built either way and the phase packets proceed regardless.
Routing
Close #2036 when phases #3795–#3797 land, or earlier at Drew's direction.
Activity
developing-today commentedon Oct 29, 2026
CODE-957
dezren39 commentedon Oct 29, 2026
Parent epic: #2056 — ID platform expansion (2026-10-28 directive).
dezren39 commentedon Oct 29, 2026
🤖 Agent note · handed off (input delivered)
doc/2026-10-29T11-05-00Z_investigation_multi_hop_relay_and_p2p_media/. Headlines for the synthesis: adopt iroh-gossip as the fan-out substrate with ID signing/membership/chaining on top; validity = origin signature only, hop chain is audit/loop control; media = direct mesh + member selective-forwarder, hairpin only in privacy-relay mode; no new wire-level chunking (QUIC streams segment; reuse welcome checked-chunking over the 1 MiB frame cap; large payloads by iroh-blobs reference).dezren39 commentedon Nov 1, 2026
🤖 Agent note · state: picked up
dezren39 commentedon Nov 1, 2026
🤖 Agent note · state: triaged — design record (queue task 5729)
Design record: ID messaging/relay protocol v1 (synthesis of #2034 + #2035)
Gate status: both inputs have landed — #2034 CLOSED (doc merged via PR #2239) and #2035 CLOSED (PR #2246 merged) — so this synthesis is ungated. Parent epic #2056.
The decision
Adopt protocol v1 as the union of the two investigation verdicts, with the open questions they left answered below. No new substrate and no new wire chunking: v1 is ID semantics layered on machinery that already exists in pkgs/id.
The protocol in one page
chain.rs:282-309). Ephemeral/live traffic (keystrokes, cursors, presence, live input) never enters the chain per-event: it rides a per-session stream authenticated by one session-header signature + a per-session MAC, closed by segment checkpoints. (Grounded today:web/collab.rsalready carries steps/cursors as unsigned MessagePack frames; only the saved revision becomes a signeddocument.put—local_events.rs:1-18.)pkgs/id/src/commands/peers.rs). A bridging member forwards to members the sender cannot reach. Validity = the origin signature alone (over content, prev-references, group, sequence); each relay appends a signed hop record outside the envelope (relay ID, previous hop, receipt time) as audit/loop control. A relay can delay or withhold — an availability fault, mitigated by duplicate paths and range-sync catch-up — but cannot forge or re-attribute. Receivers dedupe by message ID.session_id,segment_seq,prev_checkpoint,root,event_count, time bounds, signature, optional audit-blob reference (residue shape: id: investigate: ephemeral live data vs the chained event graph — retention and intermittent signing #2034 doc §7). Live views rebuild from the latest checkpoint + the ephemeral stream since it. Defaults: 256 events or 2 s, world-configurable in theWorldLimitsstyle (world/mod.rs:59-99).frames.rs:16-19); large payloads go by iroh-blobs reference. Event payloads stay bounded (world_caps.rs:65,MAX_EVENT_BYTES = 64 KiB).attestation.genesis/attestation.claimkinds inattestation.rs:1-15and id: investigate: match-result attestation — mutual concession, witness adjudication, offline play #2037's mutual-concession model are the hand-off point; segment checkpoints alone never settle a two-party dispute (the equivocation limit in id: investigate: ephemeral live data vs the chained event graph — retention and intermittent signing #2034 §4).Options considered
artifact.rsshape): the graph event inherits event_store ordering, the waiting pool, and fork proofs for free; an artifact duplicates all three. Artifact stays the right shape for identity/key material, which is not session traffic.Invariants the implementation must hold
afterresolution needs (event_store/mod.rs:12-22).Phased implementation packets (enqueued, in order)
session.checkpointevent kindrepo-health:v1:fix:developing-today/code:issue:3794repo-health:v1:fix:developing-today/code:issue:3795repo-health:v1:fix:developing-today/code:issue:3796repo-health:v1:fix:developing-today/code:issue:3797Question for Drew (explicit, non-blocking — packets proceed either way)
What should a NEW chat channel default to: durable (per-message signed, kept) or live (checkpointed, 90-day bounded)? Options: (a) durable by default, live as an opt-in per channel — recommended: history loss is the failure users notice, and a channel can relax later but cannot retroactively keep what was dropped; (b) live by default for high-chatter rooms — cheaper, but silent history loss surprises. Recommendation: (a). The per-channel policy object itself is built in phase 1/3 scope regardless of the default chosen.
🤖 Agent note · triage task 5729 · lane B · 2026-11-01
dezren39 commentedon Nov 1, 2026
Design note: ID messaging/relay protocol v1 · PR #3833
Summary
Phased plan: #3794 session/checkpoint schema → #3795 live-stream PoC → #3796 chained relay envelope/hops → #3797 retention/compaction. Each phase has separate merge acceptance in the note; phases 2 and 3 can proceed independently after the shared schema lands.
Question for Drew: Should new chat channels default to (A) durable per-message signing/retention, with live/90-day-bounded mode opt-in (recommended), or (B) live/90-day-bounded for high-chatter rooms? Recommendation: A. No other Drew questions; relay validation, key handling, and compaction safety are implementation requirements with acceptance criteria in the note.
7 remaining items
dezren39 commentedon Nov 3, 2026
🤖 Agent note · done (triaged)
Evidence (fresh, 2026-11-03)
doc/2026-11-01_design_id2036.md).The one open question (Drew, non-blocking)
What should a NEW chat channel default to: (A) durable — per-message signed and kept, with live/90-day-bounded mode as a per-channel opt-in (the design record's recommendation: history loss is the failure users notice, and a channel can relax later but cannot retroactively keep what was dropped), or (B) live by default for high-chatter rooms — cheaper, but silent history loss surprises. The per-channel policy object is built in phase scope either way; packets proceed regardless of the answer.
Routing
No new follow-up needed from this triage: implementation continues under #3795–#3797 and their existing queue tasks. Close #2036 when phases 2–4 land, or earlier at Drew's direction when answering the default question.
developing-today commentedon Nov 3, 2026
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 30 (priority/none). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03
dezren39 commentedon Nov 3, 2026
🤖 Agent note · done (triaged)
Evidence (fresh, 2026-11-03, re-verified this shift)
Open question (Drew, non-blocking — already surfaced by task 7827, not re-escalated)
New chat channels default to (A) durable per-message signing/retention with live/90-day mode opt-in (recommended), or (B) live by default for high-chatter rooms? The per-channel policy object is built either way and the phase packets proceed regardless.
Routing
Close #2036 when phases #3795–#3797 land, or earlier at Drew's direction.