KB-6883 rev 10

P2B-P1 — IU Pilot INSERT + Birth Fire Verification Prompt

11 min read Revision 10
iu-0pack-2bp2b-p1pilot-insertbirth-fireprompt

P2B-P1 — IU Pilot INSERT + Birth Fire Verification Prompt

Date: 2026-05-05 | Status: PROMPT rev2 — chờ GPT/User approve trước dispatch Controlling: P2B-P0 report + GPT P2B-P0 review + GPT P2B-P1 rev1 review (6 patches) + Pack 2B design (file 19) Scope: 1 IU row + 1 UV row trong 1 transaction. Verify birth fire. HARD STOP.


§0. Mission

Tạo đúng 1 pilot IU row + 1 unit_version row. Verify birth trigger fire. Upload report. HARD STOP.


§1. Connection

docker exec -i postgres psql -U directus -d directus

§2. Preflight — chạy TRƯỚC mọi mutation

2.1 Baselines

SELECT 'iu' AS tbl, count(*) FROM information_unit
UNION ALL SELECT 'uv', count(*) FROM unit_version
UNION ALL SELECT 'iu_birth', count(*) FROM birth_registry WHERE collection_name='information_unit'
UNION ALL SELECT 'uv_birth', count(*) FROM birth_registry WHERE collection_name='unit_version';

Expected: IU=0, IU_birth=0. UV và UV_birth capture baseline. Nếu IU hoặc IU_birth ≠ 0 → STOP, report anomaly.

2.2 Trigger exists

SELECT tgname FROM pg_trigger
WHERE tgrelid='information_unit'::regclass AND tgname='trg_birth_information_unit' AND NOT tgisinternal;

Expected: 1 row. Nếu 0 → STOP.

2.3 Audit baselines

SELECT md5(pg_get_functiondef('fn_birth_registry_auto'::regproc)) AS fn_hash;
SELECT count(*) AS birth_trigger_count FROM pg_trigger WHERE tgname LIKE 'trg_birth_%' AND NOT tgisinternal;
SELECT count(*) AS total_birth_count FROM birth_registry;

Ghi nhận fn_hash, birth_trigger_count, total_birth_count. Dùng so sánh sau INSERT.

2.4 Vocab values — QUAN TRỌNG

SELECT key, value,
       CASE
         WHEN key LIKE 'vocab.unit_kind.%' THEN replace(key, 'vocab.unit_kind.', '')
         WHEN key LIKE 'vocab.section_type.%' THEN replace(key, 'vocab.section_type.', '')
         WHEN key LIKE 'vocab.publication_type.%' THEN replace(key, 'vocab.publication_type.', '')
       END AS vocab_token
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 phải dùng vocab_token (key suffix) cho unit_kindprimary_section_type_ref. Không dùng value column. Không tự tạo vocab.

2.5 Canonical address absent

SELECT count(*) FROM information_unit WHERE canonical_address='pilot.iu0.test-001';

Expected: 0. Nếu non-zero → STOP. Không tự tăng số.

2.6 Hash function availability

SELECT to_regprocedure('digest(text,text)') AS digest_text,
       to_regprocedure('digest(bytea,text)') AS digest_bytea,
       to_regprocedure('sha256(bytea)') AS sha256_bytea;

Ưu tiên dùng:

  1. encode(digest(v_body, 'sha256'), 'hex') nếu digest
  2. encode(sha256(v_body::bytea), 'hex') nếu chỉ có sha256(bytea)
  3. Nếu không có function nào → STOP, report. Không dùng md5 thay thế.

§3. Execute — single transaction

Thay <UNIT_KIND><SECTION_TYPE> bằng giá trị thật từ §2.4.

BEGIN;
SET CONSTRAINTS ALL DEFERRED;

-- Step 1: Generate UUIDs
DO $$
DECLARE
  v_iu_id uuid := gen_random_uuid();
  v_uv_id uuid := gen_random_uuid();
  v_body text := 'Pilot content for information unit test 001. This is a controlled test row created by Pack 2B-P1.';
  v_hash text;
