← all branches

fix/dup-repair

safeviewing older commit
8af2fab · incrementalPR #306reviewed 2026-07-14 14:16 UTC0H · 0M · 2L · 2I
The branch
Purpose
One-shot operational script to repair June-2026 duplicate contract damage where the CFE pipeline minted contamination twin contracts for 57 RPUs during a bug window (2026-06-05 to 2026-06-23).
Goal
Safely flip each dup group so the newest-CFE-evidence holder is the active contract, soft-delete contamination twins, repoint SUCs and subscriptions, and clean up 12 foreign bills from the #231 remediation residue.
Sub-goals
  • SG-1: Classify dup groups with typed verdicts (FLIP_DELETE_TWIN, FLIP_KEEP_HISTORY, REACTIVATE_NO_EVIDENCE, SKIP_MANUAL, NO_ACTION_OK)
  • SG-2: Dry-run default, per-group FOR UPDATE transactions, idempotent re-runs
  • SG-3: Staging rehearsal 3/3 groups repaired; prod dry-run 57 twin-deletes + 17 flips + 12 foreign bills
  • SG-4: Unit-test the pure classifier core (16 tests)
  • SG-5: Fix Array.map-index footgun that silently disabled the contamination window
The changes (whole branch)
What
Fixed Array.map-index footgun: groups.map(classify) was passing the array element index as the window argument, disabling isTwinShaped checks. Added runtime guard in classify() + arrow-function wrappers at both call sites + test.
Why
Caught on prod pilot dry-run 2026-07-14: all FLIP_DELETE_TWIN verdicts were silently degrading to FLIP_KEEP_HISTORY because the window guard received index 0 instead of ContaminationWindow.
Areas
scripts/__tests__/repair-dup-contracts-core.test.ts+110scripts/lib/repair-dup-contracts-core.ts+70scripts/repair-dup-contracts.ts+22
Blast
3 files, +20/-2 in the operational repair script; no domain/platform code touched. Script-only impact.
one-shot script prod-repair dry-run-default
ci· CI status not accessible (token scope)coderabbit· no .coderabbit.yaml

Findings · 4

conventions1

info

Test comment slightly duplicates the test name

scripts/__tests__/repair-dup-contracts-core.test.ts:183

The comment explains what the test name already says. The incident date (2026-07-14) is the only additive context. Trivial; not a blocker.

tests2

low

Empty-object edge case not tested in classify() guard

scripts/__tests__/repair-dup-contracts-core.test.ts:185

The guard uses !window.start || !window.end to reject objects missing those fields, but no test hits that path. expect(() => classify(g, {} as never)).toThrow(/invalid window/) would seal it.

info

as never cast is reasonable; as unknown as ContaminationWindow is more idiomatic

scripts/__tests__/repair-dup-contracts-core.test.ts:185

Minor style preference — both work, no correctness difference.

improvement1

low

inWindow() has the same footgun risk (no guard)

scripts/lib/repair-dup-contracts-core.ts:56

inWindow() is exported with the same optional ContaminationWindow signature. Not currently .map()-called in the main script, so not a live bug, but the risk is structurally identical.

History · 8 commits

  1. 80e0f62safeincremental0H · 0M · 1L2026-07-16 19:20
  2. d513853needs attentionincremental0H · 2M · 3L2026-07-16 19:13
  3. 3de8c23safeincremental0H · 1M · 3L2026-07-14 14:23
  4. 8af2fabsafeincremental0H · 0M · 2L2026-07-14 14:16current
  5. 8e6343eneeds attentionincremental0H · 1M · 3L2026-07-14 04:45
  6. 57eb1ebneeds attentionincremental0H · 2M · 4L2026-07-14 02:41
  7. a29f8f4needs attentionincremental0H · 4M · 6L2026-07-14 02:33
  8. 27179efneeds attentionfull5H · 4M · 3L2026-07-14 02:15