Context
Sub-issue of #9267 (external decision-ledger anchoring). Every anchor backend (#9272 Rekor, #9273 git) needs somewhere to record what it did — including when it failed. Per the research on #9267: a failed anchor attempt must be recorded and exposed publicly, or an operator could make every anchor silently "fail" and quietly regress back to tamper-evident-only with no visible signal.
Requirements
- New migration:
decision_ledger_anchors — seq, row_hash, payload_json, signature, backend ('rekor'|'git'|'ots'), backend_ref, proof_r2_key, status ('ok'|'failed'), error, created_at.
backend_ref for Rekor must store the full resolvable reference: { shardBaseUrl, logIndex, logIdKeyId, uuid } — a bare logIndex becomes unresolvable after the annual shard rotation.
- Failures are rows, not silence. A backend call that errors writes a
status: 'failed' row with the error, on the same schedule as a success would have.
- Public read surface:
GET /v1/public/decision-ledger/anchors (paginated) exposing every attempt, success or failure, so "anchoring has been failing for a week" is a fact anyone can observe, not something only the operator's own logs show.
Deliverables
- Migration + drift-check compliance (contiguous
NNNN_*.sql, per house convention)
- Persistence helper used by both backend issues
- Public listing endpoint + OpenAPI entry
- Tests: success row, failure row, pagination, and that a failure is queryable identically to a success (no special-casing that could hide it)
Expected outcome
Anchoring's own health is itself a publicly verifiable fact, closing the "silent regression" hole the research identified.
References
Sub-issue of #9267. Feeds #9272 (Rekor backend), #9273 (git-commit backend). Depends on #9270 (payload shape) for payload_json's contents.
Context
Sub-issue of #9267 (external decision-ledger anchoring). Every anchor backend (#9272 Rekor, #9273 git) needs somewhere to record what it did — including when it failed. Per the research on #9267: a failed anchor attempt must be recorded and exposed publicly, or an operator could make every anchor silently "fail" and quietly regress back to tamper-evident-only with no visible signal.
Requirements
decision_ledger_anchors—seq, row_hash, payload_json, signature, backend ('rekor'|'git'|'ots'), backend_ref, proof_r2_key, status ('ok'|'failed'), error, created_at.backend_reffor Rekor must store the full resolvable reference:{ shardBaseUrl, logIndex, logIdKeyId, uuid }— a barelogIndexbecomes unresolvable after the annual shard rotation.status: 'failed'row with the error, on the same schedule as a success would have.GET /v1/public/decision-ledger/anchors(paginated) exposing every attempt, success or failure, so "anchoring has been failing for a week" is a fact anyone can observe, not something only the operator's own logs show.Deliverables
NNNN_*.sql, per house convention)Expected outcome
Anchoring's own health is itself a publicly verifiable fact, closing the "silent regression" hole the research identified.
References
Sub-issue of #9267. Feeds #9272 (Rekor backend), #9273 (git-commit backend). Depends on #9270 (payload shape) for
payload_json's contents.