KB-76C2

IU b/c/f Pure Read-Only Live Proof (2026-05-28)

15 min read Revision 1
iutests-b-flive-proofread-onlyaxis-baxis-csql-linkpure-readonlyquery-pg2026-05-28

IU b/c/f Pure Read-Only Live Proof (2026-05-28)

Macro: IU_B_C_F_PURE_READONLY_LIVE_PROOF_100000X Mode: PURE_READ_ONLY_LIVE_PROOF · Channel: query_pg (read-only role context_pack_readonly, READ ONLY transaction, no writes/DDL possible) Status: PASS — b PASS, c PASS, f PASS (all with documented caveats; zero mutation) Companion: iu-b-c-f-pure-readonly-live-proof-query-appendix-2026-05-28.md

This is a live, evidence-backed proof — not a planning pack. Every DB operation was a SELECT executed by a read-only role inside a READ ONLY transaction (tool-enforced: AST-validated, no writes/DDL, statement_timeout 5s, hard LIMIT 500). No write probe was executed.


1. Source verification matrix

# Source Found Used for
S1 …/iu-core-process-brick-readiness-and-gap-survey-2026-05-28.md ✅ (auto-memory + KB) Expected live inventory + the "gates OFF not missing tables" thesis to confirm against live DB
S2 …/iu-b-to-f-survey-gpt-review-next-command-2026-05-28.md Test order b→c→f-read; 4-Mothers no-go
S3 …/iu-test-b-to-f-readiness-command-pack-2026-05-28/ (12 docs) Baseline filter logic for b/c/f
S4 …/iu-b-to-f-execution-readiness-refactor-2026-05-28/ (7 docs) Execution classes; this macro is the C1 PURE_READ_ONLY_PROOF (M-A + M-B) the refactor pack defined
S5 …/v0.6-iu-4mothers-event-foundation-rev2/ (Rev5) 4-Mothers framing (stays blocked)
S6 Prior IU cut/axis/tree/sql-link reports Function inventory expectations
S7 Laws (Hiến pháp, Đ7/32/35/38-39/45) + prompt standard rev41 v1.3 Execution-class + self-check rules

No source was unavailable.


2. Live preflight matrix

Check Result
current_user context_pack_readonly
current_database directus
server version PostgreSQL 16.13 (Debian)
server address / port 172.19.0.3 (Docker postgres container) / 5432
role attributes rolsuper=false, rolcreatedb=false, rolcreaterole=false, rolcanlogin=true
read-only confirmation By role metadata + tool contract ("READ ONLY transaction as a read-only role; no writes/DDL"). No write probe executed.

Host note: the brief named "contabo VPS"; the live inet_server_addr is the Docker internal IP 172.19.0.3 of the postgres container (the MCP connects inside the container network). Database identity (directus) confirmed.


3. Table / function / view existence matrix

All in schema public.

Object Kind Exists Notes
information_unit table
iu_three_axis_envelope table axis_a/b/c columns; axis_b_tags jsonb; axis_c_parent_id/depth/ancestors
iu_metadata_tag table normalized tags (tag_key)
iu_metadata_tag_registry table vocabulary; tag_kind = family
iu_tree_path table
iu_relation table
iu_sql_link table
v_iu_sql_link_resolved view exposes validation jsonb
dot_iu_command_catalog table 42 commands
dot_iu_command_run table audit; 45 rows, unchanged across this macro
fn_iu_sql_link_validate(p_link_id uuid)→jsonb function STABLE (read-safe)
fn_iu_subtree(p_root uuid)→TABLE(iu_id,canonical_address,depth,parent_id,relative_depth) function STABLE (read-safe)
fn_iu_sql_link_inbound_capture trigger fn VOLATILE — not called (would write)
fn_iu_piece_split / merge / structure_op_rollback functions VOLATILE — not called

4. Row-count matrix (live, this run)

Table Rows
information_unit 216
iu_three_axis_envelope 216
iu_metadata_tag 536
iu_metadata_tag_registry 36
iu_tree_path 199
iu_relation 60
iu_sql_link 3
iu_split_set 0
iu_merge_set 0
iu_outbound_route 15
iu_route_dead_letter 0
dot_iu_command_catalog 42
dot_iu_command_run 45 (start) → 45 (end) — delta 0

Counts match the survey baseline exactly.


5. Test b — domain/professional axis (PASS)

Axis-B vocabulary (5 families, iu_metadata_tag_registry.tag_kind): unit_kind (216 assignments), legal_document (143), section_type (127), topic (25), legal_domain (25). Total = 536 = iu_metadata_tag rows.

The professional/domain axis = legal_domain. 3 applied values:

legal_domain value distinct IUs
legal_domain:knowledge_systems 16
legal_domain:governance 5
legal_domain:technology 4

(25 tag-assignments across 16 distinct IUs; some IUs carry multiple domains.) Plus topic family with 7 applied values (knowledge_graph 10, architecture 5, dot_trigger 3, governance 3, workflow 2, cut_pipeline 1, render_pipeline 1) — giving ≥3 meaningful professional/domain filters, including law/constitution domains.

