Agent Action Capsule · explain
02 / 11

Agent Action Capsule

A Capsule is a JSON record of one agent action that commits to what went in and what came out by digest, never by content, and whose identity is the SHA-256 of its own canonical bytes.

From request and response to a chained Capsule Stage 1: two boxes on the left, the inference request body and the completion body, held by the producer. Stage 2: each body is hashed with SHA-256 over its JCS form, giving two digest chips, request_digest and response_digest; the bodies are marked as staying local. Stage 3: the two digests flow into a Capsule box whose effect record shows type inference_completion, status confirmed, effect_attestation host_served_observed, and the two digests; below it the capsule_id is computed as SHA-256 over JCS of the Capsule with capsule_id removed, b1f60932 through df90c753. Stage 4: a previous Capsule appears on the right and an arrow labelled chain.parent_capsule_id, relation follows, links the new Capsule to it. Stage 5: a timeline along the bottom shows Capsules of epoch e1, then an epoch_opens Capsule carrying the new epoch_id e2 whose chain parent is the last Capsule of e1, followed by Capsules of e2. Request body as received at servingboundary Completion body as returned request_digest 1111…1111 response_digest 2222…2222 SHA-256(JCS(body)) bodies stay local Capsule effect.type: inference_completion status: confirmed effect_attestation: host_served_observed request_digest: 1111… response_digest: 2222… canonicalization_id: jcs … operator, timestamp, … capsule_id = SHA-256(JCS(Capsule − capsule_id)) b1f60932…df90c753 previous Capsule its capsule_id chain.parent_capsule_id relation: follows one parent, same stream epoch e1 epoch_opens epoch e2 (new model or policy) arrows point from child to parent

1What it is

An Agent Action Capsule is a JSON record of one agent action and its outcome, including actions that were refused, blocked, or timed out.

Sensitive content such as prompts, completions, and tool payloads is not carried in the record; it is committed to by SHA-256 digest only.

The Capsule's identity, its capsule_id, is the SHA-256 of its own canonical JSON, so any verifier can recompute it; a later edit shows once that id is checked against a Producer Envelope or receipt made over the original.

2Design choices

Chosen: commit content by digest; the Capsule carries request_digest and response_digest, not the bodies.
Rejected: carrying raw content. A committed Capsule cannot be retracted, so anything admitted is admitted permanently; content that must be checkable later but not disclosed now is committed as a digest. (Draft §5, §14.1)
Chosen: a signer-independent identity: capsule_id is SHA-256 over plain JCS of the Capsule with only capsule_id removed, and a COSE_Sign1 Producer Envelope signs those raw 32 bytes.
Rejected: making the signature part of the identity. Envelopes are not in the preimage, so adding, removing, or replacing one never changes capsule_id. (Draft §3.1, §5.1)
Chosen: status: "confirmed" requires a response_digest over the response actually observed.
Rejected: a status label on its own. Without the bound response a producer could present an attempt as a completion; a verifier treats confirmed-without-digest as a failure. (Draft §5.3, §6 check 3)
Chosen: for inference_completion, digest the request body as received at the serving boundary and the completion body as returned, and record who vouches in effect_attestation.
Rejected: grading a host's report as a direct observation. host_served_observed means the producer saw the host's report, not the effect boundary; it grades equal to runtime_claimed, below gate_executed. (Draft §5.3)
Chosen: a hashed chain block with exactly one parent and a registered relation; an epoch change is an ordinary Capsule with relation: "epoch_opens".
Rejected: multiple parents or a new statement type for epoch boundaries. Citations outside the producer's own stream go in references instead. (Draft §5.2.2, §5.5.4, §5.5.5)
Chosen: one declared construction: format_version: "4" and canonicalization_id: "jcs", checked before any digest is computed.
Rejected: accepting other declarations. Any other format, or an absent, empty, unknown, or withdrawn "jcs-n" canonicalization, fails closed. (Draft §2)

3What it shows / what it does not

