Mig 151 (t-paliad-319) archived 5 of 6 duplicate procedural_events for
"Mängelbeseitigung / Zahlung" and reparented their sequencing_rules
onto the canonical PE. The 6 sequencing_rules themselves were left
active — and they are byte-for-byte clones (proceeding_type_id=NULL,
rule_code=NULL, duration 14d, primary_party=NULL, condition_expr=NULL,
…). The admin shows six indistinguishable rows for one legal concept.
This migration archives 5 of 6, keeping the row with the
lexicographically lowest UUID as canonical.
Pre-write verification (Supabase MCP, 2026-05-26):
- Exactly 1 clone-group surfaces under the full-signature query
(procedural_event_id, proceeding_type_id, rule_code, duration_*,
primary_party, condition_expr::text, trigger_event_id, alt_*,
anchor_alt, combine_op, parent_id, is_spawn, spawn_*):
6 "Mängelbeseitigung / Zahlung" rows.
- 0 paliad.deadlines reference any of the 5 to-be-archived rows
(verified via deadlines.sequencing_rule_id JOIN; rule_id column
was dropped in mig 140 / Slice B.4).
- Other name-duplicates (Antrag auf Patentänderung×4, Beginn des
Hauptsacheverfahrens×2, Berufungsbegründung-R.220.1×2,
Berufungsschrift-R.220.1×2) do NOT collapse under this signature —
their proceeding_type_id / rule_code / duration / primary_party
differ. Legitimately distinct rules per proceeding. This mig
leaves them alone.
Migration shape (mirrors mig 151):
1. Build dedupe mapping (duplicate_id → canonical_id) into a
ROW_NUMBER() OVER (PARTITION BY full-signature ORDER BY
created_at, id::text) TEMP table.
2. PRE NOTICE: surface every clone-group with its canonical + dups
so the deploy log shows what's about to be touched (m may want
to spot-check).
3. Snapshot the duplicates into paliad.sequencing_rules_pre_152
(precedent pre_091/093/095/098/140/151).
4. Reparent paliad.deadlines.sequencing_rule_id duplicate → canonical
BEFORE archiving (defensive no-op today).
5. set_config('paliad.audit_reason', …) — defensive; sequencing_rules
has no audit trigger yet (mig 151 §scope verified), but a future
trigger would inherit the reason automatically.
6. UPDATE sequencing_rules SET is_active=false,
lifecycle_state='archived' WHERE id IN dups.
7. POST assertions: expected archive count met, zero clone groups
remaining in active+published, zero live deadlines pointing at
an archived sequencing_rule. RAISE EXCEPTION on any mismatch.
Down: best-effort revert (flips archived → published from snapshot).
Doesn't undo the deadlines reparent (live data didn't need one;
snapshot doesn't carry pre-state of deadlines).
Build + vet clean. TestMigrations_NoDuplicateSlot passes.