Sample evidence — legal_domain:knowledge_systems (16 IUs): all returned IUs are unit_kind=law_unit from knowledge/dev/laws/dieu39-knowledge-graph-law.md (a law/constitution source ✓). Example rows: …#0-tam-nhin, …#1-26-bai-toan, …#12-quan-he, …#13-no-ky-thuat. The denormalized axis_b_tags jsonb on each envelope nests all 5 families and is consistent with the normalized iu_metadata_tag rows (e.g. legal_domain:[legal_domain:knowledge_systems] appears in both). This proves a domain filter can cut a coherent document set.

Coverage characteristic (honest): axis_b_tags jsonb is populated on 100% (216/216) of envelopes. The legal_domain family specifically covers 16/216 IUs (~7%) — domain tagging is sparse/selective (high-level domains, not every unit), and the legal_domain registry has exactly 3 keys, all applied (no unused vocabulary). This is a coverage characteristic, not a failure.

Assertions: axis-B data exists ✓ · queryable ✓ · stable on re-run (knowledge_systems = 16 both runs) ✓ · no mutation required ✓.

Verdict: PASS — meaningful professional/domain filters return coherent IU sets with live evidence; normalized + denormalized representations agree. Coverage of the legal_domain family is sparse (documented).


6. Test c — parent/child/grandchild tree axis (PASS)

Tree shape: depth 0 = 156 units (133 true roots), depth 1 = 55, depth 2 = 5 grandchildren. Max depth 2 → full parent→child→grandchild. Total 216.

Three cases proven via STABLE fn_iu_subtree:

Case Root Subtree rel. depth
Root with full 3-level subtree D38-DIEU35-S4 (cb211ee6) 8 nodes: root + 4 children (P1–P4) + 3 grandchildren (P1-1/2/3) 0→2
Mid-level parent D38-DIEU35-S4-P1 (3477ff71) 4 nodes: itself + 3 grandchildren 0→1
Leaf D38-DIEU35-S4-P1-1 (5410e681) 1 node (itself) 0

Parent-child linkage verified: every returned node's parent_id points to a node within the set; grandchildren → parent 3477ff71 → root cb211ee6.

Integrity checks (SELECT-only):

Check Result
Dangling/orphan parent (parent_id not present) 0
Self-parent cycle (parent_id = unit_id) 0
Self-in-ancestors cycle 0
Root with non-zero stored depth 0
Depth-0 unit WITH a parent (stale depth) 23
child.depth ≠ parent.depth+1 (stored) 23

