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.
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
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)supersedes; with no such record, the action is still pending.python/capsule_emit/approval.py: fail-closed list_pending)spec/personal-agent-history-profile-v0.md §2)step_completed and step_failed.completeness: not_asserted.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_inclusionisNOT_CHECKEDuntil 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
}
}
| Field | Type | Meaning |
|---|---|---|
| name | string | The level's readable name. It is not a registered token and is never sent as one. |
| kind | string | projection: a view over the holder's records, not the records themselves. |
| subject_form | string | correlation: each request names one deal. |
| selection | array | The deal references the holder picked: sorted, no duplicates, never derived from counterparty, item, amount or message text. |
| reads | array | The only record fields any answer may reveal, exactly these four. |
| completeness | string | not_asserted: the selection is not claimed to be every deal. |
| recipient | string | The one requester the holder's responder answers under this definition; any other is refused (not_authorized in the vectors). |
| derivation | hex | SHA-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. |
| anchor | hex | The checkpoint the whole History is answered at; one anchor for every deal. |
| records[].digest / leaf_index | hex / int | The record's identifier and its position in the stream. No payload, counterparty or message text. |
| committed_at | time | When the holder's own stream committed the record. |
| event_time_claim | time | When the holder's agent says the step happened; a claim, shown apart from committed_at. |
| epistemic_type | string | producer_claim: the holder agent's own label, never shown as anyone else's corroboration. |
| record_type | string | step_completed or step_failed; anything else fails record_kinds. |
| deal_states.counts | object | One 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.
| Item | Status | Evidence |
|---|---|---|
Connector (tool-call) records: MCP adapter and the ConnectorPort contract | built-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_pending | built-not-live (released library) | capsule-emit python/capsule_emit/approval.py @ d51a934ebf9d3efa3c86e7f27aaafe2bc06ac05d (tag python/v0.11.0) |
| Scheduled-task seam and its record | designed, not built | No public repository defines one: searched capsule-emit @ d51a934ebf9d3efa3c86e7f27aaafe2bc06ac05d, agent-action-capsule @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c |
| A personal-agent host wiring connectors, approvals, scheduler and hooks to one book | designed, not built | No public repository at the SHAs above |
| A book answering a History request | built-not-live | The 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) | designed | Informational 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 them | built-not-live | agent-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 order | designed, not built | Display order specified in profile §6.3; no public verifier UI renders it at the SHAs above |
| Outcome claims with source labels (a later level) | planned | Profile §10, PA-9 |
| Record-level inclusion for a History answer | planned | Profile §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
- Internet-Draft draft-mih-agent-evidence-request-00 — the request, the
correlationsubject, derivation by definition digest, derivation-scoped disclosure. - Internet-Draft draft-mih-agent-evidence-layer-00 — the record header (
record_type,epistemic_type) a History reads. - Internet-Draft draft-mih-scitt-agent-action-capsule-05 — the record format capsule-emit seals for tool calls and approvals.
- Internet-Draft draft-mih-scitt-checkpointed-local-log-02 — the checkpointed log under the person's book.
- RFC RFC 8785 — JSON Canonicalization Scheme: the bytes the derivation digest covers.
- Profile spec/personal-agent-history-profile-v0.md — Personal-Agent History Profile v0 (informational, pre-Internet-Draft).
- Profile spec/interop-profile-v0.md — the interop profile (
evidence-interop/0) whose envelope and verifier a History uses unchanged. - Code action-state-group/capsule-emit python/v0.11.0 — the MCP adapter and approval records.
7What you need before the next step
- Your host's four seams named: connector calls, approvals, scheduled tasks, and a hook that carries each to the sealer.
- One correlation id per deal, chosen at random when the deal opens, and a mapping from your native step status to
step_completed/step_failed. - One holder key answering every deal of a History, and a pre-release scan for text outside the four declared fields.
- A verifier display that shows “outcomes not established” before any count, and never combines the counts.
- Next, a second party: work an agent does for someone, with a counterparty who keeps its own records.