feat(orb): hash-chained append-only decision ledger with a public verify endpoint - #8843
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
loopover-ui | 1f269ad | Commit Preview URL Branch Preview URL |
Jul 26 2026, 12:01 PM |
Contributor
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
JSONbored
force-pushed
the
feat/decision-record
branch
from
July 26, 2026 11:54
dd85f5a to
f237a05
Compare
JSONbored
force-pushed
the
feat/decision-ledger
branch
from
July 26, 2026 11:55
a94867c to
c8f0327
Compare
…ify endpoint decision_records makes each verdict legible; the chain makes the SEQUENCE tamper-evident: nobody deletes, reorders, or rewrites history without breaking it at a verifiable point. Advances #8837 (external anchoring/witnesses remain, deliberately deferred until tenants exist). - explicit contiguous seq (never autoincrement -- a gap IS a break), genesis prev of 64 zeros, row_hash = SHA-256(prev || canonical fields); every persist appends, including latest-finalize-wins rewrites -- supersessions are visible history - concurrent appends race on the PK and retry with a re-read tip - GET /v1/public/decision-ledger/verify: resumable window verification reporting the FIRST break by class (sequence_gap | predecessor_mismatch | row_hash_mismatch); hashes/ids only, safe unauthenticated; 409 on a break - honest limit documented at the migration: self-operated chains are tamper-evident, not tamper-proof
JSONbored
force-pushed
the
feat/decision-ledger
branch
from
July 26, 2026 11:58
c8f0327 to
1f269ad
Compare
❌ 2 Tests Failed:
View the top 2 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
This was referenced Jul 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A hash-chained, append-only ledger over the decision records, with a public, resumable verify endpoint. Advances #8837 — external anchoring (signed checkpoints / witness cosigning) stays deliberately deferred until tenants exist, per the epic's sequencing. Stacked on #8842 (chains the records that PR persists).
Why
#8842 makes each verdict legible; this makes the sequence tamper-evident. Nobody can delete, reorder, or silently rewrite decision history without breaking the chain at a point any observer can find — at ~1% of the cost of the TEE approach the research explicitly recommended against, and against a threat model we actually have.
The honest limit is documented at the migration and repeated here: a self-operated chain is tamper-evident, not tamper-proof — the operator can still rewrite wholesale. That gap is closed by witness cosigning when there are tenants to ask for it; it does not reduce the value against every other actor or against accidental corruption.
How
seqis explicit and contiguous, never autoincrement — a deleted row leaves a gap, and a gap is a detectable break rather than something the sequence papers over.row_hash = SHA-256(prev_hash ‖ canonicalJson({seq, recordId, recordDigest, createdAt})); genesis links to 64 zeros. One definition shared by append and verify.persistDecisionRecordwrite appends — including latest-finalize-wins rewrites of the same record id, so supersessions are visible history, not silent replacement.GET /v1/public/decision-ledger/verify?afterSeq=&limit=— verifies a window, reports the first break with its class (sequence_gap|predecessor_mismatch|row_hash_mismatch), returns a resume cursor, 409 on any break. Hashes and ids only — no record contents — so it is safe unauthenticated. Registered in the OpenAPI spec.Includes a real bug found by its own tests: the resume-cursor probe used
=== nullwhere D1 drivers returnundefinedfor no-row — a missing prior row would have verified as clean. Now== null, with the arm pinned.Verification