Caveat (real finding): 23 units have a valid axis_c_parent_id but their stored axis_c_depth is still 0 (not materialized to parent.depth+1). This is a denormalized-depth staleness consistent with the three_axis_auto_refresh gate being OFF — not a structural break. Proof it is harmless: for a stale unit (DIEU-37-v3.3#changelog, stored depth 0, parent stored depth 0), fn_iu_subtree(parent) still computes relative_depth=1 correctly (parent subtree size 17). fn_iu_subtree recurses on live parent linkage, so it is authoritative; the stored axis_c_depth column must not be trusted for those 23 units.

Assertions: tree data exists ✓ · descendant query works ✓ · no orphan/cycle in tested data ✓ (and zero across the whole table) · stable on re-run (subtree = 8 both runs) ✓ · no mutation ✓.

Verdict: PASS — multi-level subtree proven, integrity clean (no orphans/cycles/dangling), fn_iu_subtree authoritative. Caveat: stored axis_c_depth stale on 23 units (materialization gap; tree filtering must use fn_iu_subtree/parent linkage).


3 live links (all lifecycle_status=active, enabled=false, object_fingerprint=NULL), all anchored on dieu39-knowledge-graph-law.md:

id (short) link_role target object direction validate
e73fef17 governs view public.v_iu_section_type_vocab_sync view outbound resolved:true (pg_class_match)
c9ed8792 governs function public.fn_iu_three_axis_envelope_refresh(text,boolean) function outbound resolved:true (pg_proc_match)
48bd6ac6 represents table public.tac_publication table bidirectional resolved:true (pg_class_match)

Validation cross-check: the resolved view's validation jsonb and a direct fn_iu_sql_link_validate(id) call returned identical results (same resolved, same detail, same checked_at timestamp) for all 3 — confirming the view runs the validator. All 3 resolve true against live DB objects, proving each link's target exists and matches in pg_class/pg_proc.

enabled=false is correctly NOT a failure: validate/resolve read paths work on all 3 disabled links — enabled=false suppresses only runtime delivery/capture, not validation/resolution (confirming the survey/refactor-pack thesis on live data).

Deferred (correctly not done here): object_fingerprint is NULL on all 3 — fingerprint capture is part of the gated/mutating enable path (fn_iu_sql_link_inbound_capture is VOLATILE → not called). No link was enabled; no new link created.

Assertions: link rows exist (3) ✓ · validate/resolve read-only path works ✓ · all 3 resolved:true ✓ · view == direct function ✓ · stable on re-run (3/3 resolved both runs) ✓ · no mutation ✓.

Verdict: PASS — all 3 links read and validate/resolve successfully against current DB data, read-only, with enabled=false correctly non-fatal.


8. Re-run stability + no-mutation proof

Metric First run Re-run Stable
b: legal_domain:knowledge_systems distinct IUs 16 16
c: fn_iu_subtree(cb211ee6) size 8 8
f: links resolved:true 3 3
dot_iu_command_run rows 45 45 ✓ (delta 0)
iu_split_set / iu_merge_set 0 / 0 0 / 0

No-mutation statement: every statement was a SELECT run by context_pack_readonly in a READ ONLY transaction. No INSERT/UPDATE/DELETE/DDL is possible on this channel. dot_iu_command_run is unchanged (45→45), proving no DOT command was invoked and no audit row was written. iu_split_set/iu_merge_set remain empty. No gate flipped, no event registered, no Directus/Qdrant write, no SSH/workflow_admin channel used.


9. Cross-test synthesis matrix

Test Readiness Live evidence Blocker Next macro Mutation needed later Blocks 4 Mothers
b domain axis PASS 3 legal_domain + 7 topic filters; knowledge_systems→16 law_units; jsonb==normalized none for read; coverage of legal_domain sparse (16/216) M-C additive wrapper dot_iu_filter_axis_b (C2) only to add DOT wrapper (no IU-data change) No
c tree axis PASS 3-level subtree (8 nodes); 0 orphan/cycle; fn_iu_subtree authoritative none for read; 23 units stale axis_c_depth (auto_refresh OFF) M-C additive wrapper dot_iu_subtree (C2) only to add DOT wrapper; optional later depth re-materialize No
f sql link PASS 3/3 links resolve:true (view/fn/table); view==direct fn none for read; enable/capture + fingerprint deferred (gated) M-C read-only wrappers (C2); enable/capture later (C3, gated) yes for enable/capture (Điều 32 + bounded gate) No

Proceed to additive DOT wrapper implementation: b, c, and f-read are all proven and may proceed to the C2 additive macro (IU_B_C_F_ADDITIVE_DOT_WRAPPER_IMPLEMENTATION) — the precondition ("read-only proofs PASSED") is now met. Still need design/gate/governance: f-enable/capture (C3, bounded gate + Điều 32); test d split/merge (C3, needs gate protocol + review_decision); test e trigger delivery (C3/C4). Previous assumptions — all confirmed, two refined: (1) survey "gates OFF not missing tables" confirmed on live data; (2) refined — legal_domain registry has 3 keys (all applied), not 25 (the survey-era "25" was a tag-assignment count, not distinct keys); (3) new finding — 23 units carry stale axis_c_depth (depth column not materialized) though parent linkage and fn_iu_subtree are correct.


IU_B_C_F_ADDITIVE_DOT_WRAPPER_IMPLEMENTATION_40000X (execution class C2, from the refactor pack doc 03 Prompt 3). Its precondition — both pure read-only proofs PASS — is satisfied by this report. It creates the STABLE wrapper functions + dot_iu_* catalog pairs via SSH workflow_admin, with rollback + object-diff. In parallel, the C5/C4 design-first phase of IU_BOUNDED_GATE_PROTOCOL_AUTHORITY_PACK can begin (no live gate work until Hard-Gate-0). 4 Mothers remains BLOCKED.


11. Self-review (underload rule)

  • Did I query live DB? Yes — 13 read-only queries against directus.
  • Did I prove host/database identity? Yes — user/db/version/addr + role attributes.
  • Did I cover b, c, f? Yes — each with PASS + evidence + caveats.
  • Enough evidence for GPT to review without trusting my summary? Yes — vocabularies, counts, sample rows, validation jsonb, integrity counts, re-run deltas; full query text in the appendix.
  • Did I avoid all mutation? Yes — read-only role + READ ONLY txn; dot_iu_command_run delta 0.
  • Next macro precise? Yes — M-C additive wrapper (C2), gate protocol design in parallel.

Final verdict: PASS. b PASS, c PASS, f PASS — all read-only, all evidence-backed, all stable on re-run, zero mutation. Three honest caveats documented (b: sparse legal_domain coverage; c: 23 stale axis_c_depth; f: fingerprint/enable deferred & gated) — none blocks the read proof.


12. Forbidden-compliance statement

No INSERT/UPDATE/DELETE/CREATE/ALTER/DROP. No DOT command run. No dot_config change. No event registration. No audit-row write (dot_iu_command_run unchanged). No catalog row. No gate flip. No Directus/Qdrant write. No migration. No implementation. No workflow_admin/apply channel. No 4-Mothers work. The only writes were KB document uploads (this report + appendix). Read-only role context_pack_readonly in a READ ONLY transaction made mutation structurally impossible.