Summary
Two retention rules interact badly with consumers that assume their tables are permanent. Both are latent today and become visible on a schedule, which is why they are worth fixing before they surface.
1. decision_records 180-day prune manufactures a false tamper signal
src/db/retention.ts:57 prunes decision_records at 180 days. But verifyDecisionLedger requires the record for every ledger row — src/review/decision-record.ts:460-463 maps recordsById.get(row.recordId) and yields {kind: "missing_record"} when absent — and ledger rows are never pruned. Verification also walks from afterSeq = 0 genesis (:412).
So roughly 180 days after the rule first bites, any full-chain verification reports the chain broken at the first pruned record. For a public tamper-evidence feature, that is the worst possible false positive: a legitimate retention policy is indistinguishable from evidence of tampering, and the feature's own documentation teaches readers to treat it as the latter.
The retention comment describes decision_records as "a contributor's evidentiary trail" kept longer than most — the omission is that the ledger references it forever.
Deliverables
2. orb_pr_outcomes 90-day prune will shrink the cumulative public counter
#9415 added { table: "orb_pr_outcomes", column: "occurred_at", days: 90 } (src/db/retention.ts:77). But getOrbGlobalStats SUMs the entire table — src/orb/outcomes.ts:63-92:
SUM(CASE WHEN o.outcome = 'merged' THEN 1 ELSE 0 END) AS merged,
SUM(CASE WHEN o.outcome = 'closed' THEN 1 ELSE 0 END) AS closed,
COUNT(*) AS total
FROM orb_pr_outcomes o ...
and src/review/public-stats.ts:465-468 folds that into the cumulative homepage totals:
totals.merged += orb.merged;
totals.closed += orb.closed;
totals.handled += orb.total;
Once rows begin aging past 90 days, the "all-time" counters plateau and then decrease — a public number visibly going backwards, roughly from 2026-10-25 given #9415's merge date.
Deliverables
Expected outcome
Retention never changes the meaning of a published number, and never produces a signal that reads as tampering.
Summary
Two retention rules interact badly with consumers that assume their tables are permanent. Both are latent today and become visible on a schedule, which is why they are worth fixing before they surface.
1.
decision_records180-day prune manufactures a false tamper signalsrc/db/retention.ts:57prunesdecision_recordsat 180 days. ButverifyDecisionLedgerrequires the record for every ledger row —src/review/decision-record.ts:460-463mapsrecordsById.get(row.recordId)and yields{kind: "missing_record"}when absent — and ledger rows are never pruned. Verification also walks fromafterSeq = 0genesis (:412).So roughly 180 days after the rule first bites, any full-chain verification reports the chain broken at the first pruned record. For a public tamper-evidence feature, that is the worst possible false positive: a legitimate retention policy is indistinguishable from evidence of tampering, and the feature's own documentation teaches readers to treat it as the latter.
The retention comment describes
decision_recordsas "a contributor's evidentiary trail" kept longer than most — the omission is that the ledger references it forever.Deliverables
pruned-before-<watermark>tolerance tied to the retention cutoff; or start verification at the oldest surviving record's seq. Whichever is chosen must be legible to an external skeptic — the point of the feature is that a third party can check it.short_tailsemantics.2.
orb_pr_outcomes90-day prune will shrink the cumulative public counter#9415 added
{ table: "orb_pr_outcomes", column: "occurred_at", days: 90 }(src/db/retention.ts:77). ButgetOrbGlobalStatsSUMs the entire table —src/orb/outcomes.ts:63-92:and
src/review/public-stats.ts:465-468folds that into the cumulative homepage totals:Once rows begin aging past 90 days, the "all-time" counters plateau and then decrease — a public number visibly going backwards, roughly from 2026-10-25 given #9415's merge date.
Deliverables
orb_outcome_totalsroll-up updated by the prune), or excludeorb_pr_outcomesfrom retention and bound it another way.computeFleetAnalyticsis the obvious neighbour to audit.Expected outcome
Retention never changes the meaning of a published number, and never produces a signal that reads as tampering.