Skip to content

Commit 74e6c1b

Browse files
committed
docs: add receipt chain v0.2 proof brick
1 parent 371bf84 commit 74e6c1b

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# RECEIPT_CHAIN_v0.2
2+
3+
Status: Design and test artefact only.
4+
5+
Scope: Narrow, path-local proof surface for hash-linked refusal receipts.
6+
7+
Claim boundary: This does not claim production readiness, compliance, tamper-proofing, or path-universal governance. It describes one bounded receipt-chain pattern for inspection and testing.
8+
9+
## Purpose
10+
11+
A refusal receipt should not only say that an action was refused.
12+
13+
It should also be possible to inspect whether that receipt belongs to a coherent receipt chain, whether the attempted payload and decision record are bound to the receipt, and whether the system recorded that no mutation was committed.
14+
15+
This artefact defines the smallest useful receipt-chain brick for `commit-gate-core`.
16+
17+
## Core invariant
18+
19+
No consequence-producing mutation is permitted unless the gate returns an admissible decision.
20+
21+
If the gate refuses, the refusal must be recorded before mutation and the receipt must bind:
22+
23+
1. the attempted payload,
24+
2. the decision record,
25+
3. the refusal reason,
26+
4. the previous receipt hash,
27+
5. the current receipt hash,
28+
6. evidence that mutation did not commit.
29+
30+
## Minimal receipt fields
31+
32+
```json
33+
{
34+
"receipt_id": "rcpt_0002",
35+
"previous_receipt_hash": "sha256:...",
36+
"payload_hash": "sha256:...",
37+
"decision_record_hash": "sha256:...",
38+
"decision": "REFUSE",
39+
"refusal_reason": "missing_valid_authority",
40+
"mutation_committed": false,
41+
"state_snapshot_hash": "sha256:...",
42+
"timestamp_utc": "2026-05-11T00:00:00Z",
43+
"receipt_hash": "sha256:...",
44+
"signature": null
45+
}
46+
```
47+
48+
## Hashing rule
49+
50+
`receipt_hash` is calculated over the canonical receipt body excluding `receipt_hash` and `signature`.
51+
52+
Canonicalisation must be deterministic.
53+
54+
The minimum acceptable test is:
55+
56+
1. Same receipt body produces the same hash.
57+
2. Any payload change changes `payload_hash`.
58+
3. Any decision record change changes `decision_record_hash`.
59+
4. Any receipt body change changes `receipt_hash`.
60+
5. Any broken `previous_receipt_hash` breaks chain verification.
61+
62+
## Verification procedure
63+
64+
A verifier should check:
65+
66+
1. `decision` is `REFUSE`.
67+
2. `mutation_committed` is `false`.
68+
3. `payload_hash` matches the attempted payload.
69+
4. `decision_record_hash` matches the DecisionRecord used by the gate.
70+
5. `previous_receipt_hash` matches the prior receipt in the chain.
71+
6. `receipt_hash` recomputes correctly from the canonical receipt body.
72+
7. Optional signature verifies against the declared signing key, if signatures are enabled.
73+
74+
## Signature status
75+
76+
Signature support is optional in v0.2.
77+
78+
If used, the signature must bind the canonical receipt body and declared key identity.
79+
80+
Key rotation must be logged as its own audit event before any new signing key is treated as active.
81+
82+
## What this does not prove
83+
84+
This artefact does not prove that:
85+
86+
- the system is production-ready,
87+
- the chain is tamper-proof,
88+
- every possible execution path is covered,
89+
- the implementation satisfies any compliance regime,
90+
- downstream systems cannot mutate by another route.
91+
92+
It only defines a small, inspectable receipt-chain pattern for refused actions.
93+
94+
## Clean line
95+
96+
Do not call it hardened.
97+
Make it harder to fool.

0 commit comments

Comments
 (0)