Six sections. One truth. Tamper-evident forever.
A capsule is one cryptographically sealed record of one action your agent took. Not a log line, not a chat bubble: a structured record that answers the six questions you would ask in any audit, then is hashed, signed, and linked to the action before it.
Every action your agent takes becomes one capsule. Every capsule tells the whole story of that action through six sections, carries its own cryptographic seal, and points back at the previous capsule, forming an unbroken chain.
┌──────────────────────────────────────────────┐
│ CAPSULE (one action) │
│ │
what ───▶│ 1. TRIGGER what initiated this action │
state ───▶│ 2. CONTEXT the state of the world │
why ───▶│ 3. REASONING why this decision was made │
who ───▶│ 4. AUTHORITY who or what approved it │
what ───▶│ 5. EXECUTION what actually happened │
result ───▶│ 6. OUTCOME the result and side effects │
│ ─────────────────────────────────────────── │
│ SEAL SHA3-256 hash + Ed25519 sig │
│ LINK sequence + previous_hash │
└──────────────────────────────────────────────┘
Each section is a plain JSON object. The keys below are the conventional ones; sections are intentionally permissive (a tool can add keys), and verification never depends on section contents, only on the canonical bytes and the seal.
The origin of the action: who or what asked for it, when, and what was asked.
The environment the action ran in: which agent, which session, and provenance (working directory, git branch, model, timestamps).
"context": {
"agent_id": "cursor",
"session_id": "a3f1c2-checkout",
"environment": { "cwd": "/Users/dev/app", "git_branch": "main", "model": "claude-opus-4-8" }
}The visible deliberation. analysis holds the agent's visible prose; reasoning
holds hidden thinking text when a tool exposes it (often empty, since some tools
redact it and keep only a proof-of-reasoning signature).
"reasoning": {
"analysis": "The checkout flow calls the legacy pricing path; I'll route it through PricingService.quote().",
"reasoning": "",
"model": "claude-opus-4-8"
}The governance posture. Did the agent act on its own, under a policy, or with a human approval? This is how you see, after the fact, when an agent acted autonomously versus with a gate.
"authority": {
"type": "autonomous", // autonomous | policy | human_approved | escalated
"policy_reference": "permission_mode=acceptEdits"
}The concrete actions: the tool calls, their arguments, their results, timing, and resources used (token usage).
"execution": {
"tool_calls": [
{ "tool": "edit_file_v2", "arguments": { "file_path": "src/checkout/flow.ts" },
"result": "ok", "success": true, "duration_ms": 40, "error": null }
],
"duration_ms": 40,
"resources_used": { "input_tokens": 800, "output_tokens": 120 }
}What came of it: status, a human-readable summary, side effects, and the full result payload.
"outcome": {
"status": "success", // pending | success | failure | partial | blocked
"summary": "edit_file_v2: src/checkout/flow.ts",
"side_effects": ["wrote src/checkout/flow.ts"],
"result": "..."
}After the six sections (plus the identity and link fields) are fixed, the capsule is sealed:
"hash": "f379ba5ce838ad05...", // SHA3-256 over the capsule's canonical bytes
"signature": "2a57caf40e90ca6a...", // Ed25519 signature over the hash hex string
"signature_pq": "", // reserved for an optional post-quantum signature
"signed_at": "2026-05-31T00:00:00+00:00",
"signed_by": "153405388f063b60" // public-key fingerprintThe seal fields are not part of what gets hashed (you cannot hash a field that holds its own hash). The exact bytes that are hashed, and the precise signature scheme, are pinned in wire-format.md.
Two fields turn a pile of capsules into a tamper-evident chain:
"sequence": 1, // 0-based position in the chain
"previous_hash": "41f0ef48..." // the hash of the capsule at sequence - 1 (null at genesis)Change any byte of any capsule and its hash changes, which no longer matches
the next capsule's previous_hash, which breaks the chain at exactly that point.
That is the whole guarantee, and you can check it yourself: see
verify-it-yourself.md.
agent-capsule export turns the on-disk chains into the static JSON the
Capsule Explorer verifies.
Beyond one file per chain (each carrying the exact canonical bytes per
capsule), the bundle's index.json carries:
{
"public_key": "0edc0349...", // this machine's Ed25519 signing key
"fingerprint": "0edc03491c799def", // first 16 hex of public_key
"keys": { // the keyring: fingerprint -> public key
"0edc03491c799def": "0edc0349...", // our own key
"7879553cfff1a978": "7879553c..." // a registered known key (imported / rotated / peer)
},
"meta": { "length": 127, "head_hash": "91a8057c...", "all_hashes_ok": true },
"chains": [
{ "id": "claude-code-<session>", "signed_by": ["7879553cfff1a978"],
"started_at": "...", "ended_at": "...", "length": 2526, /* ... */ }
]
}A capsule's signed_by is a 16-char fingerprint, not a full key, so verifying a
signature needs the full public key. Our own key is always known; keys for chains
we did not sign (an imported chain, a rotated key, a peer) are registered in
~/.agent-capsule/known_keys.json and bundled into keys. The Explorer resolves
each capsule's key by signed_by and verifies every signer offline.
meta.json is a second hashchain with one capsule per sealed conversation,
recording that conversation's head hash and capsule count (in outcome.result).
Because it is itself hash-linked, its single head commits to every conversation
ever sealed, closing the two gaps a per-conversation chain cannot: deleting a
whole conversation and truncating a conversation's tail. Verify it with
agent-capsule verify-meta.
{
"id": "a3f1c2e9-...-uuid",
"type": "tool", // tool | chat | agent | system
"domain": "cursor", // the tool that produced it
"parent_id": null,
"sequence": 1,
"previous_hash": "41f0ef48...",
"spec_version": "1.0",
"trigger": { "type": "user_request", "source": "a3f1c2-checkout", "request": "Refactor the checkout flow..." },
"context": { "agent_id": "cursor", "session_id": "a3f1c2-checkout", "environment": { "cwd": "/Users/dev/app", "model": "claude-opus-4-8" } },
"reasoning": { "analysis": "Route checkout through PricingService.quote()", "reasoning": "", "model": "claude-opus-4-8" },
"authority": { "type": "autonomous", "policy_reference": "permission_mode=acceptEdits" },
"execution": { "tool_calls": [ { "tool": "edit_file_v2", "arguments": { "file_path": "src/checkout/flow.ts" }, "result": "ok", "success": true, "duration_ms": 40, "error": null } ], "duration_ms": 40, "resources_used": { "input_tokens": 800, "output_tokens": 120 } },
"outcome": { "status": "success", "summary": "edit_file_v2: src/checkout/flow.ts", "side_effects": ["wrote src/checkout/flow.ts"], "result": "ok" },
"hash": "f379ba5c...", "signature": "2a57caf4...", "signature_pq": "",
"signed_at": "2026-05-31T00:00:00+00:00", "signed_by": "153405388f063b60"
}Open any capsule in the Capsule Explorer to see these six sections rendered, with each section's seal re-verified live in your browser.
The sections above are the skeleton. What makes a capsule worth reading is the content each adapter pulls from its tool's transcript. Capsules record what an action did, not just that it ran:
- Real diffs. File edits carry a rendered unified diff with
(+N/-M)line counts in the summary. (Claude CodestructuredPatch, Codexapply_patchV4A envelope, Cursor/Cline edit payloads.) - Full tool results. Bash/shell capsules carry actual stdout and stderr; Read carries the file content and line count; Web search carries the query and the returned URLs. Cline joins its API history so even read/search/MCP tools carry their results.
- The model's reasoning. Where a tool persists it (Codex reasoning items,
Cursor/Cline thinking blocks), the deliberation lands in
reasoning.reasoning. Claude Code redacts thinking text, so the capsule records the proof-of-reasoning signature and athinking_redactedflag instead. - Subagent fan-out. A delegated subagent capsule carries a scorecard:
[Explore: 2 edits, +14/-3, 9 tool calls], so the parent chain shows what its children did. - Cost and provenance. Token usage (including cache and reasoning tokens), per-turn model and context-window telemetry, checkpoint hashes, and, for Cursor, a per-conversation AI-authorship rollup from its code-tracking DB.
Heavy raw blobs (whole original files, base64 screenshots, entire subagent transcripts) are deliberately summarized or referenced rather than inlined, so capsules stay readable and the chain stays light. Per-tool specifics and their caveats are in tools/.
- wire-format.md: the exact canonical bytes, hash, and signature scheme.
- verify-it-yourself.md: re-derive the hash and check the signature in any language.
- architecture.md: how each tool's transcript becomes capsules.