Skip to content

id: PoC: mutual-concession match attestation on the tic-tac-toe example — genesis agreement + dual signed result claims, offline-first (from #2037) #2248

Closed

Description

@dezren39

From the #2037 investigation (match-result attestation)

Investigation #2037 (queue task 3350, result posted on that issue 2026-10-29) specified the attestation object layer for ID matches: genesis agreement (both players sign game + logic hash + named witness + objection window), per-player signed result claims, agreed/final states computed from the objects, witness decision and objection as signed events, fork-proof voiding via existing event-store mechanics. This issue is the proof of concept for the concession path — the program pattern is design + PoC, and a PoC is not the permanent feature: nothing production is built on top of this without a review round (epic #2056).

PoC scope (existing tic-tac-toe example, pkgs/id/examples/tic-tac-toe)

  1. Two players play a match with a signed genesis agreement object (game id, logic/version hash, both player IDs, witness slot left unused for this PoC, objection window parameter present).
  2. At match end each player emits a signed result claim (outcome, final-state hash, both chain frontiers).
  3. A viewer computes the result state from the objects alone: proposed → agreed when both claims concur; conflicting claims → disputed.
  4. The whole exchange is demonstrated offline-first: match + attestation complete with no server, then sync to a second store which computes the identical state.
  5. Negative case demonstrated: one player's claim names the wrong winner → state is disputed, never agreed.

Out of scope

Witness decision flow, objection handling, audit replay (that is #2038 / synthesis #2039 territory), registries/rankings, any production API.

Acceptance criteria


Program: ID platform expansion, epic #2056. Parent investigation: #2037. Related: #2038 (match audit), #2039 (attestation + audit design v1, gated), #2030 (trust/visibility — counting views).

Activity

  1. added
    priority/highImportant and time-sensitive
    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. 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
  4. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  5. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    Triage findings — #2248 attestation PoC (queue task 3403)

    Verdict: live, correctly scoped, and an implementation build — not a triage-sized fix. Issue is OPEN, no held / user-owned / do-not-* labels, no competing PR or branch found for attestation work. Routed to a follow-on implementation task (enqueued this pass; see closing agent note).

    Verified against current main (2026-10-30, fresh gh reads)

    • No attestation layer exists: code search for attestation in pkgs/id/src/ returns only unrelated world-module provenance wording (src/world/mod.rs: "not a signature or a trust attestation"); no genesis-agreement, result-claim, concession, or disputed-state object exists. This matches the id: investigate: match-result attestation — mutual concession, witness adjudication, offline play #2037 investigation's verdict (task 3350, comments on id: investigate: match-result attestation — mutual concession, witness adjudication, offline play #2037).
    • Primitives the PoC composes do exist: signed chained events in pkgs/id/src/chain.rs, event store in pkgs/id/src/event_store/ (ingest.rs, sync.rs, resolve.rs — including fork/equivocation handling), and sync in src/event_sync.rs / src/log_sync.rs. The offline-then-sync scope point should ride the existing store sync, not a new transport.
    • Target example is minimal and pure: pkgs/id/examples/tic-tac-toe/ is main.roc + README + build.sh + prebuilt wasm. main.roc's update is a pure function of (model, event) and its records already publish {"board": "...", "plays": N, "winner": "X"} as JSON — so the final-state hash in a result claim can be taken over the replayed board/records, and the winner for the negative case is unambiguous.
    • Existing test surfaces to extend: pkgs/id/tests/event_store_properties.rs, chain_properties.rs, multidevice.rs, voiding_scenarios.rs — a PoC expressed as an integration test/example under pkgs/id/tests/ (or a small example crate) fits the repo's conventions better than touching the Roc world program itself.

    Recommended implementation shape (for the follow-on task)

    1. Define the two PoC objects as ordinary signed events per id: investigate: match-result attestation — mutual concession, witness adjudication, offline play #2037: genesis agreement {game id, logic/version hash (hash of tic-tac-toe main.roc/wasm), both player IDs, witness slot unused, objection-window parameter} and per-player result claim {match, outcome, final-state hash, both chain frontiers}.
    2. A pure viewer function computing proposed → agreed on concurring claims and disputed on conflicting claims, from the objects alone.
    3. Demonstration harness: play/attest in one store with no server, sync to a second store, assert identical computed state; negative case (one claim names the wrong winner) asserts disputed, never agreed.
    4. Document the object shapes in the PR and post the findings note required by the acceptance criteria — what the PoC proved / did not prove. No production API, no witness/objection flow (id: investigate: match audit — netcode log format, replay validation, and cheating signals #2038/id: design: match attestation + audit v1 #2039 territory, explicitly out of scope).

    Sizing / risk

    • Effort class L (new object types + viewer + two-store harness), medium risk: design-sensitive but fully additive and PoC-scoped; nothing existing is modified in behaviour.
    • This triage task (3403) closes as triaged; the build itself is the follow-on queue task named in the closing note.
  6. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

  7. 11 remaining items

  8. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · findings (PoC implemented, PR #2854)

    What the PoC proved about the #2037 object shapes

    • The two shapes suffice for the concession path: a genesis agreement signed identically by both players (as ordinary attestation.genesis chain events) plus one attestation.claim per player carrying {agreement hash, outcome, final-state hash, both frontiers} lets a pure viewer compute Proposed/Agreed/Disputed from the objects alone — no server, no store-specific state.
    • Offline-first works with the existing primitives exactly as triage predicted: signed chained events + the event store's ingest hold the whole exchange offline, and a second store fed the first store's applied event bytes (+ the bodies those headers commit to) computes the identical state over the identical event-id set.
    • The negative case holds: a wrong-winner claim computes Disputed, never Agreed; a single claim stays Proposed; a player double-claiming different outcomes also computes Disputed.
    • The final-state hash binds cleanly to the example's own published record ({"board":…,"plays":5,"winner":"X"}), and the logic hash to main.roc bytes — no Roc program changes were needed.

    What it did not prove

    Also noted while routing: the earlier triage note named "follow-on task 3941" for this PoC — that number is a different, unrelated queued task (triage #2816, verified live in the queue). Task 3953 is the sole fix task carrying the issue:2248 dedupe key.

  9. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    and removed
    queue/claimedQueue worker lifecycle state
    on Oct 30, 2026
  10. added a commit that references this issue on Oct 30, 2026
  11. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done (merged)

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

    @dezren39
    MemberAuthor

    Completed via PR #2854 (merge commit 0744857)

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