BEGIN
  -- Compute content_hash from body (dùng function từ §2.6 preflight)
  -- Nếu digest() có: v_hash := encode(digest(v_body, 'sha256'), 'hex');
  -- Nếu sha256() có: v_hash := encode(sha256(v_body::bytea), 'hex');
  v_hash := encode(digest(v_body, 'sha256'), 'hex');  -- ADJUST theo §2.6 result

  -- Step 2: INSERT information_unit
  INSERT INTO information_unit (
    id, canonical_address, unit_kind, owner_ref,
    created_by, updated_by, identity_profile
  ) VALUES (
    v_iu_id,
    'pilot.iu0.test-001',
    '<UNIT_KIND>',
    'pilot.owner.iu0',
    'agent:p2b-p1',
    'agent:p2b-p1',
    jsonb_build_object(
      'title', 'Pilot IU Test 001',
      'owner_lookup_ref', 'pilot.owner.iu0',
      'primary_section_type_ref', '<SECTION_TYPE>'
    )
  );

  -- Step 3: INSERT unit_version
  INSERT INTO unit_version (
    id, unit_id, body, content_hash, version_seq, created_by
  ) VALUES (
    v_uv_id,
    v_iu_id,
    v_body,
    v_hash,
    1,
    'agent:p2b-p1'
  );

  -- Step 4: UPDATE anchors
  UPDATE information_unit
  SET version_anchor_ref = v_uv_id,
      content_anchor_ref = v_uv_id::text
  WHERE id = v_iu_id;

  -- Step 5: Pre-commit sanity check (L2 fires at COMMIT, this is extra safety)
  PERFORM 1 FROM information_unit WHERE id = v_iu_id AND version_anchor_ref = v_uv_id;
  IF NOT FOUND THEN RAISE EXCEPTION 'Pre-commit: anchor link failed'; END IF;

  PERFORM 1 FROM unit_version WHERE id = v_uv_id AND unit_id = v_iu_id;
  IF NOT FOUND THEN RAISE EXCEPTION 'Pre-commit: UV link failed'; END IF;

  -- Output IDs for post-verify
  RAISE NOTICE 'IU_ID=%', v_iu_id;
  RAISE NOTICE 'UV_ID=%', v_uv_id;
  RAISE NOTICE 'CONTENT_HASH=%', v_hash;
END $$;

COMMIT;

Nếu transaction FAIL → no state persists. Ghi nguyên error vào report. STOP. Nếu COMMIT success nhưng post-verify fail → STOP ngay. Upload state snapshot + cleanup draft. Không insert lần 2, không sửa tay, không cleanup tự động.


§4. Post-verify — chạy SAU COMMIT thành công

4.1 IU row exists

SELECT id, canonical_address, unit_kind, owner_ref, lifecycle_status,
       conformance_status, version_anchor_ref, content_anchor_ref,
       identity_profile, created_by
FROM information_unit
WHERE canonical_address = 'pilot.iu0.test-001';

4.2 UV row linked

SELECT uv.id, uv.unit_id, uv.body, uv.content_hash, uv.version_seq, uv.lifecycle_status
FROM unit_version uv
JOIN information_unit iu ON uv.unit_id = iu.id
WHERE iu.canonical_address = 'pilot.iu0.test-001';

4.3 Birth fire verification

SELECT entity_code, collection_name, born_at, created_at
FROM birth_registry
WHERE collection_name = 'information_unit'
ORDER BY born_at DESC LIMIT 5;

4.3b Birth entity_code join verify (chứng minh IU id thật khớp birth row)

SELECT iu.id,
       br.entity_code,
       ('information_unit::' || iu.id::text) AS expected_entity_code,
       br.entity_code = ('information_unit::' || iu.id::text) AS entity_code_ok
FROM information_unit iu
JOIN birth_registry br
  ON br.collection_name='information_unit'
 AND br.entity_code = 'information_unit::' || iu.id::text
WHERE iu.canonical_address='pilot.iu0.test-001';

Expected: exactly 1 row, entity_code_ok = true.

4.4 UV birth check (subordinate = no birth)

SELECT count(*) AS uv_birth_count
FROM birth_registry WHERE collection_name = 'unit_version';

