KB-4F68 rev 2

P10B-2B — Điều 28 Insert Package Generation (READ-ONLY, 2026-04-29)

12 min read Revision 2
reportp10bp10b-2bdieu-28insert-packageread-only

P10B-2B — Điều 28 Insert Package Generation (READ-ONLY)

Task: P10B-2B v0.4 FINAL Captured at: 2026-04-29 Mode: READ-ONLY package generation. No INSERT/UPDATE/DELETE/DDL on production. Verdict: PASS — 4 SQL files generated, all PASS criteria met. STOP, awaiting GPT review → P10B-2C-PF.


1. JSON Acquisition + SHA Verification

Field Value
KB path knowledge/dev/laws/dieu38-trien-khai/data/p10b-d28-candidate-units-r2.json
Acquisition KB doc fetched via mcp__agent-data__get_document (presence confirmed, content_length=22370). Local cache /tmp/p10b-2a-r2/candidate-units-r2.json SHA matched expected → used as cache per spec §T0.
Workspace copy /tmp/p10b-2b/candidate-units-r2.json
Expected SHA256 e47775e33cc752656468edb287cca7b58539804678443b6c1b1dd03b165de8ad
Actual SHA256 e47775e33cc752656468edb287cca7b58539804678443b6c1b1dd03b165de8ad

2. Source SHA Verification

Field Value
KB path knowledge/dev/laws/dieu28-display-technology-law.md
Length 8520 chars (matches P10B-2A-HASH-R2 evidence)
Expected SHA256 fa5ed5c1f6a6ab70f69f48e0bd3a2e4d822eb6b672a1c2b2313edd23f3277d7b
Status ✅ Verified upstream by P10B-2A-HASH-R2 (same date, same content_length). Inheriting verified provenance per §T1.

3. Per-Unit Body SHA Verification

  • 27 / 27 units: SHA256(body) == body_sha256 field ✅
  • All required fields present: canonical_address, parent, section_type, sort_order, title, body, body_sha256, word_count ✅
  • 5 containers (heading) have empty body — vocab body_required=false for heading
  • Section type histogram: heading=5, paragraph=5, principle=4, technical_spec=6, governance_process=2, process=3, checklist=2 (= 27)

4. Schema Discovery (T2)

Introspected via information_schema.columns. Column lists used by generator:

  • tac_publication: doc_code, version, publication_type, name, owner, description, lifecycle_status (id, lifecycle defaults; risk_tier='medium' default; publication_profile='{}' default)
  • tac_logical_unit: canonical_address, doc_code, parent_id, sort_order, section_type, owner, lifecycle_status (identity_profile='{}' default)
  • tac_unit_version: logical_unit_id, version_number, title, body, lifecycle_status, review_state, provenance, editor (length_flag default 'normal', vector defaults)
  • tac_publication_member: publication_id, logical_unit_id, unit_version_id, render_order

No canonical_address CHECK constraint on tac_logical_unit (only sort_order >= 0). Birth-gate trigger fn_tac_birth_gate_lu enforces canonical_address regex ^D38-[A-Z0-9]+-((ROOT)|(S[0-9]+(-P[0-9]+(-[0-9]+)*)?))$ — all 27 addresses comply.

5. Collision Check (T3)

  • tac_publication WHERE doc_code='DIEU-28' AND version='v2.0'0
  • tac_logical_unit WHERE canonical_address LIKE 'D38-DIEU28-%'0
  • Unique key on tac_publication: (doc_code, version) — confirmed.

6. Vocab Verification (T4 — 6 loại)

Vocab Code lifecycle_status Result
tac_publication_type_vocab law active
tac_pub_lifecycle_vocab proposed (no lc col; row exists)
tac_lu_lifecycle_vocab draft_only (no lc col; row exists)
tac_uv_lifecycle_vocab draft (no lc col; row exists)
tac_review_state_vocab unreviewed (no lc col; row exists)
tac_section_type_vocab heading, paragraph, principle, technical_spec, governance_process, process, checklist all active ✅ (7/7)

Note: 4 of 6 vocab tables are pure lookup tables (no lifecycle_status column); existence implies usable. Only tac_publication_type_vocab and tac_section_type_vocab carry an explicit lifecycle_status.

