GPT Review — 09a IU-0 Pack 1 DDL Design Rev2
GPT Review — 09a IU-0 Pack 1 DDL Design Rev2
Date: 2026-05-04 Checked actual Agent Data document:
knowledge/dev/laws/dieu44-trien-khai/design/09a-iu0-pack1-vocab-schema-ddl-design.mdrev 2.
Verdict
Rev2 is materially better than rev1, but still NOT ready for execution. One more patch pass is required before C8 can be treated as closed and before asking User for C10 execution approval.
What improved
- Two-layer birth gate is now present.
unit_kindvocab enforcement exists viadot_configlookup.gen_random_uuid()pre-check is documented.- Publication WARN is explicitly pilot-only.
- Smoke tests T9-T11 were added.
- Rollback script now includes the layer1/layer2 triggers and functions.
Blocking issues to fix
P0-1 — Deferred Layer 2 uses NEW, which can fail incorrectly
The Layer 2 constraint trigger is AFTER INSERT OR UPDATE ... DEFERRABLE INITIALLY DEFERRED. In PostgreSQL, the trigger event row values are associated with the triggering event. If the INSERT initially has version_anchor_ref = NULL and the row is later updated in the same transaction, the deferred INSERT event may still evaluate with the original NEW values and fail at COMMIT, even though the final row is valid.
Fix: make fn_iu_birth_gate_layer2() re-query the current information_unit row by NEW.id at execution time, then validate that final/current row. Do not rely on NEW.content_anchor_ref / NEW.version_anchor_ref directly.
P0-2 — content_anchor_ref only checks non-null
Pack 1 transaction flow sets content_anchor_ref = version.id::text, so Layer 2 should enforce that content_anchor_ref = version_anchor_ref::text for Pack 1 pilot. Otherwise U5 can point to arbitrary text while U6 is valid.
P1-1 — Profile vocab enforcement incomplete
Layer 1 validates unit_kind, but primary_section_type_ref is a required field and should be checked against dot_config key vocab.section_type.<value> in pilot. publication_type_ref may be WARN-only when missing, but if present it should be checked against vocab.publication_type.<value>.
P1-2 — Empty string handling
Required JSONB string checks should reject both NULL and empty string for owner_lookup_ref, primary_section_type_ref, and publication fields when present.
P1-3 — Smoke tests should cover final-row deferred semantics
Add one positive test: INSERT unit with anchors NULL → INSERT version → UPDATE anchors → COMMIT succeeds, proving Layer 2 checks the final row not the stale INSERT image.
Direction to Opus
Patch 09a to rev3 in one pass. Do not execute SQL. Do not dispatch Agent.
Required changes:
- Rewrite Layer 2 function to select final row into a local record by
NEW.idbefore validation. - Enforce
content_anchor_ref = version_anchor_ref::textfor Pack 1. - Add checks for
primary_section_type_refand presentpublication_type_refagainstdot_configvocab keys. - Tighten empty-string checks.
- Add the positive smoke test for final-row deferred behavior.
- Update conflict check and rollback only if changed names require it.
Plain image: Rev2 has the right two-lock idea, but the second lock may be looking at the first draft of the door instead of the final assembled door. Make it look up the final door at closing time, then test again.