Expected: 0 (UV is subordinate, no birth trigger).

4.5 Invariants unchanged

SELECT md5(pg_get_functiondef('fn_birth_registry_auto'::regproc)) AS fn_hash;
SELECT count(*) AS birth_trigger_count FROM pg_trigger WHERE tgname LIKE 'trg_birth_%' AND NOT tgisinternal;

So sánh với baselines §2.3:

  • fn_hash PHẢI giống
  • birth_trigger_count PHẢI giống (31)

4.6 Counts delta

SELECT 'iu' AS tbl, count(*) FROM information_unit
UNION ALL SELECT 'uv', count(*) FROM unit_version
UNION ALL SELECT 'iu_birth', count(*) FROM birth_registry WHERE collection_name='information_unit'
UNION ALL SELECT 'uv_birth', count(*) FROM birth_registry WHERE collection_name='unit_version'
UNION ALL SELECT 'total_birth', count(*) FROM birth_registry;

Expected deltas vs baselines:

  • IU: 0→1 (hard invariant)
  • UV: baseline→baseline+1 (hard invariant)
  • IU_birth: 0→1 (hard invariant)
  • UV_birth: unchanged (hard invariant)
  • total_birth: capture, audit/drift only — KHÔNG dùng làm hard gate

§5. Report format

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

Report sections:

  1. Preflight results — baselines, vocab values chọn, canonical check
  2. Transaction result — SUCCESS hoặc FAIL + error
  3. IU row snapshot — full row
  4. UV row snapshot — full row
  5. Birth registry snapshot — entity_code, born_at
  6. Invariant comparison — fn_hash before/after, trigger count before/after
  7. Counts delta table — before/after cho mỗi bảng
  8. Pass/Fail summary — checklist:
    • IU row exists with correct canonical_address
    • UV row exists with unit_id = IU.id
    • IU.version_anchor_ref = UV.id
    • IU.content_anchor_ref = UV.id::text
    • Birth registry has 1 new row for information_unit
    • entity_code = information_unit::<iu_uuid>
    • UV birth count unchanged
    • fn_hash unchanged
    • birth_trigger_count unchanged
  9. Cleanup SQL draft (chỉ draft, KHÔNG execute):
-- CLEANUP (DO NOT RUN unless approved)
BEGIN;

UPDATE information_unit
SET version_anchor_ref=NULL, content_anchor_ref=NULL
WHERE canonical_address='pilot.iu0.test-001';

DELETE FROM unit_version
WHERE unit_id IN (
  SELECT id FROM information_unit WHERE canonical_address='pilot.iu0.test-001'
);

DELETE FROM birth_registry
WHERE collection_name='information_unit'
  AND entity_code IN (
    SELECT 'information_unit::' || id::text
    FROM information_unit
    WHERE canonical_address='pilot.iu0.test-001'
  );

DELETE FROM information_unit
WHERE canonical_address='pilot.iu0.test-001';

COMMIT;
  1. Hard-stop confirmation: "P2B-P1 COMPLETE. HARD STOP. Chờ GPT/User review."

§6. Hard boundaries — TUYỆT ĐỐI

  • ❌ NO schema changes (no ALTER, no CREATE)
  • ❌ NO trigger/function changes
  • ❌ NO DOT-119 changes
  • ❌ NO raw birth_registry insert
  • ❌ NO unit_version birth trigger creation
  • ❌ NO Pack 2C/vector/outbox/Qdrant
  • ❌ NO Directus exposure
  • ❌ NO P3/HC
  • ❌ NO cleanup execution (draft only)
  • ❌ NO second IU row — chỉ 1 pilot row
  • ❌ NO vocab creation — dùng vocab có sẵn

Nếu bất kỳ bước nào fail → ghi nguyên lỗi, STOP. Không tự sửa.


§7. Sau report

Upload report → DỪNG. Không tạo IU row thứ 2. Không cleanup. Không tiếp Pack 2C. Chờ review.


P2B-P1 prompt rev2 | 2026-05-05 | Opus 4.6 + GPT review 6 patches | 1 IU + 1 UV pilot. Birth fire verify. HARD STOP.

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