KB-4E75

GPT Review — P2B-P0 Schema Inspection Report and P2B-P1 Directive

9 min read Revision 1
gpt-reviewpack2bp2b-p0p2b-p1iu-0schema-first

GPT Review — P2B-P0 Schema Inspection Report and P2B-P1 Directive

Date: 2026-05-05 Reviewer: GPT-5.5 Thinking / Incomex Hội đồng AI Reviewed: knowledge/dev/laws/dieu44-trien-khai/reports/19-p2b-p0-iu-schema-inspection-report.md

Verdict

P2B-P0 PASS.

Agent produced a high-quality read-only schema inspection report. It satisfies the P2B-P0 prompt and adds useful operational insight by extracting L1/L2 trigger logic.

No additional read-only investigation is required before drafting P2B-P1, except one small vocabulary lookup that should be built into P2B-P1 preflight.

Key findings accepted

F1 — Clean baseline

  • information_unit rows = 0.
  • unit_version rows = 0.
  • birth_registry rows for information_unit = 0.
  • birth_registry rows for unit_version = 0.

F2 — IU/UV schema is a paired transaction, not independent inserts

information_unit and unit_version form a circular relationship:

  • IU version_anchor_refunit_version(id) is DEFERRABLE INITIALLY DEFERRED.
  • UV unit_idinformation_unit(id) is not deferrable.
  • L2 deferred trigger requires:
    • version_anchor_ref points to a UV row for the same IU;
    • content_anchor_ref = version_anchor_ref::text.

Therefore P2B-P1 must create IU + UV in a single transaction with a NULL-then-UPDATE/CTE pattern. Do not do separate independent inserts.

F3 — Birth trigger order is acceptable

trg_birth_information_unit fires AFTER IU INSERT, before the UV anchor UPDATE. That is acceptable because the birth trigger writes from identity_profile and does not require anchors.

F4 — L1 vocabulary gate is the main pre-P1 blocker

P2B-P1 must query dot_config vocab values before constructing payload:

  • vocab.unit_kind.%
  • vocab.section_type.%
  • optionally vocab.publication_type.%

Do not guess values such as document, section, etc.

F5 — RLS is not a blocker

No relevant RLS policies and relrowsecurity=false.

F6 — UV remains subordinate

unit_version has no trigger and birth_code_strategy=subordinate. Expected: no independent unit_version birth row.

Decisions for P2B-P1

D1 — Proceed to P2B-P1 design/prompt

Approved to draft P2B-P1 prompt, but not to dispatch until GPT/User review.

D2 — Pilot size

Use one pilot IU row + one UV row first, not two.

Rationale: first real birth-fire test should minimize state. A second row can be added later after first PASS.

D3 — Pilot canonical address

Use a clear pilot namespace, but confirm uniqueness in preflight:

pilot.iu0.test-001

If this exact address already exists, STOP and report; do not auto-increment or invent a new one silently.

D4 — Pilot payload values

Do not hardcode vocabulary values from memory.

P2B-P1 prompt must first query valid vocab values from dot_config. Then it may select the safest value based on actual results and report the selection.

If no suitable vocab value exists, STOP and report; do not create new vocab in P2B-P1.

D5 — Pilot row retention

For P2B-P1, keep pilot rows after successful verification unless GPT/User explicitly directs cleanup.

Rationale: later READ/version tests may need them. P2B-P1 report should include cleanup SQL draft only, not execute cleanup.

Required P2B-P1 prompt structure

Opus should create:

knowledge/dev/laws/dieu44-trien-khai/prompts/19-p2b-p1-iu-pilot-insert-and-birth-fire-prompt.md

Scope

Create exactly one IU row and one UV row in one transaction; verify birth trigger fire.

Required preflight

  1. Read controlling docs:

    • P2B-P0 schema report;
    • 18c report;
    • file 19 design;
    • this GPT review.
  2. Verify clean baselines:

    • IU count = 0;
    • UV count = 0;
    • IU birth count = 0;
    • UV birth count = 0;
    • trg_birth_information_unit exists;
    • fn_birth_registry_auto hash captured;
    • birth trigger count captured;
    • total birth count audit only.
  3. Vocabulary lookup:

SELECT key, value
FROM dot_config
WHERE key LIKE 'vocab.unit_kind.%'
   OR key LIKE 'vocab.section_type.%'
   OR key LIKE 'vocab.publication_type.%'
ORDER BY key;

Agent must choose valid values from query result and include evidence in report. If no valid unit_kind and section_type values exist, STOP.

  1. Confirm canonical address absent:
SELECT count(*) FROM information_unit WHERE canonical_address='pilot.iu0.test-001';

Expected 0.

Required transaction pattern

Use one transaction. Generate UUIDs explicitly to avoid circular FK ambiguity:

BEGIN;
SET CONSTRAINTS ALL DEFERRED;

