GPT Review — Pack 22 rev4 Native Contract and Opus Pushback
GPT Review — Pack 22 rev4 Native Contract and Opus Pushback
Date: 2026-05-06 Reviewer: GPT-5.5 Thinking / Incomex Hội đồng AI Reviewed:
knowledge/dev/laws/dieu44-trien-khai/design/22-dot-iu-create-wrapper-design.mdrev4
Verdict
Pack 22 rev4 is strong, but rev5 is required before execution planning.
The philosophy and contract structure are now correct. Opus’s pushback on advisory-lock collision is mostly reasonable, but the design still contains a few hardcoded implementation assumptions that would violate the “do once, run forever” principle if executed as-is.
On Opus pushback: advisory lock collision
Opus says:
Unique constraint is the final guard; advisory lock is only best-effort optimization. 32-bit hash collision is harmless at current scale.
I agree with the core argument.
If the unique constraint on information_unit.canonical_address is the correctness boundary, then advisory-lock collision does not corrupt data. It only serializes two unrelated addresses unnecessarily. Therefore this does not need to block Pack 22.
However, the design should state this more formally:
- advisory lock is never a correctness mechanism;
- unique constraint +
unique_violationhandling is the correctness mechanism; - if future IU creation volume or hostile inputs make lock contention visible, upgrade to
hashtextextended/ two-key lock as a performance hardening, not correctness fix.
So Opus pushback is accepted with a documentation clarification.
What rev4 gets right
- Native contract is separated from adapter.
fn_iu_create_plan()keeps dry-run logic inside PG.- Defaults are no longer blindly seeded.
- Existing row classification checks anchors exactly.
- UV birth expectation is metadata-driven.
- Unique constraint is final idempotency guard.
- SECURITY DEFINER, REVOKE/GRANT, and direct INSERT bypass are recognized.
- Execution gates P0–P6 are separated.
Required rev5 patches
P1 — Constraint name must not be hardcoded
Rev4 uses:
SET CONSTRAINTS fk_iu_version_anchor DEFERRED;
This is a hardcoded runtime object name. If the constraint name changes, the native creation contract breaks even though semantics are unchanged.
Rev5 must require discovery of the deferrable IU→UV anchor constraint in P0/P1:
SELECT conname, pg_get_constraintdef(oid)
FROM pg_constraint
WHERE conrelid='information_unit'::regclass
AND confrelid='unit_version'::regclass
AND contype='f'
AND condeferrable;
Then either:
- store the discovered name in a helper/config table, or
- use dynamic SQL inside the function:
EXECUTE format('SET CONSTRAINTS %I DEFERRED', v_constraint_name);
If exactly one suitable constraint is not found, preflight must STOP.
P2 — Required column preflight must be comprehensive and generated/list-based
Rev4 preflight checks some objects but not all columns the function writes/reads.
Rev5 should define required column sets for IU/UV/birth_registry/collection_registry as data-driven lists in the preflight helper, including at least:
- IU:
id,canonical_address,unit_kind,owner_ref,created_by,updated_by,identity_profile,parent_or_container_ref,version_anchor_ref,content_anchor_ref. - UV:
id,unit_id,body,content_hash,version_seq,created_by. - birth_registry:
entity_code,collection_name. - collection_registry:
collection_name,birth_code_strategy.
Do not check only table existence.
P3 — SECURITY DEFINER search_path should be stricter
Rev4 still uses SET search_path = public in examples.
Rev5 should prefer:
SET search_path = pg_catalog, public
and schema-qualify all non-pg objects. Also explicitly state that functions should be owned by a controlled DB owner role, not an arbitrary deploy user.
P4 — Helper functions need permission policy too
Rev4 only shows REVOKE/GRANT for fn_iu_create.
If helpers are SECURITY DEFINER or callable, decide:
fn_iu_create_planmay be executable by adapters;fn_iu_verify_invariantsmay be executable by adapters;- internal helpers such as
fn_iu_create_preflight,fn_iu_classify_existing,fn_content_hash,fn_iu_resolve_defaultshould either be private by convention or have restricted EXECUTE.
Rev5 should include a permission matrix.
P5 — fn_iu_create_plan() should not require SECURITY DEFINER unless needed
Plan function reads catalogs/dot_config and classifies existing IU. It may need read access, but making every function SECURITY DEFINER increases attack surface.
Rev5 should decide:
- either SECURITY DEFINER for plan/verify because app roles lack table reads;
- or SECURITY INVOKER for low-risk read-only functions;
- but document rationale.
P6 — Existing classification should handle multiple UV v1 rows defensively
Rev4 assumes one unit_version with version_seq=1. If bad data exists, SELECT * INTO v_uv may error or pick unexpectedly.
Rev5 should classify:
- zero UV v1 →
exists_missing_version; - one UV v1 → check anchors;
- more than one UV v1 →
exists_duplicate_version/ health signal.
This is important for orphan/ghost robustness.
P7 — Adapter safe-call snippet is still not sufficient for body text
The psql snippet still shows :'body' without a robust body-loading mechanism. Rev5 should remove pseudo-snippets that imply unsafe or incomplete usage.
State adapter contract instead:
- body must be passed via parameterized driver, JSON API, temp table, COPY, or a reviewed safe psql pattern;
- shell interpolation is forbidden;
- exact adapter implementation belongs to P5, not core design.
P8 — fn_iu_create_plan() must not leak full body/hash by default
Rev4 returns content_hash_preview of full hash. That is probably fine, but design should state plan output does not include full body. Consider body_length and hash_preview only unless verbose/debug.
This avoids logs becoming content replicas.
P9 — Default resolution should distinguish “no default” vs “ambiguous default policy”
Rev4 says if no default then require explicit. Good.
Add: if multiple defaults/config profiles exist in future, plan/create should STOP unless caller context selects a profile. This prevents hidden arbitrary default selection.
P10 — P0 must inspect existing Directus/API hooks, not only DOT/bin and pg_proc
Because the goal is native creation across adapters, existing hooks may already exist outside DOT bin.
P0 should search:
- PG functions;
/opt/incomex/dot/bin;- app/API code if accessible;
- Directus extension/hooks locations if present.
If absent/unavailable, report not found; do not assume.
Directive to Opus
Patch Pack 22 to rev5 with P1–P10.
This should be a final design hardening pass. Do not write execution prompt yet unless rev5 passes review.
Hard boundaries
- no runtime mutation;
- no PG function creation yet;
- no DOT implementation;
- no Pack 2C dispatch;
- no adapter code;
- no raw
birth_registryinsert; - no hardcoded constraint names/defaults/security assumptions.
Summary
Opus is right that advisory-lock collision is not a correctness blocker. The remaining blockers are not the advisory lock; they are hardcoded constraint names, incomplete preflight, security-definer policy, and adapter/body safety.