Skip to content

id: investigate: match-result attestation — mutual concession, witness adjudication, offline play #2037

Closed

Description

@dezren39

LIST 10a. For central game tracking that allows distribution and OFFLINE play — without Drew's live servers running every game: players hold matches themselves. A result counts when both agree who won (chess-style: the loser says the other won), OR both players send their data to a user acting as WITNESS who runs the witness game logic over both users' messages and decides a winner — valid as long as neither player objects to the witness's judgment. Investigate: attestation objects, objection windows/mechanics, witness selection and trust, and how offline results sync when a player reconnects. Results may flow peer-to-peer or to a gatherer (not necessarily Drew) and count when everybody agrees.

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. added
    priority/highImportant and time-sensitive
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 29, 2026
  5. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    Top priority — ID program wave-1. Drew directed this be picked up in the next runs (2026-10-29): enqueued directly as triage task 3350 in repo-health-code-pilot at queue priority 20 (only breakage-class work at priority 10 outranks it). Wave-1 is the ungated investigations and designs; syntheses and PoCs stay gated on their named inputs. Investigation route: Workhorse.

  6. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 29, 2026
  7. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  8. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    Investigation result — match-result attestation (#2037, queue task 3350)

    Verdict

    The premise is sound and the primitives already exist; the attestation layer does not. Verified against pkgs/id:

    • Every object in the system is a signed, chained event (src/chain.rs: canonical encoding, verify_strict signatures, per-author sequence/backlink chains). A match played over ID is therefore already two signed move-chains — exactly the evidence base attestation needs.
    • The event store already treats equivocation as provable: a fork (two events at one sequence number) produces a kept fork proof and voids the author's events from the fork point (src/event_store/ingest.rs). A player who rewrites their match history manufactures their own cheating evidence.
    • No attestation, concession, witness, or result object exists in src/ today (grep-verified). This investigation specifies that layer; it composes with the audit investigation id: investigate: match audit — netcode log format, replay validation, and cheating signals #2038 (replay of the netcode log) and feeds the gated synthesis id: design: match attestation + audit v1 #2039.

    The objects (all ordinary signed events in the graph)

    1. Match agreement (genesis) — signed by both players before play: game/program identity including the rules/logic hash, the two player IDs, start conditions, the named witness (and fallback), the objection-window length, and the log-submission rule (below). Pre-committing the witness and the logic hash at genesis is the single most important design decision in this document: everything after the match is mechanical because the trust choices were made before anyone knew who would lose.
    2. Result claim (per player, at match end) — {match, outcome as the author asserts it, final-state hash, frontier hashes of both chains} signed by the author. Each player files one; neither player's claim alone is a result.
    3. Witness decision — {match, both result claims + both move-log hashes, logic hash, outcome} signed by the witness named in the agreement, issued after running the agreed logic over both submitted logs.
    4. Objection — {target: claim or decision, grounds, author's frontier} signed by either player within the window. An objection never edits anything; it moves the result to disputed.
    5. Receipt/frontier evidence — no new object: objections and claims cite chain frontiers, so "when could this author first have seen the decision?" is answerable from the chains themselves (used by the offline rule below).

    Result states (computed by any viewer from the objects — no server decides)

    proposed (one claim) → agreed (both claims concur — the chess concession case: the loser's signed claim naming the winner is the concession, no separate object needed) → final (agreed results are final immediately; witnessed results become final when the window closes unobjected) · witnessed (decision issued, window open) · disputed (claims conflict, or an in-window objection exists) · void (a fork proof touches either player's match chain — the attestation built on it collapses automatically under existing store rules).

    A result "counts" only relative to a counting view (the #2030 model): a casual tracker may count agreed; a tournament registry counts only final, and only for matches whose agreement names an acceptable witness/logic hash. Attestation proves agreement and process, never metaphysical truth — registries set their own bar on top.

    Witness selection and trust

    • Ex ante or never: the witness is named in the genesis agreement by both players. A witness proposed after a dispute is witness-shopping and the protocol gives it no standing.
    • The witness judges data, not testimony: they run the agreed logic (hash pinned at genesis) over both players' submitted move logs. Deterministic logic ⇒ any third party, and specifically the id: investigate: match audit — netcode log format, replay validation, and cheating signals #2038 auditor, can re-run the same inputs and check the decision. A witness whose decision disagrees with a replay has produced signed evidence against themselves.
    • Non-submission rule: if one player withholds their log, the witness may decide on the submitted log plus the recorded refusal, with adverse inference only if the genesis agreement says so (it should, as the default template). Silence must never beat submission.
    • Quorum option: high-stakes templates may name 2-of-3 witnesses; the state machine is unchanged (a decision needs the quorum's signatures). Keep this a template variant, not the base protocol.
    • Trust accrues publicly: decisions are permanent signed objects, so a witness's track record is computable by anyone (decisions issued, how many overturned via audit) — reputation falls out of the graph instead of needing a reputation system.

    Objection windows, honestly — including offline

    • Window length is a genesis parameter (template default should scale with match stakes; hours–days, not minutes — these are async/offline games).
    • The offline problem: a wall-clock window punishes the player who was offline when the decision synced. Rule proposed: an objection is in-window if (a) signed within the window after the decision, or (b) the objector's chain frontier shows the objection was among their first actions after first syncing the decision — i.e. they objected promptly once they could have seen it. (b) is checkable from causal frontiers, needs no trusted clock, and cannot be gamed by delaying one's own sync indefinitely if registries additionally apply an outer wall-clock cap (e.g. objections after 30 days never reopen a final result — finality must eventually be final).
    • An objection's only automatic effect is disputed. Resolution of a dispute is the audit path (id: investigate: match audit — netcode log format, replay validation, and cheating signals #2038): replay decides who is right, and the replay outcome, not the objection, is what a registry's view should count.

    Offline play and sync

    Nothing here needs a live server at any point: agreement, moves, claims, decisions, objections are all signed events held by whoever has them (players, witness, any gatherer). On reconnect they sync through the existing event sync; the result state is a pure function of the object set, so two peers who have synced the same objects compute the same state, and a gatherer/registry is just a well-connected store — results "flow to" it by sync, not by submission to an authority. A match played entirely offline between two players attests completely with zero infrastructure; the witness path needs only eventual delivery of both logs to the witness.

    Abuse cases

    1. Loser refuses to concede, claims they won → conflicting claims ⇒ never agreed; witness path (named at genesis) decides from the logs. ✅
    2. Loser goes silent (no claim, no log) → non-submission rule: witness decides on the winner's log + recorded silence; registries may also simply never count a one-claim match. ✅
    3. Player rewrites their move history after the fact → fork proof voids their chain from the fork point; result becomes void, and the proof is the cheating evidence for id: investigate: match audit — netcode log format, replay validation, and cheating signals #2038. ✅ — the strongest case in this design, and it is free from existing store mechanics.
    4. Witness colludes with one player → decision is signed; objection triggers audit replay (id: investigate: match audit — netcode log format, replay validation, and cheating signals #2038) over the same logs + logic hash; a decision contradicted by replay is permanent signed evidence against the witness. ⚠️ Detection is strong; remedy (what a registry does about the match) is registry policy — flagged for id: design: match attestation + audit v1 #2039.
    5. Witness-shopping after a loss → no standing: only the genesis-named witness (or fallback, on recorded non-response) can issue a decision a view should count. ✅
    6. Two players fabricate a match (fake win to farm a ranking) → attestation cannot and does not prevent mutual fiction; it proves both agreed. Registries defend at their view layer: require witnessed matches, known-opponent sets, or stake. Named explicitly so nobody oversells concession as truth. ⚠️ Accepted, bounded by registry policy (id: investigate: trust/visibility model — servers accept all signed objects; views count only allowed writers #2030 counting views).
    7. Bought/coerced concession → indistinguishable from an honest concession in-protocol. Out of scope for the object layer; higher-tier registries requiring witnessed + auditable matches are the mitigation. ⚠️ Accepted residual risk.
    8. Objection griefing (object to everything, keep results perpetually disputed) → objections are cheap to file and expensive only if they win audits; a registry may require objections to cite grounds + the objector's log, and audit losses are permanent signed record. Rate/abuse controls are id: investigate: comms abuse controls — blocks, rate limits, and per-counterparty budgets #2032's layer. ⚠️

    Not decided here (for synthesis #2039, gated on #2038 as well)

    Wire format and template defaults (window lengths, outer cap, adverse-inference wording); witness non-response/fallback timing; how registries express "acceptable witness/logic" policy (likely a #2030 writer-set cousin — a witness set on the registry's view); dispute-remedy policy (case 4).

    Follow-on routing (same pass)

    🤖 Agent note · done — queue worker (repo-worker-code), lane C, task 3350. Investigation recorded here; PoC follow-on filed + enqueued; synthesis #2039 remains gated on #2038.

  9. 3 remaining items

  10. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    Queued: repo-health-code-pilot task 3921 (2026-10-30), wave-2 follow-on. The 2026-10-29 triage verified this issue and recorded 'write the investigation' as the next step; this task is that write — investigation doc PR under doc/, follow-up issues for buildable pieces, close with the doc link. Ordered by Drew ('queue unrun').

  11. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

    • Agent: queue worker (repo-worker-code), lane E
    • Session / ID: queue task 3921 (repo-health-code-pilot), shift 2026-10-30 14:09 CDT
    • Found via: queue claim
    • Task: Write the wave-2 investigation doc for match-result attestation (mutual concession, witness adjudication, offline play) under doc/ via PR; the 2026-10-29 wave-1 pass (task 3350) recorded the investigation as a comment here but it never landed as a design doc. This is that write — not a re-triage.
    • Expectation: effort/m — done = doc PR opened (and merged under the standing criteria), summary comment here linking the doc, buildable follow-ups filed, issue closed with the doc link.
    • Links: branch queue/3921-2037-attestation-investigation (to be created on the laptop fleet worktree)
  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 Oct 30, 2026
  13. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

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)priority/highImportant and time-sensitive

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions