|
| 1 | +{ |
| 2 | + "artefact": "refusal_receipt_chain_v0.2", |
| 3 | + "status": "example_test_fixture_only", |
| 4 | + "claim_boundary": "Path-local replay fixture for refusal receipt-chain inspection. Does not claim production readiness, compliance, tamper-proofing, signatures, or path-universal governance.", |
| 5 | + "canonicalisation_rule": "Hash the deterministic JSON body with keys sorted and compact separators. receipt_hash excludes receipt_hash and signature.", |
| 6 | + "hash_algorithm": "sha256", |
| 7 | + "genesis_previous_receipt_hash": "sha256:0000000000000000000000000000000000000000000000000000000000000000", |
| 8 | + "attempted_payloads": { |
| 9 | + "payload_0001": { |
| 10 | + "action_type": "send_external_email", |
| 11 | + "scope": "vendor_contact", |
| 12 | + "target": "external.example", |
| 13 | + "body": "Request account access change." |
| 14 | + }, |
| 15 | + "payload_0002": { |
| 16 | + "action_type": "update_access_record", |
| 17 | + "scope": "user_access", |
| 18 | + "target": "user:example", |
| 19 | + "requested_role": "admin" |
| 20 | + } |
| 21 | + }, |
| 22 | + "decision_records": { |
| 23 | + "dec_0001": { |
| 24 | + "decision_id": "dec_0001", |
| 25 | + "gate": "CommitGate", |
| 26 | + "decision": "REFUSE", |
| 27 | + "reason": "missing_valid_authority", |
| 28 | + "authority_token": null, |
| 29 | + "scope": "vendor_contact", |
| 30 | + "nonce": "nonce_0001", |
| 31 | + "expires_at_utc": null |
| 32 | + }, |
| 33 | + "dec_0002": { |
| 34 | + "decision_id": "dec_0002", |
| 35 | + "gate": "CommitGate", |
| 36 | + "decision": "REFUSE", |
| 37 | + "reason": "scope_not_authorised", |
| 38 | + "authority_token": "auth_demo_expired", |
| 39 | + "scope": "user_access", |
| 40 | + "nonce": "nonce_0002", |
| 41 | + "expires_at_utc": "2026-05-11T23:59:00Z" |
| 42 | + } |
| 43 | + }, |
| 44 | + "post_refusal_state_snapshots": { |
| 45 | + "state_after_rcpt_0001": { |
| 46 | + "path": "send_external_email", |
| 47 | + "external_email_sent": false, |
| 48 | + "access_change_created": false, |
| 49 | + "notification_emitted": false |
| 50 | + }, |
| 51 | + "state_after_rcpt_0002": { |
| 52 | + "path": "update_access_record", |
| 53 | + "access_record_updated": false, |
| 54 | + "role_change_committed": false, |
| 55 | + "notification_emitted": false |
| 56 | + } |
| 57 | + }, |
| 58 | + "valid_chain": [ |
| 59 | + { |
| 60 | + "receipt_id": "rcpt_0001", |
| 61 | + "previous_receipt_hash": "sha256:0000000000000000000000000000000000000000000000000000000000000000", |
| 62 | + "payload_hash": "sha256:a7083e23969091ddaa0376b4f1ce990cf8399ff18340cfb74454f1d705aa249e", |
| 63 | + "decision_record_hash": "sha256:67df1b9f792a108eb3e4f9aa4a67f559cdd782c7ff5c9bf519bec061f8ba217d", |
| 64 | + "decision": "REFUSE", |
| 65 | + "refusal_reason": "missing_valid_authority", |
| 66 | + "mutation_committed": false, |
| 67 | + "state_snapshot_hash": "sha256:a9834adf5a78bbef89bc2df723fcfaa3f4a71d0da728fd855ac779630400aa2b", |
| 68 | + "timestamp_utc": "2026-05-12T09:00:00Z", |
| 69 | + "receipt_hash": "sha256:b2a2c455a2ab4def9c3028992dfc2844560fee910755b56cd145f22c8deba9fb", |
| 70 | + "signature": null |
| 71 | + }, |
| 72 | + { |
| 73 | + "receipt_id": "rcpt_0002", |
| 74 | + "previous_receipt_hash": "sha256:b2a2c455a2ab4def9c3028992dfc2844560fee910755b56cd145f22c8deba9fb", |
| 75 | + "payload_hash": "sha256:b91f0faecbc74b7682b0cd3b7a5813cdedc63826f16ff0d3db36d0451c4c0cb4", |
| 76 | + "decision_record_hash": "sha256:4339709b0ad790fb723928024b70c532f2354b65577a795162260e5a28fee0c9", |
| 77 | + "decision": "REFUSE", |
| 78 | + "refusal_reason": "scope_not_authorised", |
| 79 | + "mutation_committed": false, |
| 80 | + "state_snapshot_hash": "sha256:562fd64219ffb41d8bb2cb7c828af075e80124c004823549898f9459517292a5", |
| 81 | + "timestamp_utc": "2026-05-12T09:01:00Z", |
| 82 | + "receipt_hash": "sha256:ac36b739bf676d8c9a20ca3c7199cc228d15f9f88b04ab1a61fb1da35dacd520", |
| 83 | + "signature": null |
| 84 | + } |
| 85 | + ], |
| 86 | + "broken_chain_examples": [ |
| 87 | + { |
| 88 | + "case": "broken_previous_receipt_hash", |
| 89 | + "expected_result": "FAIL", |
| 90 | + "reason": "previous_receipt_hash does not match the prior receipt_hash", |
| 91 | + "receipt": { |
| 92 | + "receipt_id": "rcpt_0002_broken_previous_hash", |
| 93 | + "previous_receipt_hash": "sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", |
| 94 | + "payload_hash": "sha256:b91f0faecbc74b7682b0cd3b7a5813cdedc63826f16ff0d3db36d0451c4c0cb4", |
| 95 | + "decision_record_hash": "sha256:4339709b0ad790fb723928024b70c532f2354b65577a795162260e5a28fee0c9", |
| 96 | + "decision": "REFUSE", |
| 97 | + "refusal_reason": "scope_not_authorised", |
| 98 | + "mutation_committed": false, |
| 99 | + "state_snapshot_hash": "sha256:562fd64219ffb41d8bb2cb7c828af075e80124c004823549898f9459517292a5", |
| 100 | + "timestamp_utc": "2026-05-12T09:01:00Z", |
| 101 | + "receipt_hash": "sha256:ac36b739bf676d8c9a20ca3c7199cc228d15f9f88b04ab1a61fb1da35dacd520", |
| 102 | + "signature": null |
| 103 | + } |
| 104 | + } |
| 105 | + ], |
| 106 | + "expected_verification": { |
| 107 | + "valid_chain": "PASS", |
| 108 | + "broken_chain_examples": "FAIL", |
| 109 | + "required_checks": [ |
| 110 | + "decision is REFUSE", |
| 111 | + "mutation_committed is false", |
| 112 | + "payload_hash matches attempted payload", |
| 113 | + "decision_record_hash matches DecisionRecord", |
| 114 | + "state_snapshot_hash matches post-refusal state snapshot", |
| 115 | + "previous_receipt_hash links to prior receipt_hash", |
| 116 | + "receipt_hash recomputes from canonical receipt body excluding receipt_hash and signature" |
| 117 | + ] |
| 118 | + } |
| 119 | +} |
0 commit comments