Skip to the content.

Shared task record contract

This is the concrete adapter-neutral contract for user-level shared task state. It is the rung where humans and agents can co-edit a task board or plan without turning edits into unstructured chat.

What ships in-tree today are the JSON envelope schemas (tools/schemas/shared-*.json), the runnable fixtures under examples/shared-task-record/ and examples/shared-task-record-verdicts/, and the in-memory runtime reference fold (internal/sharedtask) with its executable fixture validator, wired under a live consumer (#3885): the gateway’s /v1/fak/sharedtask/{task_id} co-editing surface, installed by cmd/fak/sharedtask_endpoint.go and served by fak serve when the operator opts in with FAK_SHAREDTASK=1 (see Validate).

Envelopes

Task record:

{
  "schema": "fak.shared-task.v1",
  "task_id": "task_shared_demo",
  "rev": "sha256:taskrev001",
  "state": "working",
  "title": "Coordinate the shared release checklist",
  "body_ref": {
    "kind": "cas",
    "digest": "sha256:body001",
    "bytes": 512,
    "taint": "tainted",
    "scope": "fleet",
    "durability": "session"
  },
  "artifacts": [],
  "notes": [],
  "open_decisions": [],
  "updated_by": {"kind": "agent", "id": "planner"},
  "updated_at": "2026-06-25T00:00:00Z"
}

Patch:

{
  "schema": "fak.shared-patch.v1",
  "task_id": "task_shared_demo",
  "base_rev": "sha256:taskrev001",
  "actor": {"kind": "human", "id": "editor"},
  "scope": "fleet",
  "durability": "session",
  "ops": [
    {"op": "replace", "path": "/title", "value": "Coordinate the scoped release checklist"}
  ],
  "message": "Rename the collaborative task."
}

Accepted result:

{
  "schema": "fak.shared-patch-result.v1",
  "task_id": "task_shared_demo",
  "base_rev": "sha256:taskrev001",
  "current_rev": "sha256:taskrev002",
  "verdict": "accepted",
  "reason": "",
  "event_id": "evt_title_001",
  "record_ref": "sha256:taskrev002"
}

Event:

{
  "schema": "fak.shared-event.v1",
  "event_id": "evt_title_001",
  "task_id": "task_shared_demo",
  "prev_event": "",
  "event_kind": "patch_accepted",
  "actor": {"kind": "human", "id": "editor"},
  "base_rev": "sha256:taskrev001",
  "next_rev": "sha256:taskrev002",
  "scope": "fleet",
  "durability": "session",
  "taint": "tainted",
  "patch_digest": "sha256:patchtitle001",
  "verdict": "accepted",
  "reason": "",
  "ts": "logical:1"
}

Disaggregated artifact ref:

{
  "schema": "fak.shared-artifact-ref.v1",
  "artifact_id": "art_remote_trace",
  "ref": "sha256:remoteartifact001",
  "media_type": "application/json",
  "taint": "tainted",
  "scope": "tenant",
  "store": "l3-kv",
  "deletion_certificate": "sha256:deleteartifact001"
}

Materialized journal:

{
  "schema": "fak.shared-task-journal.v1",
  "task_id": "task_shared_demo",
  "initial": {
    "schema": "fak.shared-task.v1",
    "task_id": "task_shared_demo",
    "rev": "sha256:taskrev001",
    "state": "working",
    "title": "Coordinate the shared release checklist",
    "body_ref": {
      "kind": "cas",
      "digest": "sha256:body001",
      "bytes": 512,
      "taint": "tainted",
      "scope": "fleet",
      "durability": "session"
    },
    "artifacts": [],
    "notes": [],
    "open_decisions": [],
    "updated_by": {"kind": "agent", "id": "planner"},
    "updated_at": "2026-06-25T00:00:00Z"
  },
  "entries": [],
  "digest": "sha256:journal001"
}

Merge Rules

Operation Auto-merge? Notes
append note yes note id must be new; body is a scoped ref
append artifact yes artifact id must be new enough for the adapter’s policy
append open decision yes decision id must be new
replace /title or /state no requires current base; stale writers get a conflict
replace /body_ref no external refs need deletion certificate
replace open decision state no stale or missing decisions conflict

Runtime Reference Fold

internal/sharedtask is the in-memory reference fold, live in the tree and consumed by the gateway /v1/fak/sharedtask/ co-editing surface (cmd/fak/sharedtask_endpoint.go, #3885); the behavior below is the contract the fold satisfies:

Validate

The fixtures and envelope schemas that ship in-tree are self-validating as data: every fixture file declares its schema, and the schemas it names live under tools/schemas/shared-*.json. The per-schema fixture counts are pinned in each example’s EXAMPLE-OUTPUT.md.

The go test ./internal/sharedtask -run TestContract runtime witness (TestContractDocExamplesValidate, TestContractSequenceFixtureValidates, TestContractVerdictsFixtureValidates) is runnable in the live tree and validates this document’s examples plus both fixture directories through the fold. The served write-gate itself is exercised end to end by TestSharedTaskEndpointCoEditAdjudication (cmd/fak): two clients patch the same record through the gateway surface and the fold adjudicates accept / conflict / redact.

Honest Scope

This is a contract document plus a small in-memory reference fold. It is not a networked task-store daemon, not a durable mailbox, not an external L3 transport, and not a browser/editor UI.