ReferenceSpec
Receipt Format
The chio.receipt.v1 record as chio-core-types defines it: every ChioReceipt field, the Decision enum, the kernel-written metadata blocks, id derivation, signing, and verification.
Source
This page normatively reflects spec/PROTOCOL.md in the chio repository, the sections Receipt Identity And DAG and 6.1 through 6.4. Status: Current bounded Chio release profile. Version 1.0, dated 2026-04-14. The document uses MUST, MUST NOT, and MAY as requirement words.
The wire form is the record schema spec/schemas/chio-wire/v1/receipt/record.schema.json ($id https://chio-protocol.dev/schemas/chio-wire/v1/receipt/record/v1). The companion schemas in the same directory, as the signed-artifact registry lists them:
admission-metadata.schema.json(chio.admission-receipt.v1): Chio Durable Admission Receipt Metadata.delivery-contract.schema.json(chio.delivery-contract.v1): Chio Delivery Contract Receipt Metadata.finding-delivery.schema.json(chio.finding.delivery.v1): Chio Finding Delivery Receipt Metadata.inclusion-proof.schema.json: Chio Receipt Merkle Inclusion Proof.lineage_statement.schema.json(chio.receipt_lineage_statement.v1): Chio receipt lineage statement.record.schema.json(chio.receipt.v1): Chio Receipt Record.
Behavior is checked against the crate crates/core/chio-core-types/src/receipt (body.rs, decision.rs, kinds.rs, metadata.rs, signing.rs, economics.rs, governance.rs, and lineage.rs), the kernel signing primitive in crates/kernel/chio-kernel-core/src/receipts.rs, the metadata assembly in crates/kernel/chio-kernel/src/receipt_support/receipt_metadata.rs, and the CLI flags in crates/products/chio-cli/src/cli/types/receipt.rs. Where the specification and a crate disagree, the crate is the behavior, cited by line.
Synopsis
// schema: chio.receipt.v1
pub struct ChioReceipt {
pub id: String,
pub timestamp: u64,
pub capability_id: String,
pub tool_server: String,
pub tool_name: String,
pub action: ToolCallAction,
pub decision: Option<Decision>, // omitted when None
pub receipt_kind: ReceiptKind,
pub boundary_class: BoundaryClass,
pub observation_outcome: Option<ObservationOutcome>, // omitted when None
pub tool_origin: ToolOrigin,
pub redaction_mode: RedactionMode,
pub actor_chain: Vec<ActorRef>, // omitted when empty
pub content_hash: String,
pub policy_hash: String,
pub evidence: Vec<GuardEvidence>, // omitted when empty
pub metadata: Option<serde_json::Value>, // omitted when None
pub trust_level: TrustLevel,
pub tenant_id: Option<String>, // omitted when None
pub bbs_projection_version: Option<String>, // omitted when None
pub kernel_key: PublicKey,
pub bbs_signature: Option<BbsReceiptSignature>, // omitted when None
pub algorithm: Option<SigningAlgorithm>, // omitted when None or ed25519
pub signature: Signature,
}The shape of ChioReceipt (body.rs lines 42 to 109) with the serde omission rule beside each field that has one, under the schema id chio.receipt.v1 (CHIO_RECEIPT_SCHEMA, line 38).
ChioReceipt
ChioReceipt is the signed record. The table reads each field, its type, and its doc comment from the struct; the last three columns say when serde drops the field from the wire, whether the field is part of ChioReceiptIdInput (the id preimage, lines 180 to 210), and whether it sits under the signature through ChioReceiptBody (lines 111 to 144).
The struct declares 24 fields. 20 of them form the id preimage, 21 sit under the signature, and 9 carry an omission rule.
| Field | Type | Doc | Omitted | In id preimage | Under signature |
|---|---|---|---|---|---|
id | String | Content-addressed receipt ID derived from the canonical receipt body. | never | no | yes |
timestamp | u64 | Unix timestamp (seconds) when the receipt was created. | never | yes | yes |
capability_id | String | ID of the capability token that was exercised (or presented). | never | yes | yes |
tool_server | String | Tool server that handled the invocation. | never | yes | yes |
tool_name | String | Tool that was invoked (or attempted). | never | yes | yes |
action | ToolCallAction | The action that was evaluated. | never | yes | yes |
decision | Option<Decision> | The Kernel's decision. Present only for mediated decisions. | when None | yes | yes |
receipt_kind | ReceiptKind | Signed receipt semantic kind. | never | yes | yes |
boundary_class | BoundaryClass | Signed runtime boundary class. | never | yes | yes |
observation_outcome | Option<ObservationOutcome> | Signed observation outcome for trace and advisory records. | when None | yes | yes |
tool_origin | ToolOrigin | Signed tool-origin classification. | never | yes | yes |
redaction_mode | RedactionMode | Signed redaction mode. | never | yes | yes |
actor_chain | Vec<ActorRef> | Signed actor attribution chain. | when empty | yes | yes |
content_hash | String | SHA-256 hash of the evaluated content for this receipt. | never | yes | yes |
policy_hash | String | SHA-256 hash of the policy that was applied. | never | yes | yes |
evidence | Vec<GuardEvidence> | Per-guard evidence collected during evaluation. | when empty | yes | yes |
metadata | Option<serde_json::Value> | Optional receipt metadata for stream/accounting details. | when None | yes | yes |
trust_level | TrustLevel | Strength of kernel mediation that produced this receipt. | never | yes | yes |
tenant_id | Option<String> | Multi-tenant receipt isolation: tenant identifier for multi-tenant deployments. `None` in single-tenant mode; derived from the authenticated session's enterprise identity context and MUST NOT be taken from caller-provided request fields (caller choice would defeat the isolation intent). Serialized only when set. | when None | yes | yes |
bbs_projection_version | Option<String> | BBS projection version bound into the receipt id when BBS material is present. | when None | yes | yes |
kernel_key | PublicKey | The Kernel's public key (for verification without out-of-band lookup). | never | yes | yes |
bbs_signature | Option<BbsReceiptSignature> | Optional BBS material for selective disclosure over this receipt. | when None | no | no |
algorithm | Option<SigningAlgorithm> | Signing algorithm used for [`ChioReceipt::signature`]. Informational only: verification dispatches off the self-describing encoding of the signature itself. | when None or ed25519 | no | no |
signature | Signature | Signature over canonical JSON of [`ChioReceiptSigningBody`]. | never | no | no |
Field behavior the doc comments do not state
idissha256_hex(canonical_json_bytes(ChioReceiptIdInput))(body.rslines 239 to 244). The preimage leaves outid,bbs_signature,algorithm, andsignature(lines 180 to 210). The schema fixes it to 64 lowercase hex characters (record schema line 30).decisionis required on amediated_decisionreceipt and refused on atrace_observationoradvisory_evaluationreceipt (metadata.rslines 94 to 131; record schema lines 178 to 215).receipt_kindfixestrust_level: signing refuses any other pairing (body.rslines 164 to 175). The pairings are in the semantic fields section.boundary_classnever carriescannot_seeon a signed receipt:validate_decisionrefuses it (metadata.rslines 82 to 87) and the schema enum omits it (record schema lines 67 to 75).content_hashis recomputed by the signer over the canonical content preimage before any signing work; the preimage is the RFC 8785 canonical JSON of a value output, the concatenated per-chunk digest preimage of a stream receipt, or the canonicalization ofnullfor an empty output (receipts.rslines 43 to 51 and 79 to 100).policy_hashhas no hex pattern in the schema, because some deployments embed a symbolic policy version id (record schema lines 115 to 119).metadatais schema-less at the top level (record schema lines 127 to 129). The keys the kernel reserves are in the kernel metadata blocks section.bbs_projection_versionis the constantchio.bbs-projection.receipt.v1(signing.rsline 21; record schema lines 144 to 148). It andbbs_signatureare present together or absent together: the schema declares them dependent (lines 174 to 177) andvalidate_bbs_receipt_bindingrefuses one without the other (signing.rslines 167 to 190).bbs_signature, when present, rides inChioReceiptSigningBody(signing.rslines 99 to 104), so the receipt signature covers it even though it sits outsideChioReceiptBody. Its fields and pinned constants areBbsReceiptSignature, lines 16 to 47.algorithmtakes the valuesed25519,p256,p384, orhybrid(crypto.rslines 88 to 100). serde drops it when it is unset or the default Ed25519 (lines 136 to 141). A hint that disagrees with the signature material fails verification withAlgorithmMismatch(body.rslines 517 to 526).kernel_keyandsignatureare hex strings whose prefix names the algorithm. The encodings are in the signing section.
Decision
Decision is an internally tagged enum: the tag field is verdict and the variant names serialize in snake_case (decision.rs lines 8 to 31; record schema lines 334 to 406).
| Wire value | Variant | Payload | Doc |
|---|---|---|---|
allow | Allow | none | The tool call was allowed and executed. |
deny | Deny | reason (String): Human-readable reason for the denial., guard (String): The guard or validation step that triggered the denial. | The tool call was denied. |
cancelled | Cancelled | reason (String): Human-readable reason for the cancellation. | The tool call was interrupted by explicit cancellation. |
incomplete | Incomplete | reason (String): Human-readable reason for the incomplete terminal state. | The tool call did not reach a complete terminal result. |
The specification preserves cancelled and incomplete outcomes as distinct verdicts instead of one error state (spec/PROTOCOL.md lines 1027 to 1035).
The deny receipt the quickstart captured records the refusal in decision.reason; its guard is kernel and the receipt carries no evidence entries, because capability-scope validation refused the call before the guard pipeline ran.
$ chio --receipt-db .chio/receipts.db --session-db "$(mktemp -d)/admission.db" check \
--policy ./policy.yaml --server hello --tool drop_tables --params '{}'verdict: DENY tool: drop_tables server: hello reason: requested tool drop_tables on server hello is not in capability scope receipt_id: 28b6e2576ca2ccbd031e769d8d2bd504317161115a600f27771a7f932307a284 policy: 69e943b96e9ce64d0264bb56bf8930e77bd4e68adf68fcf1395790dae03e6b55 source: 0d35135e8b19230b7aa42b0cc5982579450f5dc4a0280822e8b339e7786d2296 mode: preflight fixture: false
WARN chio_kernel::kernel::evaluation::async_evaluation_core message=capability rejected request_id=check-001 reason=requested tool drop_tables on server hello is not in capability scope
{ }, }, "delegation_depth": 0, "issuer_key": "3dbf7b1230475796d5c78cdcf441c84721d9e3c24362fbbfb4225e307d1b9fb4", "subject_key": "af2da8097f2c133affd89145302f029c7a5854e4e3a692a92b0cd20f84d07b37" }, "receipt_context": { "request_id": "check-001" } },}
crates/core/chio-core-types/src/receipt/body.rs:42-109at fe56570ToolCallAction
The action the kernel evaluated (decision.rs lines 33 to 40).
| Field | Type | Doc | Omitted |
|---|---|---|---|
parameters | serde_json::Value | The parameters that were passed to the tool (or attempted). | never |
parameter_hash | String | SHA-256 hash of the canonical JSON of `parameters`. | never |
ToolCallAction::from_parameters computes parameter_hash as the SHA-256 of the RFC 8785 canonical JSON of parameters, and verify_hash recomputes it (lines 42 to 58). The schema fixes the hash to 64 lowercase hex characters (record schema lines 327 to 331). The figures on this page recompute it from the captured receipts.
GuardEvidence
One entry per guard that evaluated the call (metadata.rs lines 184 to 194). The evidence array leaves the wire when it is empty, which is why the receipts the quickstart captured carry none.
| Field | Type | Doc | Omitted |
|---|---|---|---|
guard_name | String | Name of the guard (e.g. "ForbiddenPathGuard"). | never |
verdict | bool | Whether the guard passed (true) or denied (false). | never |
details | Option<String> | Optional details about the guard's decision. | when None |
Signed semantic fields
The enums in kinds.rs serialize in snake_case. Their wire values:
ReceiptKind
| Wire value | Variant | Meaning |
|---|---|---|
mediated_decision | MediatedDecision | The default. A kernel decision on a governed call (lines 40 to 59). |
trace_observation | TraceObservation | An observed call the kernel did not mediate. |
advisory_evaluation | AdvisoryEvaluation | An evaluation the caller may have ignored. |
BoundaryClass
| Wire value | Variant | Meaning |
|---|---|---|
prevent | Prevent | The default. The kernel could stop the call (lines 61 to 82). |
detect_only | DetectOnly | The kernel could observe but not stop the call. |
advisory_only | AdvisoryOnly | The kernel could advise only. |
cannot_see | CannotSee | Planning metadata. Refused on a signed receipt (metadata.rs lines 82 to 87; record schema line 74). |
ObservationOutcome
| Wire value | Variant | Meaning |
|---|---|---|
observed | Observed | Outcome of a non-mediated observation (lines 84 to 102). |
evaluated | Evaluated | The observation was evaluated. |
dropped | Dropped | The observation was dropped. |
ToolOrigin
| Wire value | Variant | Meaning |
|---|---|---|
caller_executed | CallerExecuted | The default. Where the tool effect executed relative to Chio (lines 104 to 123). |
host_executed_provider_reported | HostExecutedProviderReported | The host executed the tool and the provider reported it. |
host_executed_unmediated | HostExecutedUnmediated | The host executed the tool without mediation. |
RedactionMode
| Wire value | Variant | Meaning |
|---|---|---|
none | None | The default. Redaction applied to signed or exported receipt details (lines 125 to 144). |
summary | Summary | Details reduced to a summary. |
redacted | Redacted | Details redacted. |
TrustLevel
| Wire value | Variant | Meaning |
|---|---|---|
mediated | Mediated | The default. The kernel observed the call inline and authorized it through a separate trust boundary (lines 12 to 16). |
verified | Verified | Authorization ran inline in the agent process, for example a kernel embedded through FFI (lines 17 to 21). |
advisory | Advisory | The kernel evaluated but the caller may have proceeded regardless; shadow-mode and observability-only deployments (lines 22 to 25). |
Pairings signing enforces
validate_decision (metadata.rs lines 80 to 132) and validate_signable_semantics (body.rs lines 161 to 177) accept exactly these combinations; the record schema states the same rule as conditional requirements (lines 178 to 266).
| receipt_kind | boundary_class | trust_level | observation_outcome | decision |
|---|---|---|---|---|
mediated_decision | prevent | mediated | absent | present |
trace_observation | detect_only | verified | present | absent |
advisory_evaluation | advisory_only | advisory | present | absent |
is_authorized is true only for mediated_decision with prevent, no observation outcome, and an allow decision (metadata.rs lines 134 to 140); ChioReceipt::is_allowed adds trust_level == mediated (body.rs lines 545 to 550). result_label renders that case as Authorized; a trace record is Observed, an advisory record is Advisory, and any other mediated decision is Allowed, Denied, Cancelled, Incomplete, or, with no decision, Invalid (lines 142 to 158). Trace and advisory records are evidence, never authorization (spec/PROTOCOL.md lines 1022 to 1024).
Kernel metadata blocks
The kernel writes its typed blocks under reserved top-level metadata keys, merges them last, and rejects a pre-existing collision from caller or hook metadata, so a verifier can treat a block found under a reserved key as kernel-authored and covered by the receipt signature (spec/PROTOCOL.md lines 1074 to 1092; metadata.rs lines 196 to 203). The admission terminal enforces the rejection for delivery_contract, finding_delivery, and finding_recovery (crates/kernel/chio-kernel/src/kernel/admission_coordinator/terminal.rs lines 2049 to 2063, 2093 to 2103, and 2115 to 2125); the allow path merges attribution after caller metadata with last write wins on each nested key (crates/kernel/chio-kernel/src/kernel/responses/allow_responses.rs lines 84 to 93; receipt_metadata.rs lines 87 to 112).
The keys chio-core-types declares, read from the constants at the pin:
| Key | Pinned schema | Doc | Defined in |
|---|---|---|---|
admission_operation | chio.admission-receipt.v1 | crates/kernel/chio-kernel/src/admission_operation.rs | |
attribution | none | Universal receipt-side attribution for capability context. This metadata gives downstream analytics a deterministic local join path from a receipt to the capability subject and, when available, the matched grant within the capability scope. | metadata.rs |
budget_authority | none | Budget-authority lineage metadata block key for monetary receipts. | metadata.rs |
channel | none | Streamed-output channel accounting metadata block key. | metadata.rs |
chio_receipt_signing_nonce | none | The caller-supplied body.id, folded into the id input and therefore into the signed bytes before the content-addressed id is computed. | signing.rs |
delivery_contract | chio.delivery-contract.v1 | Delivery-contract evidence metadata block key (ADR-0018 item 7). | metadata.rs |
financial | none | Financial attribution and settlement metadata block key. | metadata.rs |
finding_delivery | chio.finding.delivery.v1 | Finding-delivery overlay metadata block key. | metadata.rs |
finding_recovery | chio.finding.recovery.v1 | Finding-recovery receipt metadata block key. | metadata.rs |
governed_transaction | none | Governed-transaction intent and approval metadata block key. | metadata.rs |
original_metadata | none | signing.rs |
Two reserved keys in the specification table are defined outside those constants. original_metadata is written by the signing path when a caller passed a non-object metadata value: the value moves under that key before the nonce is inserted (signing.rs line 107 and lines 127 to 135; spec/PROTOCOL.md line 1085). admission_operation is ADMISSION_RECEIPT_METADATA_KEY with schema ADMISSION_RECEIPT_SCHEMA in crates/kernel/chio-kernel/src/admission_operation.rs lines 29 to 30. Keys outside the reserved set, such as the receipt_context block the captured receipts carry, are not typed by chio-core-types.
admission_operation
A durable governed call carries an admission_operation block with schema chio.admission-receipt.v1. It binds the signed receipt to the admission operation and request namespace, the terminal projection and dispatch state, trusted time, the coordinator lease and store fence, the retained dispatch commit, and the optional tool outcome; unknown fields and unsupported schema versions fail closed (spec/PROTOCOL.md lines 1099 to 1106). The typed writer is AdmissionReceiptMetadataV1, declared deny_unknown_fields (crates/kernel/chio-kernel/src/admission_operation/projection.rs lines 52 to 71); the wire contract is admission-metadata.schema.json, which requires every field below (lines 7 to 24).
| Field | Schema shape |
|---|---|
schema | const chio.admission-receipt.v1 |
operation_id | 64-hex digest |
request_id | identifier, 1 to 512 characters |
request_namespace_digest | 64-hex digest |
request_binding_hash | 64-hex digest |
projected_operation_version | positive I-JSON integer |
projected_state | one of the admission states listed below |
projected_dispatch_state | not_committed, capture_pending, committed, finalizing, terminal, or not_applicable (lines 54 to 63) |
trusted_time_unix_ms | positive I-JSON integer |
coordinator_lease_id | identifier |
coordinator_lease_epoch | positive I-JSON integer |
store_fence | object { store_uuid, lease_id, owner_epoch } (lines 109 to 118) |
retained_dispatch_commit | null or { committed_version, coordinator_lease_id, coordinator_lease_epoch, store_fence, provider_attempt }, where provider_attempt is null or { operation_id, attempt_id, transport_id, transport_key_epoch } (lines 119 to 152) |
compensation_status | not_compensated, compensated_before_dispatch, or not_accepted_after_dispatch_commit (lines 74 to 80) |
tool_outcome_id | null or a 64-hex digest |
tool_outcome_version | null or a positive I-JSON integer |
projected_state takes the wire name of one of the 18 states of AdmissionOperationState, of which 7 are terminal (crates/kernel/chio-kernel/src/admission_operation.rs; schema lines 32 to 53). The allow receipt the quickstart captured carries this block with projected_state completed.
| Wire value | Variant | Pre-dispatch | Terminal |
|---|---|---|---|
prepared | Prepared | yes | no |
broker_attempt_registered | BrokerAttemptRegistered | yes | no |
approval_required | ApprovalRequired | yes | no |
budget_authorized | BudgetAuthorized | yes | no |
approval_reserved | ApprovalReserved | yes | no |
ready_to_dispatch | ReadyToDispatch | yes | no |
capture_pending | CapturePending | yes | no |
dispatch_committed | DispatchCommitted | no | no |
finalizing | Finalizing | no | no |
completed | Completed | no | yes |
compensated_before_dispatch | CompensatedBeforeDispatch | no | yes |
not_accepted_after_dispatch_commit | NotAcceptedAfterDispatchCommit | no | yes |
outcome_unknown_after_dispatch | OutcomeUnknownAfterDispatch | no | yes |
denied_after_delivery | DeniedAfterDelivery | no | yes |
mutation_ready | MutationReady | no | no |
mutation_submitted | MutationSubmitted | no | no |
economic_mutation_applied | EconomicMutationApplied | no | yes |
economic_mutation_not_applied | EconomicMutationNotApplied | no | yes |
delivery_contract
A digest-constrained governed call carries a delivery_contract block with schema chio.delivery-contract.v1: the expected_digest the grant fixed in advance, the observed_digest of the delivered output, both canonical lowercase 64-character hex SHA-256, and a result of matched or mismatched(spec/PROTOCOL.md lines 1108 to 1119; delivery-contract.schema.json lines 7 to 22). The block is present only when the exercised grant carried an output-digest constraint: matched accompanies an Allow and mismatched accompanies the persisted zero-charge Deny. It carries no signature of its own; the enclosing receipt authenticates it.
The typed struct is DeliveryContract, declared deny_unknown_fields (metadata.rs lines 243 to 258). On a mismatch observed_digest is a domain-separated commitment keyed by the expected digest, and the delivered output digest stays in privileged durable outcome evidence (lines 250 to 255). DeliveryContract::validate checks the pinned schema and both hex digests and does not re-derive result (lines 260 to 285); ChioReceipt::delivery_contract reads the block (body.rs lines 605 to 614).
finding_delivery
A reveal admitted under a provider-signed finding purchase marker carries a finding_delivery block beside the generic one, schema chio.finding.delivery.v1. It names the finding_id and listing_id the sale was admitted under, the kernel-proved transform_profile, the digest_check and media_type_check comparisons, the settlement_mode the admitted selector named, the canonical SHA-256 digests of the accepted-bid and venue-admission envelopes, and the authoritative reservation_id, purchase_intent_id, and authoritative_payment_operation_id. Every field derives from kernel-verified state, never from a caller-asserted value, and the block appears only when the purchase context arrived through verified signed records (spec/PROTOCOL.md lines 1121 to 1132; finding-delivery.schema.json lines 7 to 54).
The struct is FindingDelivery (metadata.rs lines 398 to 432). Its enums: transform_profile is identity (lines 294 to 301); digest_check is matched or mismatched; media_type_check is matched, mismatched, or not_evaluated (lines 303 to 313); settlement_mode is local_reversible_hold (lines 315 to 322). An optional status_proof carries the kernel-verified non-inclusion evidence for the delivered finding: feed_id, key_domain_nonce (the fixed constant 3318287169837494), map_epoch, status_epoch_artifact_sha256, proof_sha256, root_hash, and non_inclusion_checked_at (lines 324 to 347 of the metadata module, lines 73 to 94 of the schema file). A no-charge redelivery under a recovery grant carries finding_recovery instead, schema chio.finding.recovery.v1, with recovery_id, finding_id, original_capability_id, original_delivery_receipt_id, and purchase_key (lines 479 to 505).
budget_authority
A monetary receipt carries a budget_authority block with the budget hold lineage. The typed reader is FinancialBudgetAuthorityReceiptMetadata (economics.rs lines 140 to 154): guarantee_level, authority_profile, metering_profile, hold_id, optional budget_term, optional authority ({ authority_id, lease_id, lease_epoch }, lines 108 to 114), authorize (optional event_id and budget_commit_index, exposure_units, committed_cost_units_after, lines 116 to 125), and optional terminal (disposition, the same event fields, exposure_units, realized_spend_units, committed_cost_units_after, lines 127 to 138).
The kernel writes the block in two shapes. The store profile alone (guarantee_level, authority_profile, metering_profile) comes from budget_backend_receipt_metadata (crates/kernel/chio-kernel/src/kernel/validation.rs lines 909 to 925). A charge writes the full lineage through budget_execution_receipt_metadata, which also adds invocation_capture when a quota was captured and, when an execution nonce was presented, execution_nonce_id and mediated_spend.profile (lines 927 to 1048). The typed reader ignores keys it does not declare. ChioReceipt::financial_budget_authority_metadata reads the block (body.rs lines 597 to 603). The authoritative-spend checks over this block are on Authoritative Spend.
The other reserved keys
attribution:ReceiptAttributionMetadata(metadata.rslines 538 to 554):subject_keyandissuer_keyof the capability,delegation_depth, andgrant_indexwhen the request resolved to one grant. The kernel writes it on every allow and deny it signs from a capability (receipt_metadata.rslines 655 to 667). Both captured receipts carry it.chio_receipt_signing_nonce: bound bybind_receipt_signing_noncebefore the id is computed (signing.rslines 106 to 141). The signing section describes the step.financialandgoverned_transaction: the two sections that follow.channel:ChannelReceiptMetadataV1, camelCase anddeny_unknown_fields, withschemapinned tochio.channel.receipt-metadata.v1,channelId,openDigest,reservationId,reservationDigest(each 64 lowercase hex),sequence(a positive I-JSON integer), andsettlementModechannelized(economics.rslines 8 to 50).
Financial metadata
For an allow receipt under a monetary grant the kernel serializes FinancialReceiptMetadata under the financial key; a denial caused by budget exhaustion carries attempted_cost with the cost that would have been charged (economics.rs lines 52 to 58). ChioReceipt::financial_metadata reads it (body.rs lines 581 to 585).
| Field | Type | Doc (lines 78 to 105) |
|---|---|---|
grant_index | u32 | Index of the matching grant in the capability token scope. |
cost_charged | u64 | Cost charged for this invocation in currency minor units (cents for USD). |
currency | String | ISO 4217 currency code. |
budget_remaining | u64 | Remaining budget after this charge, in minor units. |
budget_total | u64 | Total budget for this grant, in minor units. |
delegation_depth | u32 | Depth of the delegation chain at the time of invocation. |
root_budget_holder | String | Identifier of the root budget holder in the delegation chain. |
payment_reference | Option<String> | Payment reference for external settlement systems. Omitted when None. |
settlement_status | SettlementStatus | Settlement status for this charge. |
cost_breakdown | Option<serde_json::Value> | Itemized cost breakdown for audit purposes. Omitted when None. |
oracle_evidence | Option<OracleConversionEvidence> | Oracle price evidence used for cross-currency conversion. Omitted when None. |
attempted_cost | Option<u64> | Cost that was attempted but denied; populated only on denial receipts. Omitted when None. |
The struct documents invariants the type system does not enforce and the kernel must uphold when it constructs the block (lines 60 to 75): cost_charged <= budget_total; budget_remaining reflects the post-charge balance at write time and may be a best-effort snapshot at read time under an HA split; and on a denial cost_charged is 0 and attempted_cost holds the rejected cost.
SettlementStatus
| Wire value | Variant | Meaning |
|---|---|---|
not_applicable | NotApplicable | No external settlement applies to this receipt, for example a pre-execution denial (economics.rs lines 156 to 168). |
pending | Pending | Settlement has been initiated but is not yet final. |
settled | Settled | The recorded charge is final for the current execution path. |
failed | Failed | Execution completed, but settlement failed or became invalid. |
OracleConversionEvidence
The cross-currency conversion evidence under financial.oracle_evidence (crates/core/chio-core-types/src/oracle.rs lines 9 to 31). The struct is deny_unknown_fields, its schema is the constant chio.oracle-conversion-evidence.v1 (line 7), and it carries no per-field doc comments: the names and types are the contract.
| Field | Type |
|---|---|
schema | String |
base | String |
quote | String |
authority | String |
rate_numerator | u64 |
rate_denominator | u64 |
source | String |
feed_address | String |
updated_at | u64 |
max_age_seconds | u64 |
cache_age_seconds | u64 |
converted_cost_units | u64 |
original_cost_units | u64 |
original_currency | String |
grant_currency | String |
oracle_public_key | Option<PublicKey>, omitted when None |
signature | Option<Signature>, omitted when None |
Governed transaction metadata
A request that carried a governed intent gets a governed_transaction block holding the intent identifiers and the approval, commerce, metering, runtime-assurance, call-chain, and autonomy evidence the kernel verified. The struct is GovernedTransactionReceiptMetadata (governance.rs lines 104 to 143); the kernel assembles it in governed_request_metadata (receipt_metadata.rs lines 480 to 604) and reads it back through ChioReceipt::governed_transaction_metadata (body.rs lines 587 to 590).
| Field | Type | Doc and shape |
|---|---|---|
intent_id | String | Governed transaction intent identifier. |
intent_hash | String | Canonical intent hash used for approval-token binding. |
purpose | String | Human or policy-readable purpose. |
server_id | String | Target tool server from the intent. |
tool_name | String | Target tool name from the intent. |
max_amount | Option<MonetaryAmount> | Explicit spend bound carried on the intent: { units, currency } in minor units (scope.rs lines 80 to 91). |
commerce | Option<GovernedCommerceReceiptMetadata> | Seller-scoped commerce approval evidence: seller, shared_payment_token_id, optional settlement_destination_ref (lines 51 to 60). |
metered_billing | Option<MeteredBillingReceiptMetadata> | camelCase: settlementMode, quote, optional maxBilledUnits, optional usageEvidence (evidenceKind, evidenceId, observedUnits, optional evidenceSha256) (lines 62 to 91). The kernel writes no usage evidence at signing time (receipt_metadata.rs line 530). |
approval | Option<GovernedApprovalReceiptMetadata> | token_id, approver_key (hex), optional approval_artifact_digest, approved (lines 18 to 29). A threshold-approval proposal fills it with the proposal id and the policy authority key (receipt_metadata.rs lines 500 to 510). |
runtime_assurance | Option<RuntimeAssuranceReceiptMetadata> | camelCase: schema, optional verifierFamily, tier (the tier accepted after any verifier trust-policy rebinding), verifier, evidenceSha256, optional workloadIdentity (lines 31 to 49; PROTOCOL.md lines 1165 to 1167). |
call_chain | Option<GovernedCallChainProvenance> | camelCase: evidenceClass, evidenceSources, optional upstreamProof, assertedContext, continuationTokenId, sessionAnchorId, receiptLineageStatementId, plus the flattened context chainId, parentRequestId, optional parentReceiptId, originSubject, delegatorSubject (capability/governance.rs lines 182 to 196 and 579 to 607). The flattened fields are the effective projection; a preserved caller assertion sits under assertedContext and is not verified truth (PROTOCOL.md lines 1169 to 1175). |
autonomy | Option<GovernedAutonomyReceiptMetadata> | camelCase: tier, optional delegationBondId (lines 93 to 102). |
economic_authorization | Option<EconomicAuthorizationReceiptMetadata> | The versioned economic envelope below (lines 138 to 142). |
economic_authorization
EconomicAuthorizationReceiptMetadata (economics.rs lines 303 to 330) keeps budget, meter, rail, and settlement truth in separate typed sub-blocks, serialized in snake_case. It is additive: the compatibility financial, commerce, metered_billing, approval, runtime_assurance, call_chain, and autonomy fields remain (spec/PROTOCOL.md lines 1133 to 1141). The kernel attaches it only when the request carried a governed intent and a verified payee binding, and it refuses to sign when the binding disagrees with the intent digest, the seller, the settlement destination, or the approval digest (receipt_metadata.rs lines 250 to 293 and 443 to 478).
| Field | Type | Shape |
|---|---|---|
version | EconomicAuthorizationReceiptMetadataVersion | Serialized v1 (lines 170 to 175). |
economic_intent_digest | Option<String> | Omitted when None. The kernel sets it from the verified payee binding (receipt_metadata.rs line 378). |
payee_binding_digest | Option<String> | Omitted when None. Set from the payee binding (line 379). |
pre_action_authority_digest | Option<String> | Omitted when None. Set from the payee binding (lines 380 to 382). |
credit_authority_digest | Option<String> | Omitted when None. The kernel leaves it unset (line 383). |
economic_mode | EconomicAuthorizationMode | budget_only, prepaid_fixed, hold_capture, metered_hold_capture, or external_dispatch (lines 177 to 186); chosen from the metered settlement mode, else from the presence of a payment reference (receipt_metadata.rs lines 357 to 373). |
payer | EconomicPayerReceiptMetadata | party_id, funding_source_ref, optional custody_provider, optional obligor_ref (lines 188 to 198). |
merchant | EconomicMerchantReceiptMetadata | merchant_id, optional merchant_of_record, optional order_ref (lines 200 to 209). |
payee | EconomicPayeeReceiptMetadata | beneficiary_id, settlement_destination_ref (lines 211 to 217). |
rail | EconomicRailReceiptMetadata | kind, asset, optional network, facilitator, contract_or_account_ref (lines 219 to 231). The kernel writes kind shared_payment_token (receipt_metadata.rs line 401). |
amount_bounds | EconomicAmountBoundsReceiptMetadata | approved_max, optional hold_amount, settlement_cap, each a MonetaryAmount (lines 233 to 241). |
pricing_basis | Option<EconomicPricingBasisReceiptMetadata> | Optional quote_hash, tariff_hash, quote_expiry (lines 243 to 253). Omitted when None. |
metering | Option<EconomicMeteringReceiptMetadata> | provider, meter_profile_hash, optional max_billable_units, optional billing_unit (lines 255 to 265). Omitted when None. |
liability_refs | Option<EconomicLiabilityReceiptMetadata> | Optional bond_id, policy_id, indemnity_ref, dispute_policy_ref (lines 289 to 301). Omitted when None; the kernel leaves it unset (receipt_metadata.rs line 425). |
budget | EconomicBudgetReceiptMetadata | grant_index, cost_charged, currency, budget_remaining, budget_total, delegation_depth, root_budget_holder, optional attempted_cost (lines 267 to 280), copied from the financial block (receipt_metadata.rs lines 426 to 435). |
settlement | EconomicSettlementReceiptMetadata | settlement_status (lines 282 to 287). |
Receipt id and signing
prepare_receipt_body_for_signing (body.rs lines 246 to 252) runs the first three steps in this order; the signing entry points (lines 290 to 314) run the rest.
- Validate the semantics.
validate_signable_semanticsrejects a body whose kind, boundary, observation outcome, decision, and trust level do not form one of the accepted pairings (lines 161 to 177). - Bind the signing nonce.
bind_receipt_signing_noncetakes the caller-suppliedbody.id, trimmed, and writes it tometadata.chio_receipt_signing_nonce. A non-objectmetadatavalue moves underoriginal_metadatafirst; an empty id skips the binding (signing.rslines 121 to 141). Becausemetadatais in the id preimage, the nonce is covered by the id and the signature. - Compute the id.
id = sha256_hex(canonical_json_bytes(ChioReceiptIdInput))over the nonce-bound body (lines 239 to 244). Canonical JSON is RFC 8785: keys sorted, no whitespace, deterministic number formatting. - Sign the signing body.
ChioReceiptSigningBodyis{ id, body: ChioReceiptIdInput, bbs_signature? }(signing.rslines 94 to 104). Its canonical JSON is signed with the kernel key:ChioReceipt::signwith an Ed25519 keypair leavesalgorithmunset, andsign_with_backendrecords the backend algorithm (lines 289 to 314). Both refuse akernel_keythat is not the signer key (lines 292 and 304). - Recompute content_hash first, in the kernel.
chio_kernel_core::receipts::sign_receipttakes the canonical content preimage with the body, recomputessha256_hexover it before the kernel-key check and before any signing work, and returnsContentHashMismatchwith the recomputed and claimed hashes when they differ (receipts.rslines 74 to 103).KernelKeyMismatchfollows whenbody.kernel_keyis not the backend key (lines 136 to 146).sign_receipt_with_handleconsumes a one-timeReceiptSigningHandleso one handle backs at most one signature (lines 226 to 238).sign_receipt_relaying_trusted_bodytrusts the caller hash and exists only for the FFI and WASM transport adapters that relay a body minted upstream (lines 105 to 139).
{ "name": "Chio" }, }, }, "compensation_status": "not_compensated", "coordinator_lease_epoch": 1, "coordinator_lease_id": "01a06cb0-a712-7440-b724-c4fe54913090", "operation_id": "a78bde4b5404092f9eecca27e3d5109dcda0a870befee69f32e9dcbd49e12343", "projected_dispatch_state": "terminal", "projected_operation_version": 8, "projected_state": "completed", "request_binding_hash": "91dc5c706136b424cd8c4bb77df99232e8f40028b2217d5d2a1c84adfd246e70", "request_id": "check-001", "request_namespace_digest": "b6fe626fa0256f31deefc202a2efaecb2defd6a4ba93a5237dbc5f063948a651", "retained_dispatch_commit": { "committed_version": 6, "coordinator_lease_epoch": 1, "coordinator_lease_id": "01a06cb0-a712-7440-b724-c4fe54913090", "provider_attempt": { "attempt_id": "attempt:a78bde4b5404092f9eecca27e3d5109dcda0a870befee69f32e9dcbd49e12343", "operation_id": "a78bde4b5404092f9eecca27e3d5109dcda0a870befee69f32e9dcbd49e12343", "transport_id": "kernel-tool-server:hello", "transport_key_epoch": 1 }, "store_fence": { "lease_id": "01a06cb0-a712-7440-b724-c4fe54913090", "owner_epoch": 1, "store_uuid": "01a06cb0-a62a-7ef0-a2bc-fee0de0a9828" } }, "schema": "chio.admission-receipt.v1", "store_fence": { "lease_id": "01a06cb0-a712-7440-b724-c4fe54913090", "owner_epoch": 1, "store_uuid": "01a06cb0-a62a-7ef0-a2bc-fee0de0a9828" }, "tool_outcome_id": "74a24dc524ae52adfe5594445a9fabb7f54d5c8d4580be5124ceab8ca7a87144", "tool_outcome_version": 2, "trusted_time_unix_ms": 1788529911968 }, "delegation_depth": 0, "grant_index": 0, "issuer_key": "e08d69a6a3bf74cf4971a7e0a1ff3f566129fad32ec5580c3342316859ecf436", "subject_key": "bb82465acb67f9413d39ef26ba3ceda6b5cd6413739e41a58b33edeb2909d8d8" }, "receipt_context": { "request_id": "check-001" } },}
crates/core/chio-core-types/src/receipt/body.rs:182-210crates/core/chio-core-types/src/receipt/body.rs:239-244at fe56570Key and signature encodings
kernel_key and signature are hex strings whose prefix selects the algorithm. Bare hex is Ed25519 (32-byte key, 64-byte signature); p256: and p384: select ECDSA with an uncompressed SEC1 point as the key and DER as the signature; hybrid: carries a classical part, ML-DSA-65 bytes, and the algorithm set (PublicKey::from_hex, crypto.rs lines 405 to 433; Signature::from_hex and to_hex, lines 757 to 808). The record schema fixes the wire patterns (lines 151 and 170):
kernel_key ^([0-9a-f]{64}|p256:04[0-9a-f]{128}|p384:04[0-9a-f]{192}|hybrid:[0-9a-f]{64}:[0-9a-f]{3904}:ed25519\+mldsa65|hybrid:p256:04[0-9a-f]{128}:[0-9a-f]{3904}:p256\+mldsa65|hybrid:p384:04[0-9a-f]{192}:[0-9a-f]{3904}:p384\+mldsa65)$
signature ^([0-9a-f]{128}|p256:([0-9a-f]{2})+|p384:([0-9a-f]{2})+|hybrid:[0-9a-f]{128}:[0-9a-f]{6618}:ed25519\+mldsa65|hybrid:p256:([0-9a-f]{2})+:[0-9a-f]{6618}:p256\+mldsa65|hybrid:p384:([0-9a-f]{2})+:[0-9a-f]{6618}:p384\+mldsa65)$Verification dispatches off the signature material, and verify_signature_with_floor applies a ReceiptCryptoFloor before the cryptographic check: allow_classical (the default) rejects hybrid receipts, pq_required rejects classical ones, and allow_hybrid accepts both (body.rs lines 496 to 530; crypto_floor.rs lines 11 to 23).
Verification
A receipt verifies from its own fields plus the set of kernel keys the verifier trusts. ChioReceipt::verify_signature (body.rs lines 478 to 494) runs, in order:
- Semantics.
validate_signable_semanticson the extracted body; a rejected pairing verifies as false. - BBS binding.
validate_bbs_receipt_bindingbetweenbbs_projection_versionandbbs_signature; a mismatch verifies as false. - Id.
chio_receipt_id(body)must equalid; a tampered identity-defining field verifies as false. - Signature.
kernel_key.verify_canonicalover the rebuiltChioReceiptSigningBody.
ToolCallAction::verify_hash checks parameter_hash separately (decision.rs lines 53 to 58). Neither step decides whether the signer is trusted; a verifier compares kernel_key against its own trust store.
TypeScript
verifyReceipt(receipt, trustedSigners) in @chio-protocol/sdk/invariants is synchronous and returns a ReceiptVerification with snake_case fields (sdks/typescript/chio-ts/src/invariants/receipt.ts lines 65 to 78 and 201 to 232). signature_valid requires the id to verify and the semantics to be signable (lines 211 to 214); signer_trusted is true only when kernel_key matches a supplied signer (lines 208 to 209), so ok is false for an empty trusted set (line 230); authorized adds the mediated-decision, prevent, and allow test (lines 206 to 216). A signature in an algorithm the SDK does not implement verifies as false instead of throwing (lines 5 to 20). verifyReceiptJson parses and verifies text with no trusted signers (lines 241 to 243).
import { parseReceiptJson, verifyReceipt } from "@chio-protocol/sdk/invariants";
// The kernel_key hex values a deployment trusts come from its own
// configuration. A receipt never vouches for its own signer.
const trustedSigners: string[] = [kernelKeyHex];
const receipt = parseReceiptJson(receiptJsonText);
const result = verifyReceipt(receipt, trustedSigners);
if (!result.ok) {
console.error("receipt rejected", result);
}
// result.signature_valid, result.parameter_hash_valid, result.receipt_id_valid,
// result.signer_trusted, result.authorized, and result.result
// ("Authorized", "Allowed", "Denied", "Cancelled", "Incomplete", "Observed",
// "Advisory", or "Invalid").Run it
chio evidence export writes a verifiable package from the receipt store, and chio evidence verify checks one offline (receipt.rs lines 160 to 200). The export takes the same tenant boundary as a listing: --tenant or --admin-all, and --require-proofs fails it when a selected receipt lacks checkpoint coverage.
$ chio --receipt-db .chio/receipts.db evidence export --admin-all --output ./evidence
$ ls evidenceREADME.txt capability-lineage.ndjson checkpoint-consistency-proofs.ndjson checkpoint-equivocations.ndjson checkpoint-publications.ndjson checkpoint-witnesses.ndjson checkpoints.ndjson child-receipts.ndjson inclusion-proofs.ndjson manifest.json query.json receipts.ndjson retention.json
Expected output
$ chio evidence verify --input ./evidenceevidence package verified tool_receipts: 2 child_receipts: 0 checkpoints: 0 checkpoint_publications: 0 checkpoint_witnesses: 0 checkpoint_consistency_proofs: 0 checkpoint_equivocations: 0 capability_lineage: 2 inclusion_proofs: 0 uncheckpointed_receipts: 2 authorized_receipts: 1 trace_observations: 0 advisory_evaluations: 0 verified_files: 12 child_receipt_scope: FullQueryWindow transparency_preview_logs: 0 publication_state: transparency_preview
When it refuses
One appended byte in receipts.ndjson moves the file hash the manifest committed to. The verify step exits 1 and names the file; a script branches on the exit code.
$ cp -R evidence evidence-tampered
$ printf '\n' >> evidence-tampered/receipts.ndjson
$ chio evidence verify --input ./evidence-tamperederror [urn:chio:error:attest:provenance-missing]: evidence package file hash mismatch for receipts.ndjson
context: {"domain":"attest","severity":"error","stability":"unstable","string_code":"CHIO-ATTEST-PROVENANCE-MISSING"}
suggested fix: Regenerate the evidence bundle and include provenance before submitting the operation.Receipt querying
chio receipt list reads the local store and prints one JSON receipt per line (receipt.rs lines 5 to 47). The HTTP surface with the same filters and cursor pagination is on Receipt Query API.
| Flag | Type | Doc |
|---|---|---|
--capability | string | Filter by capability ID. |
--tool-server | string | Filter by tool server ID. |
--tool-name | string | Filter by tool name. |
--outcome | string | Filter by decision outcome: allow, deny, cancelled, incomplete. |
--since | u64 | Receipts with timestamp >= this Unix seconds value. |
--until | u64 | Receipts with timestamp <= this Unix seconds value. |
--min-cost | u64 | Minimum cost in minor currency units, financial receipts only. Requires --cost-currency. |
--max-cost | u64 | Maximum cost in minor currency units, financial receipts only. Requires --cost-currency. |
--cost-currency | string | Currency for cost filters as a three-letter uppercase code. |
--limit | usize | Maximum number of receipts per page. Default 50. |
--cursor | u64 | Cursor for pagination: the seq value to start after. |
--tenant | string | Tenant read boundary for the listing. Conflicts with --admin-all. |
--admin-all | flag | Read across all tenants as an administrative operation. |
The read fails closed when neither --tenant nor --admin-all is supplied (lines 40 to 46), and clap refuses --min-cost or --max-cost without --cost-currency (lines 25 to 30). The quickstart lists its store with a jq projection, then selects the deny receipt as JSON:
$ chio --receipt-db .chio/receipts.db receipt list --admin-all \
| jq -r '[.decision.verdict, .tool_server, .tool_name, .id] | @tsv'allow hello hello_world 448440b65fa15559a364d24512cbe4f08631befe2c3d2ab471dad7204b8b69c8 deny hello drop_tables 28b6e2576ca2ccbd031e769d8d2bd504317161115a600f27771a7f932307a284
$ chio --receipt-db .chio/receipts.db receipt list --admin-all \
| jq 'select(.decision.verdict == "deny")'{
"id": "28b6e2576ca2ccbd031e769d8d2bd504317161115a600f27771a7f932307a284",
"timestamp": 1788529912,
"capability_id": "cap-01a06cb0-aae3-7ad3-8ba7-01350a3e01a0",
"tool_server": "hello",
"tool_name": "drop_tables",
"action": {
"parameters": {},
"parameter_hash": "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"
},
"decision": {
"verdict": "deny",
"reason": "requested tool drop_tables on server hello is not in capability scope",
"guard": "kernel"
},
"receipt_kind": "mediated_decision",
"boundary_class": "prevent",
"tool_origin": "caller_executed",
"redaction_mode": "none",
"content_hash": "74234e98afe7498fb5daf1f36ac2d78acc339464f950703b8c019892f982b90b",
"policy_hash": "69e943b96e9ce64d0264bb56bf8930e77bd4e68adf68fcf1395790dae03e6b55",
"metadata": {
"attribution": {
"delegation_depth": 0,
"issuer_key": "3dbf7b1230475796d5c78cdcf441c84721d9e3c24362fbbfb4225e307d1b9fb4",
"subject_key": "af2da8097f2c133affd89145302f029c7a5854e4e3a692a92b0cd20f84d07b37"
},
"chio_receipt_signing_nonce": "rcpt-01a06cb0-ab51-70d0-bcb3-72a8b78fe057",
"receipt_context": {
"request_id": "check-001"
}
},
"trust_level": "mediated",
"kernel_key": "3dbf7b1230475796d5c78cdcf441c84721d9e3c24362fbbfb4225e307d1b9fb4",
"signature": "e89f7a9cbe6c6b207cf5ac0c3e197a3957d62d2994217a7dcaeeeb9869abef1233680328432ee7a502a76238eb6ee9e72b19715e2458a3ef85aebfbed0df9202"
}chio receipt explain renders one receipt as a triage summary. It takes the receipt id, an optional --input-file holding one receipt or a bilateral co-sign document, --depth (default 8) and --fanout-limit (default 32) for the parent rendering, --inspect-bilateral for a structural trace of a bilateral envelope without signature verification, and the same tenant boundary (lines 78 to 122).
$ DENY=$(chio --receipt-db .chio/receipts.db receipt list --admin-all \
| jq -r 'select(.decision.verdict == "deny") | .id')
$ chio --receipt-db .chio/receipts.db receipt explain "$DENY" --admin-allreceipt: 28b6e2576ca2ccbd031e769d8d2bd504317161115a600f27771a7f932307a284 schema: chio.receipt.v1 identity: 28b6e2576ca2ccbd031e769d8d2bd504317161115a600f27771a7f932307a284 decision: deny reason: requested tool drop_tables on server hello is not in capability scope guard: kernel policy_hash: 69e943b96e9ce64d0264bb56bf8930e77bd4e68adf68fcf1395790dae03e6b55 scope_diff: requested scope vs granted scope is not embedded in this receipt parents: 0 repair_hint: inspect the guard and policy_hash, then mint or narrow a matching capability
Storage and checkpoints
The local receipt store keeps every signed receipt with a sequence number, and chio receipt checkpoint create signs the next batch as a kernel checkpoint with the kernel seed file and a batch bound (--max-batch, default 1024); status and verify report and check the chain, and chio receipt audit runs the claim-log projection validation plus the full chain check (receipt.rs lines 56 to 67 and 139 to 158).
KernelCheckpointBody (crates/kernel/chio-kernel/src/checkpoint.rs lines 98 to 137, deny_unknown_fields) carries schema, checkpoint_seq, batch_start_seq, batch_end_seq, tree_size, merkle_root, issued_at, kernel_key, and the optional previous_checkpoint_sha256 and chain_root (an RFC 6962 root over the checkpoint-chain leaves that consistency proofs verify against). KernelCheckpoint is that body plus an Ed25519 signature over its canonical JSON (lines 140 to 148).
ReceiptInclusionProof names the checkpoint_seq, receipt_seq, leaf_index, merkle_root, and a MerkleProof, and verifies the receipt canonical bytes against an expected root (lines 150 to 173). The wire form of the proof is inclusion-proof.schema.json: tree_size (at least 1), leaf_index (below tree_size), and audit_path, the ordered sibling hashes from the leaf up to the root, each 32 bytes as lowercase hex with a 0x prefix, with right-edge siblings carried upward without pairing omitted (lines 8 to 29). The evidence package the verification section exports carries the checkpoints and inclusion proofs as NDJSON files beside the receipts.
Receipt lineage
ChioReceipt carries no lineage field (body.rs lines 42 to 109). Lineage between receipts is a separate signed record, the ReceiptLineageStatement, with schema chio.receipt_lineage_statement.v1 (lineage.rs line 211). One statement links one parent receipt to one child receipt; multi-parent views are derived aggregates over these pairwise statements (lineage_statement.schema.json line 5). The body serializes in camelCase (lines 228 to 247); the signed record adds signature over the canonical JSON of the body, and verify_signature checks the pinned schema before the key (lines 319 to 399).
| Wire field | Rust field | Shape |
|---|---|---|
schema | schema | const chio.receipt_lineage_statement.v1 |
id | id | non-empty string |
parentReceiptId | parent_receipt_id | non-empty string |
childReceiptId | child_receipt_id | non-empty string |
parentRequestId | parent_request_id | RequestId |
childRequestId | child_request_id | RequestId |
parentSessionAnchor | parent_session_anchor | { sessionAnchorId, sessionAnchorHash } (schema lines 81 to 95) |
childSessionAnchor | child_session_anchor | the same shape |
relationKind | relation_kind | local_child, continued, or finding_memory_write_to_delivery (a governed memory write depending on a verified finding delivery receipt; lines 217 to 226) |
evidenceClass | evidence_class | asserted, observed, or verified; defaults to verified (lines 213 to 215) |
continuationTokenId | continuation_token_id | optional, omitted when None |
issuedAt | issued_at | u64, Unix seconds |
kernelKey | kernel_key | PublicKey |
signature | signature | Signature over the canonical JSON of the body |
The crate also defines the ordering types a DAG verifier uses: ReceiptHybridLogicalClock (wallSeconds, logical, kernelId; camelCase, deny_unknown_fields; lines 62 to 69), whose advance_from_parent takes the larger wall clock and increments the logical counter on a tie (lines 71 to 90); ReceiptDagParent (receiptId, chainId, dagOrdinal; lines 92 to 99); and parent_set_hash, the SHA-256 of the canonical JSON of the sorted, deduplicated parent receipt ids (lines 101 to 118). The record that carries chain_id, parent_set_hash, and dag_ordinal is the swarm join receipt (crates/kernel/chio-swarm-authority/src/types.rs lines 184 to 200), on Swarm Protocol.
Child request receipts
Nested flows such as sampling, elicitation, and resource reads under a parent call produce a ChildRequestReceipt (lineage.rs lines 24 to 43; spec/PROTOCOL.md lines 1060 to 1072). The signature covers the canonical JSON of ChildRequestReceiptBody, the record without algorithm and signature (lines 45 to 60 and 120 to 195). The child links to its parent through parent_request_id; a lineage statement is a separate record.
| Field | Type | Shape |
|---|---|---|
id | String | Child request receipt id. |
timestamp | u64 | Unix seconds. |
session_id | SessionId | The session the parent call ran in. |
parent_request_id | RequestId | The parent tool call request. |
request_id | RequestId | This child request. |
operation_kind | OperationKind | snake_case: tool_call, create_message, create_elicitation, list_roots, list_resources, read_resource, list_resource_templates, list_prompts, get_prompt, complete, list_capabilities, heartbeat (crates/core/chio-core-types/src/session/operation.rs lines 36 to 52). |
terminal_state | OperationTerminalState | Tagged by state: completed, cancelled with reason, or incomplete with reason (operation.rs lines 14 to 20). |
outcome_hash | String | Hash of the operation outcome. |
policy_hash | String | Hash of the policy applied. |
metadata | Option<serde_json::Value> | Omitted when None. |
kernel_key | PublicKey | The same encodings as on ChioReceipt. |
algorithm | Option<SigningAlgorithm> | Absent means Ed25519; omitted when unset or the default (line 40). |
signature | Signature | Over the canonical JSON of the body. |
Related
- Receipts: the concept and the receipt kinds.
- Quickstart: the scenario that captured the receipts on this page.
- Receipt Query API: the HTTP query, analytics, and report endpoints.
- Query audit receipts and Verify receipts offline: the task guides.
- Wire Protocol: the framing that carries receipts and the schema contract.
- Schemas and errors: the signed-artifact registry and the error codes.
- Delivery contract: the digest comparison behind the
delivery_contractblock. - Authoritative Spend: the checks over the
budget_authorityblock and the execution nonce. - Swarm Protocol: the join receipt that carries the DAG ordering fields.