Agent Action Capsule · build your own evidence layer
b6 / 11

Personal agents

Seams ① Record to ⑤ View. Build: the five layers for an agent acting for one person. Conform to: draft-mih-agent-evidence-request-00 (the History profile).

The same five layers, applied to an agent that acts for one person: the host's seams, the records they produce, the person's own book, the deals those records belong to, and a History the person chooses to share, which shows counts and makes no outcome claim.

Five layers of an evidence layer for a personal agent Left: a personal agent host with four seams: connectors, approvals, scheduler and hooks. Step 2: a connector call becomes a signed record with argument and result digests and effect dispatched. Step 3: an approval becomes a record chained to the blocked action with the relation supersedes. Step 4: a scheduled task's record is drawn dashed and marked designed, not built. Step 5: the records are appended to the person's own book, a stream of eight step records over four deals A to D, with a checkpoint; D has one failed step and B has one failed step. Step 6: the person selects deals A, B and C for one recipient under the definition personal_history_basic/1, completeness not asserted; deal D is left out. Step 7: a History card shows outcomes not established, 3 selected deals, 1 with a recorded failed step, 2 with completed steps only, 0 with no recorded step, and record inclusion not checked. Counts only, no ranking. 1 seams 2 records 3 book · 4 deals 5 shareable read Personal agent host Connectors tool calls (MCP, HTTP) Approvals a person says yes / no Scheduler runs with nobody there Hooks carry events to the sealer Record: connector call args · result: digests only effect: dispatched signed by the agent's key Record: approval decision: approve | deny chain: supersedes → blocked no approval record = pending Record: scheduled task no public scheduler seam yet designed, not built Own book append-only A ✓ B ✓ D ✓ A ✓ C ✓ D ✗ B ✗ D ✓ checkpoint ✓ step_completed ✗ step_failed A–D: 4 deals (one correlation id each) Definition, 1 recipient personal_history_basic/1 selection: A, B, C reads: 4 fields completeness: not_asserted D left out History card outcomes: not established 3 selected deals 1 with a recorded failed step 2 completed steps only 0 with no recorded step inclusion: NOT_CHECKED signed by the holder key counts only, no ranking Deals, records and counts are those of the published vectors (agent-action-capsule vectors/personal-history-basic-v0, case history-basic)

1What it is

A personal agent acts for one person: it calls tools through connectors, waits for that person's approval on some actions, and runs scheduled tasks while nobody is watching. Each of those is a place where the host can hand an event to code that seals a signed record.

The records go into the person's own append-only book, grouped into deals (one correlation id each), and each record says whether a step the agent recorded completed or failed.

When the person wants to show someone what their agent recorded, they pick some deals for that one recipient, and the recipient gets a History, signed by the holder key, that counts the selected deals by state and states plainly that no outcome is established.

2Design choices

Chosen: seal what changes the world, plus reads of sensitive data; a read-only tool call is observability, not a record.
Rejected: sealing every call; a query (MCP readOnlyHint: true, an HTTP safe method) is observability, not a consequential-action record, unless it reads sensitive data. (capsule-emit docs/whats-consequential.md, the two-signal rule; MCP readOnlyHint, HTTP safe methods)
Chosen: an approval is its own signed record, chained to the blocked record with the relation supersedes; with no such record, the action is still pending.
Rejected: marking an action approved without a chained record. (capsule-emit python/capsule_emit/approval.py: fail-closed list_pending)
Chosen: the subject of a History is the holder's signing key, not a person, a name or an account.
Rejected: naming the person; a label the holder attaches to the key is the holder's own statement and is never checked. (spec/personal-agent-history-profile-v0.md §2)
Chosen: a closed list of two record kinds for a History: step_completed and step_failed.
Rejected: any other record type, which could name an item, a category or a counterparty. (profile §3)
Chosen: a History is a recipient-specific disclosure; its identifier is the SHA-256 of the canonical (JCS) definition, which names the recipient and the selection, so two recipients get two identifiers.
Rejected: a registered derivation token sent on the wire, or presenting a History answer as the canonical answer for the deal it covers. (profile §4, §4.2)
Chosen: the holder selects deals, and the definition says completeness: not_asserted.
Rejected: implying the selection is everything; a holder can leave out any deal, and a verifier shows that the selection is not claimed to be complete. (profile §4.1, §9)
Chosen: counts in their own units: selected deals, and the count of each deal state; records counted separately.
Rejected: any figure that adds deals to records, combines across deals, holders or counterparties, or orders or grades them. (profile §5, §9 “No ordering”)
Chosen: before release, the holder's host byte-scans every reply for text outside the four declared fields (names, contact details, items, amounts, message text, unselected deal references).
Rejected: relying on the recipient's verifier alone, which checks the field set but cannot spot text it has never seen. (profile §4.4)