Shows

  • That the carried capsule_id matches the record: the verifier recomputes it and never trusts the carried value (§6 check 2). That the record is unchanged since sealing needs more: a verified Producer Envelope (§3.1) or a receipt over the original id.
  • A confirmed effect carries a digest of the response that was observed.
  • The assurance modes the bytes support: a verifier rederives assurance from the evidence present and reports overclaims (§6 check 7).
  • That effect_attestation is present wherever the effect status requires it (§6 check 5).
  • Which earlier Capsule this one follows, and where a configuration epoch starts.

Does not show

  • That the effect happened in the world. host_served_observed records a runtime's report of completion, not an observation of the effect boundary.
  • What the request or completion said. A digest can be checked only by someone who holds the body.
  • That every action was recorded. A Capsule on every verdict, refusals and blocks included, is a producer obligation (§5.5.3); a Capsule shows this action was recorded, not that none were left out.
  • That the stated effect_attestation is true. Who vouches is the producer's statement; the verifier checks only that it is present where required.
  • That the signing key was authorized for the operator. A valid envelope signature proves which key signed; authorization is the caller's policy (Draft §3.2).
  • Privacy for low-entropy values: a digest of a user or session identifier can be reversed by guessing, so identity must be excluded, not digested (Draft §14.1).

4Example

A conformance vector for the inference_completion effect, confirmed and attested host_served_observed. Its expected result is ok: true with no findings, and the recomputed capsule_id equals the carried one. The two digests are filler values (all 1s, all 2s); the vector tests the record, not real bodies. It carries no chain block, so its ledger mode is standalone.

{
  "action_id": "v05-inference",
  "action_type": "decide",
  "assurance": {
    "attestation_mode": "self_attested",
    "effect_mode": "confirmed",
    "ledger_mode": "standalone"
  },
  "canonicalization_id": "jcs",
  "capsule_id": "b1f609326c7ba59660b58f813f4fe2ef24e96f7210e3360d62a873b9df90c753",
  "developer": "agent@v1",
  "disposition": {
    "approver": "policy",
    "decision": "accept",
    "human_disposed": false,
    "verdict_class": "executed"
  },
  "effect": {
    "effect_attestation": "host_served_observed",
    "irreversibility_class": "two_way",
    "request_digest": "1111111111111111111111111111111111111111111111111111111111111111",
    "response_digest": "2222222222222222222222222222222222222222222222222222222222222222",
    "status": "confirmed",
    "type": "inference_completion"
  },
  "format_version": "4",
  "operator": "ACME-CO",
  "spec_version": "draft-mih-scitt-agent-action-capsule-05",
  "timestamp": "2026-09-26T00:00:00Z"
}
FieldTypeMeaning
action_idstringStable identifier of the action within one producer ledger.
action_typestring"decide": a disposition was required ("fyi" is informational).
assuranceobjectClaimed attestation, effect, and ledger modes; a verifier rederives each and reports overclaims.
canonicalization_idstringMust be exactly "jcs": plain RFC 8785 JCS for every digest.
capsule_id64 hexSHA-256 over JCS of the Capsule minus this field; recomputed, never trusted.
developerstringThe agent identity and version that acted.
dispositionobjectGate outcome: who disposed it, the human-in-the-loop flag, and the verdict class.
effect.typestringRegistered effect type; here an inference request whose effect is producing a completion.
effect.statusstring"confirmed": result observed and bound, so response_digest must be present.
effect.effect_attestationstringProducer-stated grade: the serving host's runtime reported the completion.
effect.irreversibility_classstringOrdered consequence class; "two_way" is the lowest.
effect.request_digest64 hexSHA-256 of JCS of the request body as received.
effect.response_digest64 hexSHA-256 of JCS of the completion body as returned.
format_versionstringSerialization suite; must be exactly "4".
operatorstringThe accountable tenant (a placeholder in this vector).
spec_versionstringThe profile text the Capsule conforms to; never selects an algorithm.
timestampstringRFC 3339 UTC time with "Z".

Source: action-state-group/agent-action-capsule:vectors/capsule/pos-v05-effect-inference-completion-host-served/input.json @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c

5Specs