KB-4C6E

IU Core MVP — 04 DDL Migration + Rollback Package

4 min read Revision 1
dieu44iu-core-mvpddl-packagerollbackv0.62026-05-21author-only

IU Core MVP — 04 DDL Migration + Rollback Package

Date: 2026-05-21 · Author-only. NO DDL executed. Repo path sql/iu-core/.

Forward migrations

# File Objects Notes
001 001_iu_sql_link.sql table iu_sql_link + 3 indexes IU↔SQL object link; idempotency UNIQUE; object-shape CHECKs
002 002_iu_event_routes.sql iu_sql_event_route, iu_outbound_route, iu_route_attempt + 5 indexes route registries; enabled=false OR dry_run=true CHECK on both routes
003 003_parent_child_constraints.sql table iu_tree_path + 3 indexes + view v_iu_tree recursive view is cycle-safe (path-membership guard)
004 004_structure_ops_lineage.sql iu_structure_operation, iu_relation + partial-unique + 4 indexes one active contains parent per child enforced
005 005_trigger_contracts_and_guards.sql 7 functions + view v_iu_sql_link_resolved NO CREATE TRIGGER; trigger DDL parked in commented SANDBOX-ONLY block

Rollback package (reverse order 005 → 001)

Every forward file has rollback/NNN_*.rollback.sql. Each table rollback is a DO block that RAISES and REFUSES if the table still holds rows. Rollback 005 drops functions/views in reverse dependency order and documents that a sandbox-attached trigger must be dropped first (intentional fail-closed).

DDL constraint compliance

  • No hard delete: zero ON DELETE CASCADE; links/relations retire via lifecycle_status / relation_status + valid_to.
  • Idempotent shape: CREATE TABLE/INDEX IF NOT EXISTS, CREATE OR REPLACE.
  • No ALTER on information_unit, unit_version, event_*, cutter_governance.*.
  • No cross-schema FK to catalog internals (pg_proc/pg_class/pg_trigger); resolution is a STABLE helper function fn_iu_sql_link_validate.
  • Every table carries audit timestamps (created_at / started_at / valid_from).
  • Every event/route table carries an idempotency/uniqueness guard (idempotency_key UNIQUE on link + operation; (idempotency_key,attempt_no) UNIQUE on attempt; route_code UNIQUE on both routes).
  • Disabled-by-default: route rows default enabled=false, dry_run=true, fail_closed=true; a CHECK forbids an enabled+non-dry-run route in this package.
  • Owner/purpose/lifecycle in every file header + COMMENT ON on tables.
  • Each migration wrapped BEGIN; ... COMMIT;.

Idempotency key formats (from DDL brief, mirrored in cutter_agent/iu_core)

iu_sql_link : iu_sql_link:{unit_id}:{object_kind}:{schema}:{name}:{row_pk_hash}:{link_role}
inbound     : iu_sql_in:{route_code}:{schema}.{table}:{pk_hash}:{op}:{content_or_tx}
outbound    : iu_out:{event_domain}:{event_type}:{unit_id}:{version_ref}:{content_or_seq}
attempt     : iu_attempt:{route_kind}:{route_code}:{event_ref}:{subject_hash}
operation   : iu_op:{operation_type}:{sorted_source_ids}:{sorted_target_ids}:{payload_hash}

Acceptance checklist (DDL brief §G4) — status

Schema: exactly the approved objects (+ justified iu_route_attempt); no ALTER; no trigger attached; UUID PK + gen_random_uuid(); metadata default '{}'::jsonb; routes default safe — ALL PASS. FK/check/index: link FKs to information_unit + unit_version; UNIQUE idempotency_key; UNIQUE route_code ×2; CHECKs for kinds/direction/lifecycle/ sql_event/target_kind; lookup indexes; no catalog FK — ALL PASS. No-mutation: authored only, not executed; sandbox plan separate; production approval absent ⇒ STOP — PASS. Rollback/disable: routes disable without trigger drop; links retire not delete; future trigger has disable route + guard plan; DOT verifier planned — PASS.

Production execution: NOT performed. See report 10.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-core-mvp-pg-native-parent-child-structure-ops-authoring/04-ddl-migration-and-rollback-package.md