Bundles and selective disclosure
A bundle packages a record with what makes it checkable and says exactly what it left out; selective disclosure withholds single fields without breaking the signature over the record.
1What it is
An Evidence Bundle is one JSON object that carries a root record, the records it cites, any revealed preimages, and log evidence, without changing any record inside it.
It states its completeness as three separate claims, graph closure, interval coverage and per-record membership, and a verifier reports each one on its own.
Selective disclosure lets a producer replace single eligible fields with salted digests before signing, so a holder can later reveal some fields to a verifier and keep others back while the signature still verifies.
2Design choices
closure_depth is either supplied or listed once in completeness.missing.checkpoint_unverified.effect.status or a response digest would make base checks impossible, so that is a structural failure. (sel-disc §4.4, §8.6)3What it shows / what it does not
Shows
- That every citation reached within the stated depth is supplied with a matching identity, or openly declared missing.
- That each supplied record sits at its claimed log position, by its own inclusion proof to the range root.
- That a revealed preimage hashes to the digest the record committed to (REVEALED-match), or does not (REVEALED-mismatch).
- That a revealed selective disclosure matches a digest under the signature; a mismatch is reported as
sd_commitment_mismatch. - How many constraint records are still concealed, so a reader knows the visible list may be incomplete.
Does not show
- Anything about records beyond
closure_depth. - Interval coverage or membership as independent results while the checkpoint is unverified.
- What a withheld field contains, or how many fields are concealed (decoys blur the count).
- A full verification when a REQUIRED field such as
operatorstays concealed:okis false, withsd_required_field_not_disclosed(sel-disc §8.5). - Anything from the
verificationmember, which is producer self-report. - A valid countersignature: the slot is reserved and every entry is surfaced as
unverifiedin this revision.
Two digest checks appear on this page. The bundle overlay compares the plain JSON digest of a revealed preimage (for example agent_input) with the digest the record carries. Selective disclosure compares the digest of a salted [salt, name, value] array with an entry in a signed _sd array.
4Example
A single-record bundle from the conformance vectors: one root record, depth 0, nothing missing, the agent_input preimage revealed in the overlay, and a one-leaf log certificate with an unsigned checkpoint. Recomputing the JSON digest of the full revealed agent_input gives the record's agent_input_digest. One member of that preimage is elided below.
"name": "pos-single-record-report",
…
"bundle": {
"bundle_version": "2",
"bundle_kind": "evidence-bundle/v2",
"root": "01011c5da0a88805492b97c4ddd8f50f63839757de8cbf4608bfb51098bfd6fe",
"records": [
{
…
"action_id": "report-single-record-1",
"action_type": "fyi",
…
"model_attestation": {
"compute_attestation": {
"agent_input_digest": "1fadc146114450fe2e22def4f2a57832d68e8ecfd3dca792d93fd68e505e2798"
}
},
"countersignatures": [],
"capsule_id": "01011c5da0a88805492b97c4ddd8f50f63839757de8cbf4608bfb51098bfd6fe"
}
],
"completeness": {
"closure_depth": 0,
"records_mode": "complete",
"payloads_mode": "selected",
"suppressed_fields": [],
"missing": []
},
"disclosures": {
"01011c5da0a88805492b97c4ddd8f50f63839757de8cbf4608bfb51098bfd6fe": {
"agent_input": {
…
"rows": [
{
"id": "r1",
"result": "pass"
},
{
"id": "r2",
"result": "withheld"
}
]
}
}
},
"completeness_certificate": {
"log_id": "vector-log",
"range_root": "3d8f59c9a33a55f63256b75bf2710e696d8f397fbc10766b95b0e803d0a4800e",
…
"memberships": {
"01011c5da0a88805492b97c4ddd8f50f63839757de8cbf4608bfb51098bfd6fe": {
"log_coordinates": {
"log_id": "vector-log",
"seq": 1,
"leaf_index": 0
},
…
"checkpoint": {
"root": "3d8f59c9a33a55f63256b75bf2710e696d8f397fbc10766b95b0e803d0a4800e",
"mmr_size": 1
}
},
"expected": {
"graph_closure": "pass",
"interval_coverage": "pass",
"interval_findings": [
"checkpoint_unverified"
],
"per_record_membership": "pass",
"membership_findings": [
"checkpoint_unverified"
]
}
| Field | Type | Meaning |
|---|---|---|
| root | hex | capsule_id of the record the bundle's claim starts from. |
| records | array | Unmodified records; here only the root. |
| completeness.closure_depth | integer | How many citation edges were followed; 0 means the root alone. |
| completeness.missing | array | Cited digests declared absent; empty, so records_mode is complete. |
| disclosures | object | Overlay of revealed preimages keyed by capsule_id; checked against the record's committed digest. |
| completeness_certificate | object | Log id, range root, and a per-record membership proof at leaf_index = seq - 1. |
| checkpoint | object | Root and MMR size; no signature here, hence checkpoint_unverified. |
| expected | object | The three completeness results, each reported on its own. |
Source: action-state-group/agent-action-capsule:vectors/bundle/report-single-record.json @ 2ef8aeb49e2334e24c404bd62d3fdb161770873c
5Specs
- Internet-Draft draft-mih-zhang-agent-disclosure-bundle-00 — the Evidence Bundle: closure, overlay, the three completeness claims, bundle digest.
- Internet-Draft draft-mih-scitt-agent-action-capsule-sel-disc-00 — per-field salted commitments, decoys, eligible fields, verifier checks.
- Internet-Draft draft-ietf-spice-sd-cwt-08 — SD-CWT, the CBOR sibling of the same selective-disclosure model.
- Internet-Draft draft-mih-scitt-agent-action-capsule-05 — the record, its capsule_id and Producer Envelope.
- Internet-Draft draft-mih-scitt-checkpointed-local-log-02 — related reading on checkpointed logs and MMR proofs; the bundle draft defines its own log-evidence shape and cites no revision of it.
- RFC RFC 8785 — JSON Canonicalization Scheme (JCS), hashed by both digest checks.
- RFC RFC 9052 — COSE; the Producer Envelope is a COSE_Sign1.
- Code action-state-group/agent-action-capsule — Evidence Bundle vectors, and
selective_disclosure.pyin the Python package.