Skip to content

agent-action-capsule

CI Conformance

An open specification for recording — and independently verifying — what an AI agent actually did. The Agent Action Capsule is a SCITT statement profile: a digest-committed, signed record of one agent action carrying its verdict-level disposition (executed, blocked, denied, errored, timed out), the deterministic constraints that were evaluated, the effect that was committed together with a confirmed-effect binding that distinguishes a dispatched attempt from an observed result, and an honest human-in-the-loop flag.

Capsules are expressed as SCITT Signed Statements (COSE_Sign1) and made transparent by registration in a SCITT Transparency Service. A Capsule is recorded on every verdict, including refusals — a blocked or denied Capsule is the auditor-grade evidence that a gate worked.

Status / standards honesty. This is an individual IETF Internet-Draft, not a Working Group document, and not an RFC. The substrate it builds on is now published: the SCITT architecture is RFC 9943 and COSE Receipts are RFC 9942 (both June 2026). No RFC number is claimed for this profile; no WG adoption is claimed.

The draft

The authoritative version of the draft is the one on the Datatracker; the .md here is the editor's source from which it is built. Draft -03 is currently in preparation.

Quickstart — try the reference verifier

Verify a capsule in under a minute. Class-1 verification is reproducible from the capsule bytes alone — no keys, no network, no clock.

git clone https://github.com/action-state-group/agent-action-capsule
cd agent-action-capsule
pip install -e python            # or, once published: pip install agent-action-capsule

# a known-good conformance vector  ->  ok: True, findings: none
agent-action-capsule verify test-vectors/pos-executed-confirmed/input.json

# a tampered capsule               ->  ok: False, capsule_id_mismatch
agent-action-capsule verify test-vectors/neg-capsule-id-mismatch/input.json

The good capsule recomputes its content-address and passes; the tampered one is rejected because the recomputed capsule_id no longer matches the carried value. Every directory under test-vectors/ is one case — input.json is the capsule, expected.json is the verifier's expected result — so you can check the reference implementation against the frozen bytes the spec is conformance-tested on.

agent-action-capsule verify --help     # also: verify a store, or a full SCITT Signed Statement
agent-action-capsule anchor --help     # submit a capsule_id digest to a SCITT Transparency Service

For the SCITT receipt + anchor paths: pip install -e "python[transparent,anchor]". Full reference-library detail — the producer/emit side, --transparent Signed-Statement verification, and every option — is in python/README.md.

Repository layout

spec/            the Internet-Draft (.md source + built .xml/.txt), REGISTRY.md,
                 section-map.md, Makefile
python/          reference library (capsule parse + verify) -> PyPI agent-action-capsule
test-vectors/    conformance vectors (frozen bytes; the scitt-cose pattern)
LICENSE          BCP 78/79 for the specification; Revised BSD for code components
NOTICE           attribution + neutrality intent
CONTRIBUTING.md  IETF process (BCP 78/79), DCO, scope gates
SECURITY.md      private vulnerability reporting

Relationship to scitt-cose

This profile builds on top of the neutral substrate in action-state-group/scitt-cose: that package verifies anyone's SCITT Signed Statements and COSE Receipts and treats the statement payload as opaque bytes, with no profile baked in. The Agent Action Capsule is one example consumer that defines the statement/claim semantics carried inside that payload. Substrate verification (the COSE_Sign1 signature, registration, the Receipt's inclusion proof) is SCITT's and is verified by reference; the agent-domain checks defined in this draft are the part that is specific here.

Relationship to capsule-emit

This repository is the specification + reference verifier (and the typed producer carriers). The easiest way to produce conforming capsules is action-state-group/capsule-emit — a thin, neutral producer library (one emit() call, anchoring, a ledger CLI, framework adapters) built on top of this package. The dependency points one way — capsule-emit depends on agent-action-capsule, never the reverse — and the format defined here is open to any producer; capsule-emit is simply the convenient on-ramp. Both are neutral, donatable substrate.

Canonical Payload Binding (CPB)

Agent Action Capsule is the first payload profile registered under the Canonical Payload Binding (CPB) profile — a payload-neutral SCITT binding (canonicalize → derive an identifier → bind a receipt → cite externals). CPB and its provisional registries have a dedicated repository: action-state-group/scitt-payload-binding.

The CPB -00, as posted, references this repository as its source; the -01 revision updates that pointer to the dedicated repository.

Transparency-layer design — VDS-agnostic

The Agent Action Capsule is a statement-layer profile. A capsule is a SCITT Signed Statement (COSE_Sign1 over a JSON payload); it makes no claim about how it is registered or which Verifiable Data Structure (VDS) algorithm the Transparency Service uses.

┌──────────────────────────────────────────────────┐
│  Signed Statement  (COSE_Sign1, our format)      │  ← what we define/emit
│   protected: { alg, content_type, CWT_Claims }   │
│   payload:   application/agent-action-capsule+json│
└──────────────────────────────────────────────────┘
         │  (submitted to a Transparency Service)
         ▼