WITH ids AS (
  SELECT gen_random_uuid() AS iu_id, gen_random_uuid() AS uv_id
), ins_iu AS (
  INSERT INTO information_unit (
    id,
    canonical_address,
    unit_kind,
    owner_ref,
    created_by,
    updated_by,
    identity_profile
  )
  SELECT
    iu_id,
    'pilot.iu0.test-001',
    '<VALID_UNIT_KIND_FROM_DOT_CONFIG>',
    'pilot.owner.iu0',
    'agent:p2b-p1',
    'agent:p2b-p1',
    jsonb_build_object(
      'title', 'Pilot IU 0 Test 001',
      'owner_lookup_ref', 'pilot.owner.iu0',
      'primary_section_type_ref', '<VALID_SECTION_TYPE_FROM_DOT_CONFIG>'
    )
  FROM ids
  RETURNING id
), ins_uv AS (
  INSERT INTO unit_version (
    id,
    unit_id,
    body,
    content_hash,
    version_seq,
    created_by,
    content_profile
  )
  SELECT
    ids.uv_id,
    ids.iu_id,
    'Pilot IU-0 Test 001 body — verifies IU insert, unit_version anchor, and birth trigger fire.',
    encode(digest('Pilot IU-0 Test 001 body — verifies IU insert, unit_version anchor, and birth trigger fire.', 'sha256'), 'hex'),
    1,
    'agent:p2b-p1',
    jsonb_build_object('profile_kind','pilot','test_case','p2b-p1')
  FROM ids
  RETURNING id, unit_id
), upd_iu AS (
  UPDATE information_unit iu
  SET version_anchor_ref = ins_uv.id,
      content_anchor_ref = ins_uv.id::text
  FROM ins_uv
  WHERE iu.id = ins_uv.unit_id
  RETURNING iu.id, iu.canonical_address, iu.version_anchor_ref, iu.content_anchor_ref
)
SELECT * FROM upd_iu;

-- Pre-COMMIT verification inside transaction:
-- IU row exists and anchors set;
-- UV row exists and unit_id matches;
-- content_anchor_ref = version_anchor_ref::text.

COMMIT;

This is a template. P2B-P1 prompt must replace vocab placeholders with actual values discovered in preflight.

Required post-verify

After COMMIT:

  1. IU row exists:
SELECT id, canonical_address, unit_kind, version_anchor_ref, content_anchor_ref, identity_profile
FROM information_unit
WHERE canonical_address='pilot.iu0.test-001';
  1. UV row exists and linked:
SELECT uv.id, uv.unit_id, uv.version_seq, uv.content_hash, uv.content_profile
FROM unit_version uv
JOIN information_unit iu ON iu.id=uv.unit_id
WHERE iu.canonical_address='pilot.iu0.test-001';
  1. IU birth row exists:
SELECT entity_code, collection_name, species_code, born_at
FROM birth_registry
WHERE collection_name='information_unit'
ORDER BY born_at DESC;

Expected:

  • count for information_unit increases 0 → 1;
  • entity_code should match actual synthetic output. Preferred expected pattern: information_unit::<uuid> matching the created IU id. Verify against actual IU id.
  1. UV birth remains 0:
SELECT count(*) FROM birth_registry WHERE collection_name='unit_version';
  1. Invariants:
  • fn_birth_registry_auto hash unchanged;
  • birth trigger count unchanged at 31;
  • total birth count audit may drift, but IU-specific count must be +1.

Rollback / cleanup rule

If transaction fails before COMMIT, no state should persist. Report failure.

If COMMIT succeeds but post-verify fails, do not hard-delete automatically unless the prompt includes a reviewed cleanup path. For P2B-P1, safer rule:

  • STOP + report state;
  • include cleanup SQL draft;
  • wait for GPT/User decision.

Rationale: deleting pilot rows in circular FK/birth_registry environment can create more risk than leaving a clearly named pilot row.

Report path

knowledge/dev/laws/dieu44-trien-khai/reports/19-p2b-p1-iu-pilot-insert-and-birth-fire-report.md

Report must include:

  • vocab query output + chosen values;
  • transaction SQL actually executed;
  • pre-COMMIT verification output;
  • post-COMMIT IU/UV row outputs;
  • birth_registry IU row output;
  • UV birth count;
  • function hash before/after;
  • trigger count before/after;
  • total birth count audit before/after;
  • whether pilot rows kept;
  • cleanup SQL draft but not executed;
  • hard boundaries confirmation.

Hard boundaries for P2B-P1

  • no schema changes;
  • no trigger/function changes;
  • no DOT-119 changes;
  • no raw birth_registry insert;
  • no unit_version birth trigger;
  • no Pack 2C/vector/outbox/Qdrant;
  • no Directus exposure;
  • no P3/HC;
  • no cleanup unless separately approved.

Current state

P2B-P0 is accepted. Next deliverable is P2B-P1 prompt for review, not immediate dispatch.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/reviews/gpt-review-p2b-p0-schema-inspection-report-and-p1-directive-2026-05-05.md