- prev_chain_hash
nullFirst record: no predecessor- payload_hash
PbQTKH7/sGHUg+GjB0acqsNluk4DuU42HAZaHUwQ5r4=SHA-256 of canonical state_payload- chain_hash
NZpNkbVJ5z7OzkbmqpiGM89RqzAA9A0+eUVvAyUPkOg=Becomes prev_chain_hash in sequence 2
Diagrams
These diagrams explain the decision evidence boundary: applications read state, make decisions, emit evidence, and StateMirror preserves that evidence for later integrity verification.
The application owns the decision.
StateMirror preserves decision-time evidence. The application reads state, applies business logic, owns the decision and action and submits an evidence snapshot for later inspection.
Submit once. Retrieve and verify later.
Each record carries the chain forward.
The previous record’s chain_hash becomes the next record’s prev_chain_hash. Matching values below show that continuity directly.
verify range / 1–3EXAMPLE RANGE /PASS- sequence_num001
- sequence_num002
- prev_chain_hash
NZpNkbVJ5z7OzkbmqpiGM89RqzAA9A0+eUVvAyUPkOg=chain_hash from sequence 1- payload_hash
H/po/j1xS7YqfbxVFftdw2ckMjmuLJJu92iXrFZajrk=SHA-256 of canonical state_payload- chain_hash
ID8uVcrrOft4c61G6lWdCQxsZwf6jrvN5atJp1agJiQ=Becomes prev_chain_hash in sequence 3
- sequence_num003
- prev_chain_hash
ID8uVcrrOft4c61G6lWdCQxsZwf6jrvN5atJp1agJiQ=chain_hash from sequence 2- payload_hash
ihcP+YghhVDHPTWs6eOeoET2gTLJfNj9AV2OGjw82IY=SHA-256 of canonical state_payload- chain_hash
lsyChJa9nPGo8U0txI2tvpJ/QI7qDwB65CAWOqnbVW0=Continues the same chain
payload_hash = SHA-256(canonical UTF-8 JSON(state_payload))chain_hash = SHA-256(sequence_num bytes || payload_hash bytes || prev_chain_hash bytes)|| means byte concatenation: 8-byte signed big-endian sequence, then two 32-byte hashes. The first record stores prev_chain_hash: null; hashing substitutes 32 zero bytes. Hashes above are Base64 encodings, not strings concatenated into the formula.
Inspect the example payloads and computed result
{
"records": [
{
"sequence_num": 1,
"state_payload": {
"subject": "customer_123",
"inputs": {
"plan_status": "active",
"seats_used": 10,
"seat_limit": 10,
"read_at": "2026-06-15T18:22:30.000Z"
},
"rule_version": "access-rules@2026.06.12",
"decision": "deny",
"reason": "seat_limit_reached",
"correlation_id": "request_001"
}
},
{
"sequence_num": 2,
"state_payload": {
"subject": "customer_123",
"inputs": {
"plan_status": "active",
"seats_used": 10,
"seat_limit": 10,
"read_at": "2026-06-15T18:22:30.000Z"
},
"rule_version": "access-rules@2026.06.12",
"decision": "deny",
"reason": "seat_limit_reached",
"correlation_id": "request_002"
}
},
{
"sequence_num": 3,
"state_payload": {
"subject": "customer_123",
"inputs": {
"plan_status": "active",
"seats_used": 10,
"seat_limit": 10,
"read_at": "2026-06-15T18:22:30.000Z"
},
"rule_version": "access-rules@2026.06.12",
"decision": "deny",
"reason": "seat_limit_reached",
"correlation_id": "request_003"
}
}
],
"verification": {
"valid": true,
"message": "Preserved evidence chain integrity verified.",
"checked_count": 3,
"first_sequence": 1,
"last_sequence": 3
}
}A changed payload breaks verification.
verify range / 1–3EXAMPLE RANGE /FAIL- sequence_num001INTEGRITY /PASS
- sequence_num002INTEGRITY /FAIL
PAYLOAD_HASH_MISMATCH - sequence_num003NOT CHECKEDRange stopped at 2
Sequence 2: the stored payload changed.
Change state_payload.decision from "deny" to "allow", leaving the stored hashes unchanged. Verification recomputes the payload hash and finds a mismatch.
expected/ recomputed from modified payload5HTyjnnLhUfCQHr11oXSBh1dg8EjT2ClBG+/J5qaT7I=actual/ stored payload_hashH/po/j1xS7YqfbxVFftdw2ckMjmuLJJu92iXrFZajrk=
Inspect Core’s computed failure result
{
"valid": false,
"failure_code": "PAYLOAD_HASH_MISMATCH",
"message": "Stored payload hash does not match recomputed payload hash.",
"sequence_num": 2,
"break_at_sequence": 2,
"expected": "5HTyjnnLhUfCQHr11oXSBh1dg8EjT2ClBG+/J5qaT7I=",
"actual": "H/po/j1xS7YqfbxVFftdw2ckMjmuLJJu92iXrFZajrk=",
"checked_count": 2,
"first_sequence": 1,
"last_sequence": 2
}