┌──────────────────────────────────────────────────┐
│  SCITT Receipt  (COSE_Sign1, TS-minted)          │  ← what the TS adds
│   protected: { alg, vds=1 (RFC9162_SHA256) }     │
│   unprotected: { vdp: { inclusion_proof } }      │
│   payload:   Merkle root (detached)              │
└──────────────────────────────────────────────────┘
         │
         ▼
  Transparent Statement = Signed Statement + Receipt(s)

emit() in capsule-emit produces the Signed Statement. It has no opinion on VDS. The VDS (vds header in the Receipt) is the Transparency Service's choice.

RFC9162_SHA256 (vds=1) is the current default — the only VDS registered under draft-ietf-cose-merkle-tree-proofs today, and the profile implemented in scitt-cose (both build_receipt and verify_receipt).

CCF (Microsoft Confidential Consortium Framework) — tested against scitt-ccf-ledger v7.0.6 (2026-06-26): CCF emits receipts with vds=2 (ccf.v1 Merkle format), not vds=1 (RFC9162_SHA256). Our scitt-cose verify_receipt currently implements vds=1 only; vds=2 support is in progress and tracked in scitt-cose. Once landed, verify_receipt will accept real CCF receipts without any change to the capsule or Signed Statement format. See scitt-cose/tests/test_ccf_interop.py for the integration test.

Adding support for a new VDS is a new if vds == N branch in scitt-cose's verifier — the capsule format does not change.

What we are NOT saying:

  • We are not claiming the capsule format requires CCF.
  • We are not claiming CCF's VDS is the same as ours — CCF 7.0.6 uses vds=2 (its own Merkle format); our verifier uses vds=1 (RFC9162_SHA256). Different proof formats, same statement layer — the expected outcome during standardisation.
  • We are not claiming capsule-anchor's local TS provides the same trust guarantees as CCF. The SCITT protocol is the same; the trust model is not.

Interop & independent implementations

INTEROP.md is the registry of record for cross-implementation runs and third-party verification events as of IETF 126 (Vienna, Jul 2026). It covers roughly a dozen rows across two tiers:

Independent implementations (different organization, independently written codebase): EMILIA Protocol (Schrock), Tyche Institute (Sokolov), Microsoft/CCF (Chamayou), Songbo Bu, NANDA/MIT, GlyphZero, APS, COSA, GAR, and VeritasChain — each row links a public artifact (PR, release tag, or datatracker entry) as its evidence. "Ran and verified" means the result is on the public record; a link to a digest or PR is the evidence, not a name.

Same-team ports (ASG's own dual runtime — Python reference library plus Go clean-room verifier): both track the same frozen conformance vectors and are cross-checked in CI; they are listed separately in scitt-cose rather than claimed as third-party implementations.

The INTEROP.md table includes additional rows marked agreed — scheduled (runs coordinated, artifact exchange pending) and one row marked HOLD (PermitReceipt — wording fixed by agreement with the owner). Scheduled and HOLD rows are not counted as completed runs.

Building the draft

# one-time toolchain
gem install kramdown-rfc
python3 -m venv ~/.venvs/x2r && ~/.venvs/x2r/bin/pip install xml2rfc

# build (from spec/)
cd spec && make            # md -> v2 xml -> v3 xml -> txt
make idnits                # expected residuals only (RFC 8785 downref, BCP14, UTF-8)

kramdown-rfc emits RFCXML v2; the committed .xml is RFCXML v3 (RFC 7991). The Makefile converts with xml2rfc --v2v3 — see spec/Makefile.

Provenance, neutrality & governance

This specification was developed by Action State Group, Inc. and is published as an open specification, intended for contribution to an appropriate standards body as the ecosystem matures. The content here is standard-only: the draft, its registry of record, a reference implementation, and conformance vectors — nothing product-specific or tenant-specific.

The specification text is an IETF contribution under BCP 78 / BCP 79; the intended venue for discussion is the IETF SCITT Working Group (scitt@ietf.org). The change controller for the interim registry is Action State Group, Inc., transferring to the IETF on RFC publication. No primacy is claimed; the value is an interoperable, independently-verifiable record format and a clean transfer path to a neutral home (Working Group adoption or a foundation donation) whenever that moment arrives.

License

See LICENSE: the specification text is governed by BCP 78 and the IETF Trust's Legal Provisions; code and reference-implementation material are under the Revised BSD License. Contributions follow CONTRIBUTING.md (DCO sign-off; no CLA).

Patent posture: All six provisional patent applications related to this specification were expressly abandoned on July 6, 2026. No license is required. See agentactioncapsule.org/ip for details.

About

Agent Action Capsule — an open SCITT statement profile for recording and verifying what an AI agent did (draft-mih-scitt-agent-action-capsule)

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages