Chio/Docs

EconomyThe Cognition Marketnew

Reveal & Settlement

Proposed one-call, digest-checked delivery and settlement for a purchased finding.

Planned delivery path

This page specifies the proposed Cognition Market reveal and settlement path. It does not describe a shipped read_finding flow.

Proposed Governed Call

The proposed design delivers a finding through a governed call the kernel mediates like any other, verified against a capability before dispatch. The purchase step uses the seller's AskResponse.token_offer, which carries a read_finding grant capped at one invocation and one price.

The grant expires after one invocation, preventing token replay. Also, ToolServerConnection::invoke carries only the tool name and its arguments, so the seller's server has no buyer field to check. The kernel verifies the capability before dispatch; the seller's server does not enforce buyer identity.


Proposed OutputDigestSha256 Constraint

A one-invocation cap does not bind the grant to the purchased bytes. A seller could return a different finding. The proposed capability-scope constraint variant is Constraint::OutputDigestSha256(String), minted by the seller into the read_finding grant inside AskResponse.token_offer, and carries the digest required for the delivered output.

The variant chosen here is deliberate: it is Chio's one exception to the rule against new variants on frozen wire enums. A rejected alternative, Constraint::Custom, is evaluated input-side only, so an old kernel that does not recognize a custom payload dispatches anyway with no digest gate at all: fail-open across version skew. OutputDigestSha256 carries no serde other fallback, so that same old kernel hard-rejects the token outright instead of silently admitting it: fail-closed, not fail-open, which is why this wire change earns the exception.


Two-Layer Enforcement

A constraint is only a value until something checks it. Chio checks OutputDigestSha256 twice: a correct verdict and a correct ledger are not the same guarantee.

Layer 1: Universal Soundness

The first check lives in build_allow_response_with_metadata, the single choke point every Allow arm in the kernel routes through, for any governed call, not only read_finding. Before letting an Allow stand, it compares the tool's actual output digest against the constraint's committed value: a mismatch routes the whole response to the deny builder instead, the same road a guard's explicit denial takes, and so does a Stream output. Because every Allow arm passes through this one function, no second path can forget to check.

Layer 2: Money-Correctness Before Irreversible Settlement

Layer 1 gets the verdict right, but does not by itself unwind money that already moved. The mediated call's finalizer only runs the post-invocation hook pipeline when a call carries no charge at all, so on either branch where a reveal actually costs something the digest still has to be checked before that money settles for good. Layer 2 places that check directly in the budgeted finalizer, before the specific step that makes settlement irreversible.

BranchGate runs beforeDigest matchesDigest mismatches
Charged (grant carries a per-call ceiling)reconcile_budget_chargeReconcile proceeds; charge standsReconcile skipped; charge reversed
MustPrepay, no ceiling (authorization on file, no further charge)settle_prepaid_authorization_without_chargeAuthorization settlesAuthorization released, not captured

On the charged branch this is a pre-reconcile clawback: the buyer never pays for content it did not get. On the no-ceiling MustPrepay branch there is only a payment authorization to resolve, not a further charge; releasing rather than capturing it means a prepaid hold that never sees a matching finding never converts into revenue for the seller.


The Reveal Envelope

Both layers above check a digest against the tool's actual output. That phrase needs one precise, normative definition, because content_hash is generic: for any value output, the kernel's content_hash is sha256_hex(canonical_json_bytes(value)), computed over the whole response value, never over some sub-field of it.

For read_finding specifically, the response value MUST be exactly one shape, the reveal envelope:

json
{
  "media_type": "text/x-diff",
  "payload_b64": "<base64 of raw payload bytes>"
}

Snake_case keys, canonical JSON key ordering, and nothing else in the object: that combination is what makes the hash deterministic. Because the envelope is what gets hashed, not the bytes it carries, a finding's committed digest is defined over the envelope, not the payload: Finding.payload_sha256 = sha256_hex(canonical_json_bytes(reveal_envelope)). The committed value is the digest of the canonical envelope, not the decoded payload bytes underneath it.

Corollaries

  • The envelope's media_type MUST equal the finding's payload_media_type; a mismatch is challengeable as evidence_invalid, never auto-applied.
  • The envelope deliberately excludes finding_id: including it would create a hash cycle, since finding_id is itself content-addressed over a body containing payload_sha256.
  • Identical payload bytes under the same media type legitimately share one envelope digest across two findings. That is agreement, not a collision.
  • A Stream output under this constraint denies fail-closed in v1: streamed digests are per-chunk and truncatable, so there is no single whole-value hash to check yet.

Digest Equality on the Delivery Receipt

The same equality is enforced once more, where evidence of delivery is produced. The tool contract MUST refuse to issue a delivery receipt whose content_hash differs from the finding's committed payload_sha256, the same rule Layer 1 and Layer 2 already enforce: never receipted, let alone paid for.


MustPrepay or ChioEscrow

The capability above still needs a rail to settle money on. A reveal picks between two, matched to size and to how much the buyer and seller already trust each other.

Small or high-frequency reveals settle MustPrepay: the kernel's own hold is the escrow, nothing else has to exist, and aborting the call refunds it directly, no separate contract to unwind. Large or cross-org reveals settle through ChioEscrow instead: beneficiary fixed to the seller, a deadline, and exactly two predeclared, price-free terminal states, release-on-proof or refund-after-deadline. Never a third.

PathCustodyTerminal states
MustPrepayThe kernel hold is the escrowCharge stands, or the hold is refunded on abort
ChioEscrowOn-chain contract; beneficiary = sellerRelease-on-proof, or refund-after-deadline (exactly two)

Release wires directly from the reveal receipt: the same digest-checked delivery receipt from the section above is what a merkle inclusion proof is computed over, and releaseWithProofDetailed on the escrow contract accepts that proof, prepared on the kernel side by the same batched prepare_merkle_release helper any other merkle release uses. Reveal settlement is not a special-cased escrow path; it is the ordinary merkle release, pointed at a reveal receipt instead of some other kind.

Kernel-attested reveal, not buyer possession

Everything above proves one specific thing: an Allow on a read_finding call means the kernel accepted a preimage whose content_hash equals the committed digest, kernel-attested reveal soundness, and it stops there. It does not prove the buyer's own process received or retained the bytes. A crash in the buyer process after the Allow, before it persists the payload, is a named and accepted residual: there is no kernel re-read path today, so the default mitigation runs on the seller's side instead, a re-serve keyed on the delivery receipt, not a second kernel-mediated reveal.

Next Steps

  • Finding Records · the chio.finding.v1 schema and the payload_sha256 content-addressing this page depends on
  • The Mediated Call · the finalizer sequence build_allow_response_with_metadata and reconcile_budget_charge sit inside
  • Settlement Rails · the full MeteredSettlementMode picture, must_prepay among the three settlement modes
  • On-Chain Settlement · ChioEscrow, merkle release, and prepare_merkle_release in depth
  • Pricing, Bonds & Audits · how the price a MustPrepay hold or ChioEscrow lock settles against is set