Structure, verification and trust boundaries
A portable accountability object for consequential decisions.
Decision Receipts bind policy, evidence references, actors, outcomes, and verification metadata into a signed record that can be replayed and independently verified later.
This page is the public overview of the object. For exact field definitions, cardinality and wire formats, the Receipt Reference is the authority.
- Schema
- receipt_schema_version 1 · 2
- Verification
- Offline bundle
- Canonicalization
- meshqu-canonical/v0
- Anchoring
- Transparency-log compatible
- Hashing
- SHA-256
- Replay
- Policy snapshot
- Signing
- Ed25519
- Chains
- Supported
MeshQu is currently available for research, evaluation and design-partner deployments. Production availability and support commitments are agreed per engagement.
What this specifies
This page describes the shape of a Decision Receipt: the envelope fields, integrity model, verification claims, replay semantics, chain references, evidence boundaries and trust boundaries it carries — and the ones it deliberately does not.It is not the field contract and not API documentation. For exact field definitions, cardinality and wire formats, the Receipt Reference is the authority — where it and this page disagree, it wins.
Receipt anatomy
Inspect the object. This is not an illustration: it is the published demo receipt, serialised line by line from the signed fixture this site ships. Field names and values are the real ones. The data behind them is synthetic — a declined credit application, signed with a demo key.
The integrity hash binds the decision, the submitted context, the policy snapshot digest and the evidence manifest digest. The signature covers the integrity hash, the timestamp and the key identity — so a valid signature alone does not detect an edit; the integrity hash is what binds the content.There is no verification block, by design. A receipt does not carry its own verdict — what a verifier reports is §04.
- {
- "context": {
- "decision_type": "credit_application",
- "fields": {
- "applicant": "Demo Applicant 1",
- "product": "unsecured-personal-loan",
- "requested_amount": 25000,
- "currency": "GBP",
- "dti": 0.52,
- "months_employed": 14,
- "channel": "broker"
- }
- },
- "result": {
- "decision": "DENY",
- "violations": [
- {
- "rule_code": "DTI_MAX",
- "severity": "high",
- "reason_code": "VALUE_ABOVE_MAX",
- "reason": "Field 'dti' value 0.52 exceeds maximum 0.45",
- "field": "dti",
- "actual_value": 0.52,
- "expected_value": "<= 0.45",
- "is_shadow": false
- }
- ],
- "rules_evaluated": 3,
- "evaluation_time_ms": 3,
- "timestamp": "2026-07-15T09:24:11.000Z",
- "policy_snapshot_id": "018f9a1e-6d4c-7a3b-9f52-0c1d2e3f4a60",
- "evaluated_rules_hash": "2c03aa631f0ddf27900dee2ccfd480b3f8719bef4851a09c8337b0a66adaab79",
- "action": null,
- "transparency_anchor": null,
- "receipt_schema_version": 2,
- "policy_snapshot_digest": "5b32b0787167389c0a643a72521e906405f31dd3eb105073bc900125ea4ab736",
- "evidence_manifest_digest": null,
- "integrity_hash": "b20158d4684cd066acffea0cf5def73a6d364814ef074cc51d0909cb894ba8b6",
- "signature": "LI-2rncUT3-6xpWNLQftNZA67WziMMFfaHawHRsH07LohWwWRuvPI1HAO6aAkvXCZDMTCxHGorLeCeTsTKgABA",
- "signature_kid": "msk_demo_v2",
- "signature_algorithm": "ed25519"
- }
- }
Field definitions
Every row names a field that exists, qualified by where it lives on the wire. Cardinality is whether it is present on a signed v2 receipt; source is whether it is written directly or derived by a documented computation; and each row names what the field proves and — more usefully — what it does not. The receipt in §02 is unchained and unanchored, so the optional rows are legitimately absent from it.
| Field | Description | Cardinality | Source | Proves / does not prove |
|---|---|---|---|---|
| Decision context — context | ||||
| context.decision_type | Selects the policies that apply to this evaluation. | Required | Direct | Which policy family ran (not that it was the right one). |
| context.fields | The evaluation inputs, dot-notated. Hashed into the receipt as context_hash. | Required | Direct | What was submitted (not that any of it was true). |
| context.evidence | Reference-only list — kind, ref, hash. MeshQu holds the reference, never the payload. | Optional | Direct | That a reference was recorded (not the content behind it). |
| context.source_artifact | Single-artifact binding. Only hash enters the integrity hash; type, filename and size sit outside it. | Optional | Direct | That this artefact was the one evaluated (not what it says). |
| context.metadata | Request metadata — actor_id, correlation_id and similar. actor_id is bound through context_hash. | Optional | Direct | Attribution as the caller attested it (MeshQu does not validate identity). |
| Outcome — result | ||||
| result.decision | ALLOW, DENY, REVIEW or ALERT. There is no fifth value. | Required | Direct | The outcome recorded (not that it was correct or fair). |
| result.violations[] | Rule code, severity, reason code and reason for each breach. Empty array on a clean pass. | Required | Direct | Which rules fired and why (not that the rules were well designed). |
| result.rules_evaluated | How many rules ran. | Required | Direct | Coverage of the evaluation (not coverage of the risk). |
| result.rules_na, result.na_rules[] | Rules skipped because a when clause did not match. Absent when every active rule applied. | Optional | Direct | Which rules were out of scope (not that the scoping was right). |
| result.evaluation_time_ms | Evaluation duration. | Required | Direct | Operational cost. It proves nothing about the decision. |
| result.timestamp | ISO 8601 evaluation time. Part of the signed v2 envelope. | Required | Direct | When MeshQu evaluated (not when the underlying facts were true). |
| Policy binding — result | ||||
| result.policy_snapshot_id | UUID of the frozen snapshot that governed the evaluation. | Required | Direct | Which snapshot was named (an id alone cannot prove its content). |
| result.evaluated_rules_hash | SHA-256 over the active-rule projection — code, condition, severity, when. | Required | Derived | The rules exactly as evaluated (not that they were the intended rules). |
| result.policy_snapshot_digest | SHA-256 of the canonical snapshot. Required on v2. Binds snapshot content, not just its id — approval lineage rides transitively inside it. | Required | Derived | That the bundled snapshot is the one that ran (not that the policy was good). |
| Integrity & signature — result | ||||
| result.integrity_hash | SHA-256 over the canonical v2 payload: decision, violations, context hash, snapshot id and digests, evidence manifest digest, action, timestamp. Bare 64-char hex, no sha256: prefix. | Required | Derived | That the bound content has not been altered (not that it was correct). |
| result.signature | Ed25519 over the canonical v2 envelope, base64url. The algorithm is a separate field, never a prefix on this value. | Required | Direct | Issuance by the holder of the key. On its own it does not detect an edit — it covers the integrity hash, not the content. |
| result.signature_kid | Key that produced the signature, msk_v{N}. Bound inside the signed envelope on v2, so tampering with it fails the signature check. | Required | Direct | Which key to check against. The key material itself must arrive out-of-band. |
| result.signature_algorithm | ed25519. Anything else requires a manifest-version bump. | Required | Direct | The verification path (not the quality of key custody). |
| result.receipt_schema_version | 2 for the v2 envelope; absent or 1 for v1. Cross-version fallback is rejected in both directions. | Required | Direct | Which verification path applies. A v2 receipt must verify as v2. |
| Optional bindings — result | ||||
| result.evidence_manifest_digest | SHA-256 of the canonical evidence manifest, or null when the decision bound none. | Optional | Derived | That the manifest shipped in a bundle is the one bound (not that the evidence is true). |
| result.action | Downstream consequence: type and reference_id, both hashed. Its metadata is not hashed. | Optional | Direct | The consequence recorded at decision time (not that it was carried out). |
| result.transparency_anchor | Rekor anchor object — provider, entry_uuid, log_index, inclusion_proof, signed entry timestamp. Stamped after signing, so it is never part of the integrity hash, and never a bare hex string. | Optional | Direct | Binding to a public log entry. What that does and does not cover is §04. |
| Envelope & chain — alongside result | ||||
| id | UUID of the decision record. | Required | Direct | Identity (not correctness). |
| tenant_id | Owning tenant. Absent from the published demo fixture, which is unscoped synthetic data. | Required | Direct | Which deployment issued the receipt (not who is accountable for it). |
| actor | id, type, and optional role, authority and display_name. Stored beside the receipt; not part of the integrity hash. | Optional | Direct | The actor the caller attested (MeshQu does not verify who they are). |
| created_at | When the record was written — distinct from result.timestamp, which is when it was evaluated. | Required | Direct | Time of recording (not time of decision, and not time of truth). |
| chain_id, chain_step | Chain membership and position. Present only on receipts that belong to a workflow chain. | Optional | Direct | Continuity and order (not completeness — a chain seal covers that). |
| parent_decision_id | The receipt this one links back to. | Optional | Direct | Linkage (not that the parent decision was correct). |
context.decision_type
Selects the policies that apply to this evaluation.
Which policy family ran (not that it was the right one).
context.fields
The evaluation inputs, dot-notated. Hashed into the receipt as context_hash.
What was submitted (not that any of it was true).
context.evidence
Reference-only list — kind, ref, hash. MeshQu holds the reference, never the payload.
That a reference was recorded (not the content behind it).
context.source_artifact
Single-artifact binding. Only hash enters the integrity hash; type, filename and size sit outside it.
That this artefact was the one evaluated (not what it says).
context.metadata
Request metadata — actor_id, correlation_id and similar. actor_id is bound through context_hash.
Attribution as the caller attested it (MeshQu does not validate identity).
result.decision
ALLOW, DENY, REVIEW or ALERT. There is no fifth value.
The outcome recorded (not that it was correct or fair).
result.violations[]
Rule code, severity, reason code and reason for each breach. Empty array on a clean pass.
Which rules fired and why (not that the rules were well designed).
result.rules_evaluated
How many rules ran.
Coverage of the evaluation (not coverage of the risk).
result.rules_na, result.na_rules[]
Rules skipped because a when clause did not match. Absent when every active rule applied.
Which rules were out of scope (not that the scoping was right).
result.evaluation_time_ms
Evaluation duration.
Operational cost. It proves nothing about the decision.
result.timestamp
ISO 8601 evaluation time. Part of the signed v2 envelope.
When MeshQu evaluated (not when the underlying facts were true).
result.policy_snapshot_id
UUID of the frozen snapshot that governed the evaluation.
Which snapshot was named (an id alone cannot prove its content).
result.evaluated_rules_hash
SHA-256 over the active-rule projection — code, condition, severity, when.
The rules exactly as evaluated (not that they were the intended rules).
result.policy_snapshot_digest
SHA-256 of the canonical snapshot. Required on v2. Binds snapshot content, not just its id — approval lineage rides transitively inside it.
That the bundled snapshot is the one that ran (not that the policy was good).
result.integrity_hash
SHA-256 over the canonical v2 payload: decision, violations, context hash, snapshot id and digests, evidence manifest digest, action, timestamp. Bare 64-char hex, no sha256: prefix.
That the bound content has not been altered (not that it was correct).
result.signature
Ed25519 over the canonical v2 envelope, base64url. The algorithm is a separate field, never a prefix on this value.
Issuance by the holder of the key. On its own it does not detect an edit — it covers the integrity hash, not the content.
result.signature_kid
Key that produced the signature, msk_v{N}. Bound inside the signed envelope on v2, so tampering with it fails the signature check.
Which key to check against. The key material itself must arrive out-of-band.
result.signature_algorithm
ed25519. Anything else requires a manifest-version bump.
The verification path (not the quality of key custody).
result.receipt_schema_version
2 for the v2 envelope; absent or 1 for v1. Cross-version fallback is rejected in both directions.
Which verification path applies. A v2 receipt must verify as v2.
result.evidence_manifest_digest
SHA-256 of the canonical evidence manifest, or null when the decision bound none.
That the manifest shipped in a bundle is the one bound (not that the evidence is true).
result.action
Downstream consequence: type and reference_id, both hashed. Its metadata is not hashed.
The consequence recorded at decision time (not that it was carried out).
result.transparency_anchor
Rekor anchor object — provider, entry_uuid, log_index, inclusion_proof, signed entry timestamp. Stamped after signing, so it is never part of the integrity hash, and never a bare hex string.
Binding to a public log entry. What that does and does not cover is §04.
id
UUID of the decision record.
Identity (not correctness).
tenant_id
Owning tenant. Absent from the published demo fixture, which is unscoped synthetic data.
Which deployment issued the receipt (not who is accountable for it).
actor
id, type, and optional role, authority and display_name. Stored beside the receipt; not part of the integrity hash.
The actor the caller attested (MeshQu does not verify who they are).
created_at
When the record was written — distinct from result.timestamp, which is when it was evaluated.
Time of recording (not time of decision, and not time of truth).
chain_id, chain_step
Chain membership and position. Present only on receipts that belong to a workflow chain.
Continuity and order (not completeness — a chain seal covers that).
parent_decision_id
The receipt this one links back to.
Linkage (not that the parent decision was correct).
Verifier-computed claims are not fields. What a verifier reports over a bundle is §04.
Full field referenceVerification semantics
A verifier consumes a verification bundle and reports a status per sub-claim. A missing trust root yields not_applicable rather than a soft pass — verification fails closed.
| Sub-claim | What it checks | Status |
|---|---|---|
| bundle_manifest | Manifest digest recomputes; declared files are present and match recorded SHA-256 entries. | valid |
| integrity | integrity_hash recomputes from the canonical receipt body. | valid |
| signature | Ed25519 signature verifies against externally supplied trust root keyed by signature_kid. | valid |
| snapshot_replay | Bundled snapshot evaluates to the same outcome and rules hash as the receipt. | valid |
| evidence | evidence_manifest_digest equals SHA-256 of the bundled canonical evidence manifest. | valid |
| approval_lineage | Per-version approval-receipt digest, ratifier signature and policy_rules_hash all verify. Activates only when the bundled snapshot carries an approval_receipt_digest, and needs ratifier trust roots supplied out-of-band. | n/a |
| transparency | Rekor entry binds to this receipt — the DSSE subject digest equals integrity_hash — and the signed entry timestamp verifies offline against a pinned Rekor log key.That offline SET check against a pinned log key is the guarantee MeshQu stands behind: it needs no network call and survives MeshQu disappearing. Online entry-existence lookup is implemented, and the browser verifier does query Rekor live — but that confirms an entry is present, nothing more. Inclusion-proof verification against a co-signed log witness is not implemented, so read a valid result as “bound to a Rekor entry, checkable offline”, never as “independently and continuously witnessed”. | valid |
| chain_link | Linked receipts chain consistently — parent reference and link signatures verify. | valid |
| chain_seal | Sealed chain’s closing signature verifies and binds the recorded sequence. | n/a |
| canonicalization | Profile identifier matches and known canonicalization vectors round-trip identically. | valid |
bundle_manifestvalid
Manifest digest recomputes; declared files are present and match recorded SHA-256 entries.
integrityvalid
integrity_hash recomputes from the canonical receipt body.
signaturevalid
Ed25519 signature verifies against externally supplied trust root keyed by signature_kid.
snapshot_replayvalid
Bundled snapshot evaluates to the same outcome and rules hash as the receipt.
evidencevalid
evidence_manifest_digest equals SHA-256 of the bundled canonical evidence manifest.
approval_lineagen/a
Per-version approval-receipt digest, ratifier signature and policy_rules_hash all verify. Activates only when the bundled snapshot carries an approval_receipt_digest, and needs ratifier trust roots supplied out-of-band.
transparencyvalid
Rekor entry binds to this receipt — the DSSE subject digest equals integrity_hash — and the signed entry timestamp verifies offline against a pinned Rekor log key.
That offline SET check against a pinned log key is the guarantee MeshQu stands behind: it needs no network call and survives MeshQu disappearing. Online entry-existence lookup is implemented, and the browser verifier does query Rekor live — but that confirms an entry is present, nothing more. Inclusion-proof verification against a co-signed log witness is not implemented, so read a valid result as “bound to a Rekor entry, checkable offline”, never as “independently and continuously witnessed”.
chain_linkvalid
Linked receipts chain consistently — parent reference and link signatures verify.
chain_sealn/a
Sealed chain’s closing signature verifies and binds the recorded sequence.
canonicalizationvalid
Profile identifier matches and known canonicalization vectors round-trip identically.
- The receipt has not been altered.
- The issuer signature validates.
- The decision can be replayed against preserved context.
- Referenced evidence digests match the bundle manifest.
- Chain references and seals verify where present.
- Approval lineage verifies where trusted ratifier roots are supplied.
- The original business policy was correct.
- The underlying evidence was true.
- The decision was fair by itself.
- That all disclosure should be unrestricted.
- That MeshQu must be trusted as a live service.
Replay semantics
Same context, same policy snapshot, same outcome. Replay re-runs the preserved decision context against the preserved policy snapshot and checks that the outcome is consistent. Replay validates consistency against preserved context. It does not certify universal truth.
Load snapshot
Load policy snapshot referenced by policy_snapshot_digest.
Resolve evidence
Resolve references using the bundle manifest and verify digests.
Re-evaluate
Run the decision evaluator with the preserved context and snapshot.
Compare outcome
Check that the derived outcome matches the receipt.
Evidence model
Bound by digest. Held by the custodian. MeshQu binds evidence through digests, manifests, and references. The institution or custodian retains the underlying evidence. This supports trust without unrestricted disclosure.
Chains
A single receipt proves one decision. A chain proves a workflow. Receipts can reference each other to record an operational sequence — for example: screening → escalation → human review → override → final approval. Chains preserve operational continuity. A chain seal proves completeness and order where present.
- Step 01 · systemScreening
- Step 02 · systemEscalation
- Step 03 · humanHuman review
- Step 04 · humanOverride
- Step 05 · humanFinal approval
- Continuity
- Each receipt references its parent_decision_id, recording the operational sequence as it happened.
- Ordering
- chain_step is monotonically assigned per chain_id; gaps indicate evidence the verifier did not receive.
- Seal
- When a chain closes, a chain seal proves completeness and ordering. The seal is optional; absence reports as not_applicable.
Portability & survivability
A bundle outlives the systems that produced it. Verification bundles are designed to remain useful long after the operational systems that produced them have changed.
A verification bundle outlives the systems that produced it.
The bundle is self-describing. It carries the receipt, the canonical policy snapshot, the evidence manifest digest, the public keys it expects, and the canonicalization profile under which every digest was computed. Replay and verification do not require contacting MeshQu.
- The original vendor is gone.
- The model changed.
- The workflow platform was replaced.
- The internal dashboard is unavailable.
- MeshQu is not online.
Standards posture
Decision Receipts are designed to align with emerging practice in runtime accountability, provenance, and verification. The shape of the object — open schemas, public-key verification, transparency-log compatibility, evidence manifests — sits comfortably alongside Sigstore, DSSE, and in-toto style attestations without claiming conformance to any single specification.
- Open schemasReceipt and bundle types are published as versioned TypeScript definitions.
- Public-key verificationEd25519 over a canonical envelope. No shared secrets.
- Transparency-log compatibilityAnchors carry inclusion proofs and signed entry timestamps.
- Evidence and provenanceManifest digests bind to attested artifacts, not stored payloads.
Trust boundaries
The reference is bounded on purpose. These limits keep verification claims honest and prevent the object from being read as more than it is.
Evidence remains with custodians
MeshQu does not store evidence payloads by default. Receipts bind digests and references; the underlying artifacts stay in the institution’s systems.
Replay is consistency, not correctness
Replaying the preserved context against the preserved policy snapshot proves outcome consistency. It does not adjudicate whether the original policy was correct or fair.
Verification is authenticity and integrity
The signature, integrity hash, and digests prove that the receipt was issued under a known key and has not been altered. They do not adjudicate business judgement.
Disclosure is governed separately
Verifiability does not imply unrestricted transparency. Receipts can be disclosed selectively under whatever access controls the issuing organisation operates.
Actor identity is attested by the issuer
The actor field reflects what the issuing system asserts. External identity roots can strengthen this; absent those, actor binding is at the issuer’s level of trust.
Transparency anchors prove inclusion, not correctness
A transparency-log entry proves the receipt was witnessed at a particular time. It does not prove that the underlying decision was substantively correct.