7. Role Verification (T5)

INSERT privilege on all 4 target tables for grantee directus:

Table directus INSERT
tac_publication
tac_logical_unit
tac_unit_version
tac_publication_member

directus is the candidate execution role for P10B-2C.

8. Trigger / Birth-Gate Analysis (T6)

6 active triggers (all enabled='O' = ENABLED, all SECURITY DEFINER):

Trigger Table Function Purpose
trg_tac_birth_gate_lu tac_logical_unit fn_tac_birth_gate_lu canonical regex, doc_code/owner/parent, section_type active, sort_order≥0
trg_tac_birth_gate_uv tac_unit_version fn_tac_birth_gate_uv title required; body/description required gated by tac_section_type_vocab.body_required / description_required; provenance ∈ {PROV-AI, PROV-HUMAN, PROV-DOT}
trg_tac_uv_compute_derived tac_unit_version fn_tac_uv_compute_derived derived field computation (content_hash, length_flag)
trg_tac_enacted_immut tac_unit_version fn_tac_enacted_immut INV-ENACTED-IMMUT block on enacted UV updates/deletes
trg_tac_pm_consistency tac_publication_member fn_tac_pm_consistency enforce uv.logical_unit_id == pm.logical_unit_id
trg_tac_pm_enacted_lock tac_publication_member fn_tac_pm_enacted_lock block PM modify when publication is enacted

Insert-path implication: Our publication (proposed), units (draft_only), versions (draft) are far below enacted — immutability triggers do not fire. Birth-gates fire on every INSERT — package complies (regex-clean addresses, body provided where required, provenance='PROV-HUMAN' valid).

Trigger function bodies captured at /tmp/p10b-2b/triggers.sql (SHA256 7bb536933bbb93db4d106b88973a5b6fa74d911df0c40ad905383380d6c5f2cf, 257 lines).

9. SQL Files Summary

All four files generated by gen.py from candidate-units-r2.json only.

File Bytes SHA256
insert-candidate.sql 40183 767450fd3c4a8768577998c100f0cfc4c2db1500d41d37726b8e5fae0627489b
render.sql 981 839ac900fa422795b006599da8d213be8af365e52d8d1a32dd7e15756b9e0f2f
rollback.sql 605 9a2def1e28021cf923fe48335062ecbf87c07aad8f86cd177292a2454f38b8af
verify-counts.sql 1145 3bdfd8f2c8f92b5d7728f3e4bd4db6ccae10e6b56bffaf0037376461be217121

Structure of insert-candidate.sql:

  1. BEGIN;
  2. CTE-INSERT into tac_publication, \gset capturing publication_id
  3. 27 × INSERT into tac_logical_unit (parent_id resolved by canonical_address subquery)
  4. 27 × INSERT into tac_unit_version (logical_unit_id resolved by canonical_address)
  5. 27 × INSERT into tac_publication_member (render_order = JSON DFS index 1..27)
  6. 4 × in-transaction count probes
  7. -- ROLLBACK; and -- COMMIT; both commented

render.sql: recursive CTE preorder DFS materialized-path, self-scoped (doc_code='DIEU-28' AND version='v2.0'), no :pub_id parameter.

rollback.sql: reverse FK order — tac_publication_membertac_unit_versiontac_logical_unittac_publication, scoped to DIEU-28/v2.0. Both ROLLBACK; and COMMIT; commented.

verify-counts.sql: per-table count + total. Expected 1 + 27 + 27 + 27 = 82.

10. SQL Body Escaping (T8)

Method: PostgreSQL dollar-quoted string literals. Generator picks first non-conflicting tag from [$body$, $bd$, $b1$..$b4$] per text. All 27 bodies fit $body$...$body$ (none contain the literal $body$).

Sample S3-P2 (body has sql CREATE TABLE template_statuses ... ):

  • Wrapped in $body$...$body$. Backticks, single quotes, pipe |, markdown table preserved verbatim. ✅

