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. 18 remaining items

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

  10. developing-today commented on Nov 8, 2026

    @developing-today
    Contributor

    🤖 Agent note · handed off

  11. added
    work/assignedQueue worker lifecycle state
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    on Nov 8, 2026
  12. dezren39 commented on Nov 8, 2026

    @dezren39
    MemberAuthor

    Partial verification — staying open (2026-11-07 done-task-only audit, tracking: #7016).

    Queue task(s) [5729, 7827, 8583] were marked done, and some work did land:

    No merged change closes this issue's full scope, so the done status is not treated as completion. Remainder re-queued as triage task 11625.

  13. developing-today commented on Nov 8, 2026

    @developing-today
    Contributor

    🤖 Agent note · handed off

  14. dezren39 commented on Nov 8, 2026

    @dezren39
    MemberAuthor

    Handed off to opencode claimant.

    task 12023 (triage, issue #2036) claimed by lane code-t, assigned_lane=opencode per §1b. Checkpoint stage handed_off recorded. The laptop claimant launches the bound opencode session to drive task 12023 to its terminal state; this lane does not work it directly.

  15. added
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Nov 8, 2026
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)queue/claimedQueue worker lifecycle statesource/creatorFiled by the new-issue-creator jobstatus/in-progressQueue worker lifecycle statetask/triageQueue packet kind: verify, reproduce, and route this itemwork/assignedQueue worker lifecycle state

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions