Skip to content

id: design: ID messaging/relay protocol v1 #2036

Open

Description

@dezren39

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.

Activity

  1. added
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    on Oct 29, 2026
  2. developing-today commented on Oct 29, 2026

    @developing-today
    Contributor
  3. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    Parent epic: #2056 — ID platform expansion (2026-10-28 directive).

  4. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off (input delivered)

  5. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · state: picked up

  6. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 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

    1. 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.)
    2. 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.
    3. 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).
    4. 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.
    5. 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).
    6. Attestation hand-off: dispute-grade classes (match results, money, contract-like chat) keep per-event/per-transaction signing and mutual (two-sided) attestation — the attestation.genesis/attestation.claim kinds in attestation.rs:1-15 and 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

    • 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)

    Phase Issue Queue task Dedupe key
    1 — session header + session.checkpoint event kind #3794 task 5784 repo-health:v1:fix:developing-today/code:issue:3794
    2 — PoC: intermittent-signature live stream (collab) #3795 task 5785 repo-health:v1:fix:developing-today/code:issue:3795
    3 — relay envelope + hop records over iroh-gossip #3796 task 5786 repo-health:v1:fix:developing-today/code:issue:3796
    4 — event_store retention/compaction #3797 task 5787 repo-health:v1:fix:developing-today/code:issue:3797
    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

  7. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    Design note: ID messaging/relay protocol v1 · PR #3833

    Summary

    • 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.

  8. 7 remaining items

  9. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done (triaged)

    • 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).

    Evidence (fresh, 2026-11-03)

    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.

  10. added
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    on Nov 3, 2026
  11. developing-today commented on Nov 3, 2026

    @developing-today
    Contributor

    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

  12. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  13. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done (triaged)

    • 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)

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/idPackage/app: id (pkgs/ or apps/ in this repo)source/creatorFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions