fix/dup-repair
needs attentionviewing older commit27179ef · fullPR #306reviewed 2026-07-14 02:15 UTC5H · 4M · 3L · 1I- Purpose
- Repair the June-2026 duplicate-contract damage: contamination twins minted by foreign CFE XML cross-account contamination (#231), inverted replacements from stale-evidence backfills, and foreign xml bills (#231 residue).
- Goal
- One-shot data remediation: flip each dup group so the newest-CFE-evidence holder becomes active, soft-delete contamination twins, re-point SUCs + subscriptions, sweep foreign bills.
- Sub-goals
- Census + classify into 5 verdict types
- Per-group FOR UPDATE transactions with version guards
- Foreign-bill sweep + S3 manifest
- Dry-run default + typed reparar confirmation + post-run re-census verify
- What
- Adds scripts/repair-dup-contracts.ts (601 lines). No production runtime code changed.
- Why
- PR #298 fixed future recurrence; this script repairs the ~85 existing actionable groups (57 twin-deletes + 17 flips + 12 foreign bills + 1 SKIP_MANUAL). Staging rehearsal 2026-07-13: 3/3 groups, 0 actionable after.
- Areas
- scripts/repair-dup-contracts.ts+601−0
- Blast
- 1 file, +601 lines, no production runtime code. Script runs manually against prod DB — ~85 actionable dup groups.
Findings · 13
correctness4
FLIP_DELETE_TWIN leaves orphaned xml bill rows when twin has foreign xml bills
scripts/repair-dup-contracts.ts:355
DELETE bill_files covers ALL bills (incl. foreign xml), but DELETE bills only removes source<>xml. A twin with foreign_xml>0 passes the twin check (xml_bills counts non-foreign only). Fix: drop the AND source <> xml predicate in the twin case.
findForeignBills missing deleted_at IS NULL on utility_contracts join
scripts/repair-dup-contracts.ts:433
Sweep scans bills on already-soft-deleted contracts (twins from the repair loop). Add AND uc.deleted_at IS NULL.
REACTIVATE_NO_EVIDENCE: deposed twin gets terminate, not soft-delete
scripts/repair-dup-contracts.ts:344
repairGroup only checks verdict === FLIP_DELETE_TWIN for soft-delete; REACTIVATE_NO_EVIDENCE falls through to FLIP_KEEP_HISTORY. The deposed contamination-twin gets terminate instead of soft-delete + bill purge.
SET statement_timeout may not apply under Supavisor pooling
scripts/repair-dup-contracts.ts:469
security1
Non-numeric --limit silently removes scope guard
scripts/repair-dup-contracts.ts:103
conventions1
classify() closes over module-level WINDOW constants instead of params
scripts/repair-dup-contracts.ts:253
tests2
No unit tests for classify() — project precedent requires testing pure script logic
scripts/repair-dup-contracts.ts
classify() has 6 reachable verdict paths with no tests. Project precedent (metrics migration scripts) requires unit tests for pure script logic.
REACTIVATE_NO_EVIDENCE preWindow tie-breaking untested
scripts/repair-dup-contracts.ts:265
improvement5
entity_relationships rows not re-pointed from deposed to holder
scripts/repair-dup-contracts.ts:373
repairGroup re-points SUCs + subscriptions but not entity_relationships. If used as PATH 2 org-claim path, those orgs silently lose contract visibility.
Snapshot captures plan intent, not pre-change DB state
scripts/repair-dup-contracts.ts:539
Foreign-bill sweep has no SELECT FOR UPDATE — race with concurrent pipeline write
scripts/repair-dup-contracts.ts:450
--skip-foreign --execute produces snapshot with foreignBills: [] — misleading audit trail
scripts/repair-dup-contracts.ts:547
Bills not version-locked inside transaction
scripts/repair-dup-contracts.ts:317
History · 8 commits
- 80e0f62safeincremental0H · 0M · 1L2026-07-16 19:20
- d513853needs attentionincremental0H · 2M · 3L2026-07-16 19:13
- 3de8c23safeincremental0H · 1M · 3L2026-07-14 14:23
- 8af2fabsafeincremental0H · 0M · 2L2026-07-14 14:16
- 8e6343eneeds attentionincremental0H · 1M · 3L2026-07-14 04:45
- 57eb1ebneeds attentionincremental0H · 2M · 4L2026-07-14 02:41
- a29f8f4needs attentionincremental0H · 4M · 6L2026-07-14 02:33
- 27179efneeds attentionfull5H · 4M · 3L2026-07-14 02:15current