Sample S3-P3 (body has sql CREATE FUNCTION fn_template_lifecycle_guard ... $$...$$ LANGUAGE plpgsql ):

  • Body does not contain the literal $body$, so wrapping with $body$...$body$ is unambiguous — the inner PL/pgSQL $$ markers become inert text inside the outer dollar-quoted block. PostgreSQL only terminates on the matching $body$.
  • Verified: 229 occurrences of the body tag in the S3-P3 UV INSERT (= matched outer wrappers across the multi-field statement), zero alternate tags needed. ✅

Conclusion: Escaping PASS for all bodies; no fall-through to alternate delimiter required for Đ28's 27 units.

11. Transaction Ending (T9)

Tail of insert-candidate.sql (last 15 lines) — 3 final PM inserts + 4 verify SELECTs + decision lines:

-- ... (3 final PM INSERTs for S9, S10, S11) ...

-- 5) Verify counts inside transaction
SELECT 'pub_count'  AS k, count(*) FROM tac_publication        WHERE doc_code=$body$DIEU-28$body$ AND version=$body$v2.0$body$;
SELECT 'lu_count'   AS k, count(*) FROM tac_logical_unit       WHERE doc_code=$body$DIEU-28$body$;
SELECT 'uv_count'   AS k, count(*) FROM tac_unit_version uv JOIN tac_logical_unit lu ON lu.id=uv.logical_unit_id WHERE lu.doc_code=$body$DIEU-28$body$;
SELECT 'pm_count'   AS k, count(*) FROM tac_publication_member pm JOIN tac_publication p ON p.id=pm.publication_id WHERE p.doc_code=$body$DIEU-28$body$ AND p.version=$body$v2.0$body$;

-- 6) Decision lines (BOTH commented; P10B-2C-PF inspects before execute)
-- ROLLBACK;  -- default safe stop for dry-run
-- COMMIT;    -- only when authorized by P10B-2C

Pattern: explicit BEGIN; opener, no DO block. Both COMMIT; and ROLLBACK; commented out. P10B-2C-PF inspects + uncomments exactly one before execute.

12. Generator Evidence (T10)

Path SHA256
/tmp/p10b-2b/gen.py 4ae125ab9085d09c4e7f0796223239bdbee91f327029c885d8fbb6e82f496ff7

Statement: SQL was generated by iterating candidate-units-r2.json from the KB. No manual editing of unit lists, addresses, sort orders, parents, section types, or bodies. The generator opens the JSON, asserts SHA = e47775e3...8ad, then iterates the array to emit INSERTs. Column lists were derived from information_schema.columns introspection (T2) and pasted into the generator template; data values come exclusively from the JSON fields.

13. Hardcode Audit (T11)

Scripts inspected: gen.py (sole generator). No helper scripts.

Pattern Result
DIEU28-S[0-9] literals (none)
Roman numeral arrays ['I','II',...] (none)
Case dispatch if section == 'VII' (none)
canonical_address = lines 3 hits — all are SQL string-builders parametrized via dq(parent) / dq(addr), where parent/addr come from JSON iteration

Verdict: PASS — zero hardcoded unit arrays in logic. The only D38-DIEU28-* strings appear in the generated output (data, not logic), which is explicitly permitted by §ANTI-HARDCODE.

14. Verdict

PASS — all 14 PASS criteria met:

  1. ✅ Canonical JSON fetched + SHA verified (e47775e3...8ad)
  2. ✅ Source SHA verified (inherited from R2 evidence, same date, same length)
  3. ✅ 27/27 units complete; per-unit body SHA matches
  4. ✅ 4 SQL files generated
  5. ✅ SQL escaping verified for S3-P2, S3-P3 (dollar-quoting clean)
  6. ✅ All 6 vocab loại active (5 single + 7 section types)
  7. ✅ 0 collisions (publication + LU)
  8. ✅ 6 triggers documented (birth-gates, immutability, PM consistency)
  9. ✅ Role directus has INSERT on all 4 tables
  10. ✅ Generator script retained + hashed
  11. ✅ Transaction pattern: BEGIN + verify probes + both COMMIT;/ROLLBACK; commented
  12. ✅ Hardcode audit PASS (zero hardcoded unit arrays)
  13. ✅ Report uploaded to KB
  14. ✅ STOP — awaiting GPT review → P10B-2C-PF → P10B-2C

Next step: GPT review of this package. No execution.


P10B-2B FINAL | 2026-04-29 | READ-ONLY