Observed on a live self-host instance
GET /v1/public/decision-ledger/verify
{"ok":false,"checked":4,"tipSeq":1639,"totalCount":1639,"prunedRecords":0,
"break":{"kind":"content_mismatch","atSeq":5,
"recordId":"record:JSONbored/loopover#8921@a2446db8e808529d19803ada464cc9d605a89638"}}
Verification stops at the first break, so 4 of 1,639 rows are checked and the endpoint publicly reports
ok: false. Anyone running the documented verification against this deployment sees a chain break.
Why this is probably not tampering
The chain is only three days old — seq 1 @ 2026-07-26T13:40:09Z, seq 1639 @ 2026-07-29T14:01:03Z — and
prunedRecords: 0, so the legitimate pruned-preimage explanation does not apply. The instance has been
tracking beta images across that window (currently orb-v3.6.0-beta.6).
The likely cause is that the decision-record preimage changed between the release that wrote seq 5 and the
release verifying it now. Recomputing the digest over the current shape yields a different value than the one
committed at write time, and the content check correctly reports a mismatch.
Why that matters more than one bad row
If the record preimage is not stable across versions, then every schema change silently invalidates the
content check for every row written before it — and the published /verify endpoint starts reporting
ok: false on an untampered ledger. The chain-structure guarantees (sequence, prevHash, rowHash) still hold;
it is specifically the content re-check that breaks.
That inverts what the surface is for. A verifier cannot distinguish "someone edited a record" from "the
software changed shape", which is exactly the discrimination the ledger exists to provide.
What needs deciding
- Is the record preimage intended to be version-stable? If yes, this is a bug in whatever changed it, and
the fix is a versioned preimage (a schemaVersion in the digest input, with the verifier recomputing under
the row's own version) rather than a re-hash of history.
- If it is NOT intended to be stable,
/verify needs to say so — the same way prunedRecords already
carves out legitimately-unre-checkable rows — so a shape change does not read as tampering.
Reproduce
Any deployment whose ledger spans a release that altered the decision-record shape. Confirmed above on a
3-day-old chain.
Links
src/review/decision-record.ts, src/review/ledger-anchor.ts, the /v1/public/decision-ledger/verify
handler in src/api/routes.ts. Related: #9271, #9267.
Observed on a live self-host instance
Verification stops at the first break, so 4 of 1,639 rows are checked and the endpoint publicly reports
ok: false. Anyone running the documented verification against this deployment sees a chain break.Why this is probably not tampering
The chain is only three days old —
seq 1 @ 2026-07-26T13:40:09Z,seq 1639 @ 2026-07-29T14:01:03Z— andprunedRecords: 0, so the legitimate pruned-preimage explanation does not apply. The instance has beentracking beta images across that window (currently
orb-v3.6.0-beta.6).The likely cause is that the decision-record preimage changed between the release that wrote seq 5 and the
release verifying it now. Recomputing the digest over the current shape yields a different value than the one
committed at write time, and the content check correctly reports a mismatch.
Why that matters more than one bad row
If the record preimage is not stable across versions, then every schema change silently invalidates the
content check for every row written before it — and the published
/verifyendpoint starts reportingok: falseon an untampered ledger. The chain-structure guarantees (sequence, prevHash, rowHash) still hold;it is specifically the content re-check that breaks.
That inverts what the surface is for. A verifier cannot distinguish "someone edited a record" from "the
software changed shape", which is exactly the discrimination the ledger exists to provide.
What needs deciding
the fix is a versioned preimage (a
schemaVersionin the digest input, with the verifier recomputing underthe row's own version) rather than a re-hash of history.
/verifyneeds to say so — the same wayprunedRecordsalreadycarves out legitimately-unre-checkable rows — so a shape change does not read as tampering.
Reproduce
Any deployment whose ledger spans a release that altered the decision-record shape. Confirmed above on a
3-day-old chain.
Links
src/review/decision-record.ts,src/review/ledger-anchor.ts, the/v1/public/decision-ledger/verifyhandler in
src/api/routes.ts. Related: #9271, #9267.