3What it shows / what it does not

Shows

  • For a connector call or approval record: that the key named in the record signed its id, and that its content matches that id (the id recomputes).
  • For a History: which deals the holder selected for this recipient.
  • When each record was committed to the holder's stream, and the event time the agent claimed, as two separate times.
  • Whether each recorded step completed or failed, as the holder's agent recorded it.
  • That one holder key answered for every selected deal, at one anchor.

Does not show

  • Any outcome: sale, payment, delivery, receipt or return. A recorded completed step is not a completed sale.
  • That the selection is all of the holder's deals.
  • That anything happened at the claimed event time; neither time is witnessed.
  • Who holds the key, or that the key's holder made the deals.
  • Record-level inclusion for a History answer: anchor_inclusion is NOT_CHECKED until the interop profile registers the material for it (PA-13).
  • That two recipients cannot link a shared deal: deal references and record digests are the same in every History (§4.5, PA-7).

4Example

The positive case of the published conformance vectors: a holder stream of four deals, three selected for one recipient. Below are the definition the recipient holds, the artifact of one reply (deal 50c8…, decoded from the reply's base64url artifact), and the deal states the test derives. All keys are test keys.

// inputs.definition
{
  "completeness": "not_asserted",
  "kind": "projection",
  "name": "personal_history_basic/1",
  "reads": ["committed_at", "epistemic_type", "event_time_claim", "record_type"],
  "recipient": "recipient-1",
  "selection": [
    "50c896dcc67b046d2e960466df3d7ce4",
    "6d443544e41e7d4878ff95318777cc05",
    "a34e091973f2480c793ad9b9bc5aa118"
  ],
  "subject_form": "correlation"
}

// inputs.exchanges[0].reply, its "artifact" decoded
{
  "anchor": "c417672f9e12bb4282024b2f159f2ecd09ffd01409ce7e0a531024fb142d6c51",
  "derivation": "68c06bd846ae2a0238b6e65b5f10cdf0325a6a9e58b11ed54e0c3da6d6b92192",
  "evidence_stream": "holder-stream-1",
  "records": [
    {"committed_at": "2026-10-15T00:00:02Z",
     "digest": "704d9aae72ed4b26b05f1a8d208d2088313fd8cd0a5d05dd55d649111fbe4d5f",
     "epistemic_type": "producer_claim",
     "event_time_claim": "2026-10-14T23:25:02Z",
     "leaf_index": 1, "record_type": "step_completed"},
    {"committed_at": "2026-10-15T00:00:10Z",
     "digest": "a75ff16c0494f91f13471a41c8a0673c1619f0cd03fc93189cf7c5158c86981f",
     "epistemic_type": "producer_claim",
     "event_time_claim": "2026-10-14T23:50:10Z",
     "leaf_index": 8, "record_type": "step_failed"}
  ],
  "subject": {"correlation": "50c896dcc67b046d2e960466df3d7ce4"}
}

// expected.deal_states (abridged: per_deal omitted)
{
  "selected_deals": 3,
  "counts": {
    "with a recorded failed step": 1,
    "with recorded completed steps only": 2,
    "with no recorded step": 0
  }
}
FieldTypeMeaning
namestringThe level's readable name. It is not a registered token and is never sent as one.
kindstringprojection: a view over the holder's records, not the records themselves.
subject_formstringcorrelation: each request names one deal.
selectionarrayThe deal references the holder picked: sorted, no duplicates, never derived from counterparty, item, amount or message text.
readsarrayThe only record fields any answer may reveal, exactly these four.
completenessstringnot_asserted: the selection is not claimed to be every deal.
recipientstringThe one requester the holder's responder answers under this definition; any other is refused (not_authorized in the vectors).
derivationhexSHA-256 of the definition's canonical JSON; the holder key signs it in every reply, so it binds the recipient, the selection and the field set.
anchorhexThe checkpoint the whole History is answered at; one anchor for every deal.
records[].digest / leaf_indexhex / intThe record's identifier and its position in the stream. No payload, counterparty or message text.
committed_attimeWhen the holder's own stream committed the record.
event_time_claimtimeWhen the holder's agent says the step happened; a claim, shown apart from committed_at.
epistemic_typestringproducer_claim: the holder agent's own label, never shown as anyone else's corroboration.
record_typestringstep_completed or step_failed; anything else fails record_kinds.
deal_states.countsobjectOne state per selected deal, counted per state. Deal 50c8… has a failed step, so it counts under “with a recorded failed step”.

The reply that carries this artifact is in the vectors, driven by their producer/main.go; any conforming book must produce the same reply. The twelve cases are this positive run, ten mutant cases covering the nine mutants of the profile's §6.4 (each fails the property §6.4 names), and one refusal to another requester.

Source: action-state-group/agent-action-capsule:vectors/personal-history-basic-v0/vectors.json (case history-basic) @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c

5Status

Tags: live running in a personal-agent host (none today) · built-not-live merged or released at a SHA, not running in any personal-agent host · designed written down, no code · planned named as an open point, not designed.

ItemStatusEvidence
Connector (tool-call) records: MCP adapter and the ConnectorPort contractbuilt-not-live (released library)capsule-emit python/capsule_emit/adapters/mcp.py, python/capsule_emit/connector.py @ d51a934ebf9d3efa3c86e7f27aaafe2bc06ac05d (tag python/v0.11.0, released 2026-10-16)
Approval records: seal_approval, list_pendingbuilt-not-live (released library)capsule-emit python/capsule_emit/approval.py @ d51a934ebf9d3efa3c86e7f27aaafe2bc06ac05d (tag python/v0.11.0)
Scheduled-task seam and its recorddesigned, not builtNo public repository defines one: searched capsule-emit @ d51a934ebf9d3efa3c86e7f27aaafe2bc06ac05d, agent-action-capsule @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c
A personal-agent host wiring connectors, approvals, scheduler and hooks to one bookdesigned, not builtNo public repository at the SHAs above
A book answering a History requestbuilt-not-liveThe positive case and its mutants: action-state-group/agent-action-capsule:vectors/personal-history-basic-v0/ @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c
Personal-Agent History Profile v0, Basic level (personal_history_basic/1)designedInformational host profile, pre-Internet-Draft. agent-action-capsule#259, MERGED 2026-10-15 (merge 995c377bf3fbc5a50630a07c998c0d0fce315a87); spec/personal-agent-history-profile-v0.md @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c
Conformance vectors (12 cases) and the Python check that runs thembuilt-not-liveagent-action-capsule#296, MERGED 2026-10-17 (merge 0b7b1825965e7f7845cbc70a490a581cbc70bd37); vectors/personal-history-basic-v0/, python/tests/test_personal_history_basic_v0_vectors.py @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c
A History card: a verifier display in the profile's §6.3 orderdesigned, not builtDisplay order specified in profile §6.3; no public verifier UI renders it at the SHAs above
Outcome claims with source labels (a later level)plannedProfile §10, PA-9
Record-level inclusion for a History answerplannedProfile §10, PA-13: anchor_inclusion stays NOT_CHECKED until the interop profile registers the material

Not to be confused: history_card/1 is a different derivation, registered by the evidence-request Internet-Draft (a checkpoint history with no record content). The personal History on this page is personal_history_basic/1, a separate, recipient-specific derivation.

6Specs

7What you need before the next step