The record format
Seam ① Record. Build: one sealed record: digests, the effect, a nonce, a signature over its id. Conform to: draft-mih-scitt-agent-action-capsule-05.
Before you keep a book of records, decide what one record carries: digests of what went in and what came out, the effect it names and who vouches for it, a nonce the store draws itself, and the key that signs the record's identity.
1What it is
The record format is the choice of what one record commits to for one action: which facts go in as digests, which go in as plain values, and which never go in at all.
For a model exchange, the Agent Action Capsule Internet-Draft gives the effect type inference_completion, which binds the request and the completion by digest, and a COSE_Sign1 Producer Envelope that signs the record's identity under a key named in its kid.
Mesh-LLM's capsules plugin (release v0.1.4) is the worked example: it fills those fields from the host's exchange event, adds a store nonce, a join nonce and the serving facts, and leaves its hardware-evidence slot empty.
2Design choices
inference_completion, request_digest covers the request body as received at the serving boundary and response_digest the completion body as returned; status: "confirmed" requires the response digest.status: "dispatched" with no response digest rather than claim a completion. (Draft -05 §5.3; capsules crates/evidence-plugin/src/capsule_emit.rs)effect_attestation: host_served_observed when the plugin only saw the host's report of the exchange, gate_executed when the plugin admitted and served the request itself.host_served_observed grades equal to runtime_claimed, below gate_executed. (Draft -05 §5.3; both seal paths in capsule_emit.rs)capsule_id, protected header exactly alg EdDSA, content type application/agent-action-capsule-id and kid (the raw Ed25519 public key); unprotected header empty.store_nonce, 256 bits the store draws from a secure random source for that record alone, committed into capsule_id.rust/capsule-emit/src/capsule.rs @ 44ad8bd528b029c1abff1937f700423f94e1d6db, tag crates/capsule-emit-v0.0.6)references entry {type, digest_alg, digest} with citation_purpose: "ran_under". The cited record's grade covers only what that record measured.citation_purpose table and grade rule are printed under §5.5.6)model_name_digest is a hash of the model's name; weights_digest, the SHA-256 of the served file's bytes, is sealed only when the host reports it, with scope: "file". The serving host's name is left out unless the operator opts in.crates/evidence-plugin/src/producer/capsule.rs)3What it shows / what it does not
Shows
- That the holder of the key in
kidsigned thiscapsule_id, and, once the verifier recomputes the id, that the record's bytes are the ones signed. - To anyone who holds the request or completion body: whether it is the body this record committed to.
- That a
confirmedeffect carries a digest of the response that was observed, and which grade of voucher the producer states. - When the client supplied a nonce or the host forwarded one: which records are the two halves of one exchange, through the shared
client_nonce. The markerhost-served-no-noncejoins nothing. - With
store_noncein every record: the siblings in an inclusion proof cannot be confirmed by guessing a record's content.
Does not show
- What the request or the completion said.
- Who holds the key in the real world, or that it was authorized to sign for the operator (Draft -05 §3.2).
- That the named model ran.
model_name_digesthashes a name;weights_digestis the host's report of the file it opened. - Anything rooted in hardware. In v0.1.4 the
tee_attestationslot is always empty, andbinary_attestationis the plugin measuring its own executable (self- or OS-measured); on the host-served path that is not the runtime that served the model. - That every exchange was recorded: a record shows this exchange was recorded, not that none was left out.
- Privacy from
client_nonce: it is a join key both sides know, not a secret.
4Example
The format's own conformance vector for an inference_completion exchange, confirmed and attested host_served_observed. A verifier returns ok: true with no findings, and the recomputed capsule_id equals the carried one. The digests are filler values (all 1s, all 2s): the vector tests the record, not real bodies.
{
"action_id": "v05-inference",
"action_type": "decide",
"assurance": {
"attestation_mode": "self_attested",
"effect_mode": "confirmed",
"ledger_mode": "standalone"
},
"canonicalization_id": "jcs",
"capsule_id": "b1f609326c7ba59660b58f813f4fe2ef24e96f7210e3360d62a873b9df90c753",
…
"effect": {
"effect_attestation": "host_served_observed",
"irreversibility_class": "two_way",
"request_digest": "1111111111111111111111111111111111111111111111111111111111111111",
"response_digest": "2222222222222222222222222222222222222222222222222222222222222222",
"status": "confirmed",
"type": "inference_completion"
},
"format_version": "4",
…
"spec_version": "draft-mih-scitt-agent-action-capsule-05",
"timestamp": "2026-09-26T00:00:00Z"
}
| Field | Type | Meaning |
|---|---|---|
| capsule_id | 64 hex | SHA-256 over JCS of the record minus this field; recomputed, never trusted. |
| canonicalization_id | string | Must be exactly jcs; checked before any digest is computed. |
| format_version | string | Must be exactly 4. |
| effect.type | string | Registered effect type: an inference request whose effect is producing a completion. |
| effect.status | string | confirmed: result observed and bound, so response_digest must be present. |
| effect.effect_attestation | string | Who vouches: the serving host's runtime reported the completion. |
| effect.request_digest | 64 hex | SHA-256 of JCS of the request body as received at the serving boundary, floats first written as decimal strings. |
| effect.response_digest | 64 hex | SHA-256 of JCS of the completion body as returned. |
| assurance | object | Claimed modes; a verifier rederives each from the bytes and reports overclaims. |
| spec_version | string | The profile text the record conforms to; never selects an algorithm. |
Source: action-state-group/agent-action-capsule:vectors/capsule/pos-v05-effect-inference-completion-host-served/input.json @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c
The hardware citation, from the same repository's vector for ran_under: one references entry, identified by its digest alone (the digest is a filler value).
"references": [
{
"citation_purpose": "ran_under",
"digest": "5555555555555555555555555555555555555555555555555555555555555555",
"digest_alg": "SHA-256",
"type": "agent-action-capsule"
}
]
Source: action-state-group/agent-action-capsule:vectors/capsule/pos-v05-reference-ran-under/input.json @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c
What the Mesh-LLM producer adds, from a record the plugin sealed with its own fixture generator. This record comes from the path where the plugin admitted and served the request itself, so it reads gate_executed; its developer header (trimmed) names an earlier plugin version. For this page its capsule_id was recomputed and its envelope checked against key_id: both hold.
{
"spec_version": "draft-mih-scitt-agent-action-capsule-05",
"format_version": "4",
"capsule_id": "ddd8685c1b578b39c9163a5c748ac7148108663719227f7636b2a113a1dd34dc",
…
"model_attestation": {
"model_id": "m",
"provider": "mesh-llm",
"compute_attestation": {
"agent_input_digest": "6d139f1403cd84518768857efed6c375c0e3fe1af3f250cd3a5c59ea87a0323c",
"agent_output_digest": "a8461110d26a1ceb91765128a3f8a648e86238810f4bdf27a330deb8681f9d87",
…
"x-mesh-poc-v1": {
"client_nonce": "n",
"client_nonce_source": "client_supplied",
"model_name_digest": "62c66a7a5dd70c3146618063c344e531e6d4b59e379808443ce962b3abd63c5a",
"serving_provenance": {
…
"exchange_id": "e-1",
…
},
"role": "served",
…
"evidence_refs": {
…
"tee_attestation": {
"type": "tee_attestation",
"measurement_class": null,
"digest": null,
"context": "no TEE quote measured (…); recorded absent, never fabricated"
},
…
}
},
"store_nonce": "e372af496774c05c301d3185c83a4a98396b355ca87df2dfb07f8754def62dfe"
}
},
"effect": {
"status": "confirmed",
"type": "inference_completion",
"effect_attestation": "gate_executed",
"request_digest": "6d139f1403cd84518768857efed6c375c0e3fe1af3f250cd3a5c59ea87a0323c",
"response_digest": "a8461110d26a1ceb91765128a3f8a648e86238810f4bdf27a330deb8681f9d87"
},
…
"signature": "d284584ca301270378236170706c69636174696f6e2f6167656e742d616374696f6e2d63617073756c652d6964045820…",
"key_id": "9e4480104975505a70ec6fc913efff2884a93af380a657adf39babf91fbe1fe1"
}
| Field | Type | Meaning |
|---|---|---|
| agent_input_digest / agent_output_digest | 64 hex | The same request and completion digests, also kept in the producer's attestation block. |
| client_nonce | string | Join key between the two halves of one exchange. A fixture value here; on the host-observed path it is the nonce the host forwarded, else the marker host-served-no-nonce. |
| client_nonce_source | string | Where the nonce came from (client_supplied, host_forwarded_nonce, …). |
| model_name_digest | 64 hex | SHA-256 of the model's name string, not of its weights. |
| serving_provenance.exchange_id | string | The host's per-exchange id, to join this record to the host's own log. |
| role | string | served: this node served the exchange (requested on the other half). |
| evidence_refs.tee_attestation | object | The hardware-evidence slot: always empty in v0.1.4, with the reason stated. |
| store_nonce | 64 hex | 256 random bits the store drew for this record alone; inside the capsule_id preimage. |
| effect.effect_attestation | string | gate_executed: the plugin admitted and served this request itself. |
| signature | hex | The COSE_Sign1 Producer Envelope: tag 18, protected header alg -8 (EdDSA), the content type and kid; payload the 32 bytes of capsule_id; empty unprotected header. Outside the id preimage. |
| key_id | 64 hex | The signer's raw Ed25519 public key, the same bytes as the envelope's kid. Outside the id preimage. |
Source: Mesh-LLM/capsules:vectors/record_push_bundle_rust.json (member capsule) @ b4e24453f572b2d9fe8f2cefbd0f35a5eb54b0ad (tag v0.1.4)
5Status
| Item | Status | Evidence |
|---|---|---|
The format: inference_completion, request/response digests, Producer Envelope with kid, references with ran_under | live | Published Internet-Draft -05 and its conformance vectors: action-state-group/agent-action-capsule:spec/draft-mih-scitt-agent-action-capsule-05.md, vectors/capsule/, vectors/producer-envelope/ @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c |
One sealed, signed record per exchange half, with digests, store_nonce, signature and key_id | live | Mesh-LLM/capsules:crates/evidence-plugin/src/capsule_emit.rs @ b4e24453f572b2d9fe8f2cefbd0f35a5eb54b0ad; CHANGELOG.md 0.1.4: four paid exchanges between two nodes built from the release, “each node sealed its own half” |
| Request and response digests carried on the host's exchange event | built | request_digest, response_digest in Mesh-LLM/mesh-llm:mesh/crates/mesh-llm-host-runtime/src/plugin/openai_exchange.rs @ 60697c61755b7280c22d3ab9d9bcf5b663e8ae3b (main). First in mesh-llm release v0.77.0 (4ae1ace57dbbe28d0c3d10a05ee542328e8e64e7; set in crates/mesh-llm-host-runtime/src/network/openai/ingress.rs). Without them the plugin seals status: "dispatched" and no response digest. |
weights_digest of the served file | built | Sealed only when the host reports it: Mesh-LLM/capsules:crates/evidence-plugin/src/producer/capsule.rs @ b4e24453f572b2d9fe8f2cefbd0f35a5eb54b0ad |
Hardware evidence cited by digest (ran_under) | designed | Specified in draft -05 §5.5.5 (the citation_purpose table and grade rule are printed under §5.5.6) with vectors (vectors/capsule/pos-v05-reference-ran-under, vectors/interop/ran_under @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c). Not sealed by capsules v0.1.4: its plugin source (crates/) writes no ran_under entry, and its tee_attestation slot is always empty (producer/capsule.rs @ b4e24453f572b2d9fe8f2cefbd0f35a5eb54b0ad). |
6Specs
- Internet-Draft draft-mih-scitt-agent-action-capsule-05 — the record, its identity, the effect record, the Producer Envelope, and
referenceswithcitation_purpose. - Internet-Draft draft-mih-sokolov-scitt-payload-binding-05 — the typed digest reference
{type, digest_alg, digest}areferencesentry uses. - Internet-Draft draft-mih-agent-evidence-layer-00 — why every record carries a store-drawn random value (“What a Checkpoint Reveals”).
- RFC RFC 8785 — JSON Canonicalization Scheme: the bytes every digest and
capsule_idcovers. - RFC RFC 9052 — COSE: the
COSE_Sign1Producer Envelope. - RFC RFC 8949 — CBOR: the envelope's encoding (tag 18).
- RFC RFC 9943 — SCITT architecture: the separate registration statement for a
capsule_id. - RFC RFC 9942 — COSE Receipts: what that registration returns.
- Code action-state-group/agent-action-capsule — draft source and conformance vectors.
- Code Mesh-LLM/capsules v0.1.4 — the worked example's producer.
- Code action-state-group/capsule-emit — the sealing library the plugin links (crate 0.0.6, tag
crates/capsule-emit-v0.0.6@44ad8bd528b029c1abff1937f700423f94e1d6db).
7What you need before the next step
- A field list for each kind of record: what goes in as a digest, what goes in clear, and what never goes in (user and session identifiers, secrets).
- An effect type and an honest
effect_attestationvalue for each kind of action your host performs. - A signing key per producer (Ed25519), its public key as
kid, and a way for peers to learn it. - A store-drawn random value in every record, separate from any nonce a client or peer supplies.
- A JCS implementation that passes the format's canonical vectors, so your
capsule_idrecomputes anywhere. - A decision on where hardware evidence would be cited (
ran_under), even before you have any.