01 — Live Substrate Audit (read-only, 2026-06-02): what exists, what's missing, exact gaps
01 — Live Substrate Audit (read-only, 2026-06-02)
Branch A. Mutation footprint: ZERO — every fact below comes from
query_pg(AST-validated READ ONLY role) andinformation_schema/pg_classintrospection on databasedirectus. No write channel touched. Verdict: the substrate is far richer than "topic lives nowhere." The real gaps are four: (G1) no technical build-authorization substrate; (G2) no Axis Registry (M-DEF-9) generalizing facets; (G3) the assignment layer lacks confidence/evidence/lifecycle for semantic axes; (G4)iu_three_axis_envelopehardcodes 3 axes — but only as a projection. NĐ-36-01's soft-relation substrate (entity_relationset al.) is decreed but not built.
01.1 Existence matrix (live, 2026-06-02)
Exists (relevant to this mission):
| Group | Tables / views (live) |
|---|---|
| IU core | information_unit (219), unit_version (182), iu_relation (60), iu_tree_path, iu_tree_change_log, iu_lifecycle_log, iu_lifecycle_vocab, iu_gate_transition |
| IU axis projection | iu_three_axis_envelope (216) + _refresh_log + _trigger_error_log + v_iu_three_axis_envelope_drift + v_iu_three_axis_envelope_refresh_status + v_ui_iu_three_axis_envelope |
| IU structure ops | iu_structure_operation, iu_merge_set, iu_split_set, iu_piece_collection, iu_piece_membership |
| IU draft/edit | unit_edit_draft, doc_reviews, tac_review_state_vocab |
| IU tagging | iu_metadata_tag, iu_metadata_tag_registry |
| Taxonomy / labels | taxonomy (58), taxonomy_facets (10), taxonomy_matrix, label_rules (37), entity_labels (~771,481) |
| KG / edges | universal_edges (~2,199), v_kg_edges_all, kg_acl_config, kg_auto_approve_rules, kg_constraint_config, kg_signal_config, kg_source_authority, kg_thresholds, kg_priority_templates, kg_quality_log, kg_quality_issues (v), kg_quality_latest (v), kg_evolution_latest (v) |
| Pivot axis | pivot_definitions (Điều 26 mechanics) |
| Approval spine | approval_requests (211), apr_action_types (6), apr_approvals (42) |
| Sales/deal proposal e-sign | os_proposals, os_proposal_blocks, os_proposal_contacts, os_proposal_approvals (0), os_deal_stages, table_proposals |
| Governance | governance_registry (9), governance_relations (8), normative_relations, directus_relations |
| Coverage / catalogs | collection_registry (166, coverage_* columns), meta_catalog (169), derived_objects_registry, registry_changelog (~67,328) |
| Events / issues | event_type_registry (40), event_outbox (~175,588), system_issues (~195,633) |
| Workflow | workflow_categories (3), workflow_step_relations |
Absent (verified this run — does NOT exist live): entity_relations, abbreviation_dict, disambiguation_log, entity_embeddings, axis_registry, iu_axis_value, governance_build_authorization, governance_object_ownership, governance_responsibility_scope, governance_candidate_state, species/species_registry (under those names). I.e. the NĐ-36-01 soft-relation substrate, the Axis Registry, the build-auth substrate, and the SB-2/SB-10 governance substrates are all paper-only / unbuilt.
01.2 The axis / IU substrate (what topic, reconstruction, containment use today)
information_unit (219). Columns: id uuid, canonical_address, unit_kind, lifecycle_status, content_anchor_ref, version_anchor_ref uuid, owner_ref (free text), parent_or_container_ref uuid, conformance_status, identity_profile jsonb, doc_code, section_type, section_code, sort_order, …. Live distributions:
unit_kind: law_unit 187, design_doc_section 32 — only 2 of 9 seed kinds populated.conformance_status: 'open' for all 219 — governance conformance is never closed (pilot-grade; confirms the IU island has no central conformance gate).lifecycle_status: enacted 146, draft 58, deprecated 12, retired 3.- Built-in axis anchors:
parent_or_container_ref= primary containment parent (axis C);doc_code+section_code+sort_order= reconstruction / source order (axis A);owner_reffree-text = ungoverned ownership (OP-B blocker).
iu_relation (60). Rich, bitemporal, evidence-bearing: source_unit_id, target_unit_id, relation_type, relation_subtype, relation_status, operation_ref, source/target_version_id, metadata jsonb, valid_from/to, provenance jsonb, confidence numeric, evidence jsonb, assertion_mode, valid_time tstzrange. Live: all 60 rows relation_type='contains', status='active'. → Only the containment axis is populated; topic and reconstruction relations are not yet expressed here, even though the table is shaped to hold them with confidence/evidence/provenance.
iu_three_axis_envelope (216). Denormalized projection: axis_a_doc_code/sort_order/section_code (reconstruction), axis_b_tags jsonb / axis_b_tags_by_source jsonb (topic/semantic tag-bag), axis_c_parent_id/depth/ancestors[]/ancestor_addresses[] (containment), plus refreshed_at/by. This hardcodes exactly three axes (DDL-level), refreshed on a schedule — it is a read projection, not the axis model (confirmed by hardening doc 03 §3.2: "the headline three-axis is a denormalized envelope, not the closed set of IU axes; the live/implied IU axes are at least nine").
iu_tree_path. Materialized containment closure: unit_id, root_unit_id, parent_id, depth, path_ids[], path_addresses[], sibling_order, path_hash, valid_from/to. → The tree projection for reconstruction/containment, with sibling order and a path hash (drift detection) — bitemporal.
taxonomy (58) + taxonomy_facets (10) + taxonomy_matrix. This is already a generalized facet/axis-and-vocabulary system:
-
taxonomy_facetsrows = facets withcardinality (single|multiple),max_labels_per_entity,status. The 10 facets:code name cardinality max meaning FAC-01 Chuyên môn gì? multiple 3 professional/expertise FAC-02 Vai trò hệ thống? single 3 system role FAC-03 Hành động gì? multiple 3 action FAC-04 Phạm vi tác động? single 3 impact scope FAC-05 Giai đoạn? single 3 stage/phase FAC-06 Phục vụ ai? multiple 3 audience FAC-07 Thuộc tài liệu nào? single 0 which document (reconstruction/containment) FAC-08 Chủ đề nội dung? single 0 content TOPIC FAC-09 Tầng kiến trúc? single 0 architecture layer FAC-PROV Description Provenance single 1 provenance -
Topic already exists as a facet (FAC-08).
max_labels_per_entity=0⇒ defined but not operationalized for assignment. This is the single most important reuse finding: topic is not greenfield — it is an un-activated facet in the live taxonomy system. -
taxonomyrows =code, name, name_en, facet_id, parent_id, parent_facet, depth, description, scope[], status, replaced_by, sort, _dot_origin. → hierarchical (parent_id) DAG-capable (parent_facet) vocabulary with status lifecycle andreplaced_bysupersession (live: 57 active + 1 deprecated). This is the node store for semantic axes. -
taxonomy_matrix=facet_id, composition_level, requirement→ which facet is required at which composition level (a coverage rule already, in data).
entity_labels (~771,481) + label_rules (37). The assignment layer at scale: entity_labels(id, entity_code, label_code, assigned_by, rule_id, assigned_at); label_rules(id, name, facet_id, rule_type, condition jsonb, result_label, priority, skip_wide_warning, status). → Rule-driven auto-labeling already exists. Gap (G3): entity_labels has no confidence, no evidence, no status/zone, no valid_time, no provenance — it cannot hold an uncertain semantic assignment with the 3-zone (Approved/Candidate/Quarantine) discipline NĐ-36-01 §MT4 mandates.
iu_metadata_tag + iu_metadata_tag_registry. IU-scoped tagging with confidence: iu_metadata_tag(iu_id, tag_key, confidence numeric, enrichment_source, assigned_by, assigned_at); registry (tag_key, tag_kind, tag_label, derived_from_column, active). → Closer to the semantic-assignment shape (has confidence + source), but no evidence/zone/valid_time and is IU-only.
universal_edges (~2,199) + v_kg_edges_all. The live cross-collection graph (Điều 39 / NĐ-36-01 hard relations): source_collection/source_id/source_code/source_composition_level, target_*, edge_type, edge_subtype, weight, is_auto_managed, symmetry_group_id uuid, metadata jsonb, valid_from/to, status, confidence, valid_time tstzrange, provenance jsonb. Live edge types: USES 1486, BELONGS_TO 431, CONTAINS 282. → A fully evidence/confidence/provenance/bitemporal, auto-managed edge substrate spanning any collection by code/id. This is the canonical graph store; KG/Qdrant are projections of it (Điều 39 NT8, Đ38 §10).
kg_* config/quality family. kg_auto_approve_rules (Điều 39: "no rule = no auto = default human"), kg_source_authority (trust hierarchy: quy định > báo cáo > chat), kg_thresholds, kg_constraint_config, kg_acl_config, kg_signal_config, kg_priority_templates, kg_quality_log/kg_quality_issues(v)/kg_quality_latest(v). → A working KG governance + quality substrate, config-driven, no hardcode.
01.3 The proposal / review / draft / versioning substrate (Branch E inputs)
approval_requests(211). The governance proposal spine:code, request_type, entity_type, entity_code, title, current_state jsonb, proposed_action jsonb, alternative_actions jsonb, evidence, source, priority, status, reviewed_by/at, review_note, applied_at, action, target_collection, target_entity_code, source_context, issue_signature, request_type_code, proposed_action_code (→ apr_action_types). → Full propose→review→apply with proposed/alternative actions and an issue signature (coalescing). Live note (hardening doc 03 §3.1): 0 rows reference IU — the IU island does not use the central spine.apr_action_types(6) +apr_approvals(42) — see §01.4.unit_edit_draft. A Git-like content-edit/merge primitive:unit_id, base_version_ref, base_version_seq, base_content_hash, draft_title, draft_body, draft_content_hash, draft_status, created_by, applied_by/at, applied_version_ref, stale_at, reason, metadata. → base-version + content-hash = optimistic concurrency / 3-way-merge basis;applied_version_ref= merge target;stale_at= conflict detection. This is "proposal-as-edit" already in PG.iu_merge_set/iu_split_set. Ontology-change primitives with governance:merged_iu_id / source_iu_ids[],actor, review_decision_id, change_set_id, idempotency_key, reason, tool_revision, rolled_back_at/by/reason. → merge/split carry a review decision, a change set, idempotency, and rollback — exactly the topic merge/split workflow shape (Branch F).doc_reviews. Two-gate review:status, thread_title, source_doc_id, created_by, created_by_type, review_gate_1 jsonb, review_gate_2 jsonb, resolution jsonb, history jsonb. → human/AI two-gate review surface.tac_review_state_vocab. Text-as-Code review state vocabulary (Điều 38 review states).unit_version(182). Version history for IUs.
01.4 Where authorization currently lives (Branch B input — the decisive finding)
-
approval_requests+apr_action_types+apr_approvals= the only real authorization engine.apr_action_types(action_code, description, handler_ref, risk_level, status, retired_at)live rows:action_code risk_level handler_ref meaning create_item low dot-apr-execute:create data create update_item low dot-apr-execute:update data update add_field medium dot-apr-execute:add_field schema add field patch_ops_code high dot-apr-execute:patch_ops ops code patch amend_law high unimplemented law amend (fail-closed) enact_nrm high unimplemented normative enact (fail-closed) apr_approvals(apr_id, approver, approver_type, decision, rationale)— quorum votes;approver_typeseparates human / ai_council / president. Quorum is risk-tiered (fn_apr_quorum_check, from prior rehearsals: high ⇒ president + 2 ai_council; reject blocks; self-approve prohibited). A dangerous default exists:fn_auto_approve_addauto-approvesaction='add'on INSERT before quorum (implementation-index doc 27/84 — must be hardened). -
os_proposal_approvals(0). Schema (implementation-index doc 114, re-read this run):id, status, signature_text, signature_image, signature_type, first_name, last_name, organization, proposal (→ os_proposals), email, ip_address, esignature_agreement bool, metadata, contact (→ os_proposal_contacts). It is a Directus-managed human e-signature collection, and its siblings prove it is a sales/deal proposal module:os_proposals,os_proposal_blocks,os_proposal_contacts,os_deal_stages,table_proposals. →os_proposal_approvalswas repurposed as the M-1 commit key. It is the wrong instrument: it captures a person physically e-signing a sales proposal (typed/drawn signature, legal name, email, consent flag, capture IP). An agent cannot write it without forging a human signature, and it has no concept of "technical build step", scope, expiry, or rollback. -
GAP (G1): there is no
apr_action_typesrow for build/deploy authorization, and nogovernance_build_authorizationtable. This is the structural reason the design fell back toos_proposal_approvals: the approval spine had no way to express "a controlled technical build step is authorized to COMMIT."
01.5 Governance + coverage substrate (Branch I input)
governance_registry(9): GOV-COUNCIL (council, governance), GOV-DOT (system, monitoring.dot), GOV-KG-SYS (system, kg), GOV-MOIT/MOT/MOUT/MOW (factory/mother, draft), GOV-NRM-SYS (normative), GOV-SIV (system, monitoring.integrity). → No governance object ownsinformation_unit,taxonomy, or an Axis Registry today (IU island; axis owner gap).governance_relations(8):source_type/code, target_type/code, relation_type, is_contract, discovery_source, enforcement_type, enforcement_ref, status. (Per concept doc: its CHECK currently forbids the object-ownership edge — SB-2 blocker.)collection_registry(166) carries the live coverage ledger:coverage_status, coverage_scope_status, coverage_exemption_reason, coverage_review_owner, coverage_decided_at/byplusstorage_role, governance_role, source_kind, migration_state, species_code, birth_code_strategy, …. → Coverage decisions are already data (BIRTH_REQUIRED/DEFERRED/EXEMPT pattern).meta_catalog(169) = registry-of-registries:code, entity_type, source_model, registry_collection, sync_script, record_count, actual_count, orphan_count, baseline_count, composition_level, identity_class, layer. → self-describing catalog enabling orphan/coverage scans.system_issues(~195,633) +event_type_registry(40) +event_outbox(~175,588) = the issue/event substrate (Điều 45 register-before-emit). Live: 0 governance-domain event types registered, 0 governance events emitted (consistent with implementation-index baseline).
01.6 Where each concept lives today — summary
| Concept | Lives in (live) | State |
|---|---|---|
| Topic axis | facet FAC-08 (taxonomy_facets) + taxonomy nodes; tag-bag iu_three_axis_envelope.axis_b_tags; iu_metadata_tag |
facet defined but not operationalized (max=0); no born topic nodes; no IU-topic assignments with confidence |
| Reconstruction axis | information_unit.doc_code/section_code/sort_order (axis A); iu_tree_path; envelope axis_a |
deterministic; invariant fn_iu_reconstruct_source (GOV-SIV) |
| Containment axis | information_unit.parent_or_container_ref; iu_relation (60 contains); iu_tree_path; envelope axis_c |
populated; only axis with relations live |
| Axis Registry (M-DEF-9) | — | ABSENT (G2 / inventory_gap critical); taxonomy_facets is a partial, label-only proto-registry |
| Axis relation | iu_relation (IU↔IU), universal_edges (any↔any), taxonomy.parent_id (vocab hierarchy) |
hard relations live; soft relations (entity_relations) NOT built |
| Axis assignment | entity_labels (no confidence), iu_metadata_tag (confidence, IU-only), iu.parent_or_container_ref |
no unified confidence/evidence/zone/lifecycle assignment (G3) |
| Proposal / review / versioning | approval_requests, unit_edit_draft, iu_merge_set/split_set, doc_reviews, tac_review_state_vocab, unit_version |
rich; PG-native Git-like model already partly present |
| Authorization | approval_requests+apr_action_types(6)+apr_approvals; os_proposal_approvals(sales e-sign, misused as M-1) |
no build-auth substrate (G1) |
01.7 Live-vs-design corrections (live wins; charter rule)
entity_relations(NĐ-36-01 soft relations) is NOT live. The decree's soft-relation/alias/disambiguation substrate (entity_relations,abbreviation_dict,disambiguation_log,entity_embeddings) is unbuilt. Today, both hard and (the few) soft relations rideuniversal_edges+iu_relation. Any axis-relation design must treatentity_relationsas a future table, not a current one.- Topic is a facet, not an island. Design direction "Topic Registry" must bind to FAC-08 +
taxonomy, not a newtopictable. iu_three_axis_envelopeis a projection, not the model — generalizing it (SB-3) means building the Axis Registry and making the envelope a view/refresh over it.entity_labelscannot hold uncertain assignments (no confidence/evidence/zone) — the 3-zone NĐ-36-01 model needs either added columns or a parallelaxis_assignmenttable.- The approval spine works and is risk-tiered; it simply lacks a build-auth action type — so the authorization fix is additive to a working engine, not a rebuild.
conformance_status='open'on all 219 IUs and 0approval_requestsreference IU — the IU governance island is real and must be dissolved by the coverage model (doc 09), not worked around.
01.8 Exact gaps (the design targets)
| # | Gap | Consequence | Addressed in |
|---|---|---|---|
| G1 | No technical build-authorization substrate (no build action-type, no governance_build_authorization) |
Build blocked behind human e-sign meant for sovereign acts | doc 02 |
| G2 | No Axis Registry (M-DEF-9) | inventory_gap (critical); future axis = schema change, not a row; topic/axis ungoverned |
docs 03, 04 |
| G3 | Assignment layer lacks confidence/evidence/zone/lifecycle for semantic axes | Cannot run Approved/Candidate/Quarantine; uncertain topic can't be stored honestly | docs 04, 06 |
| G4 | 3-axis envelope hardcodes axes (projection) | Looks like the model; risks fixed-axis-array antipattern | docs 03, 04, 13 |
| G5 | IU governance island (no owner, no central APR, private DOT/audit) | One-roof violation; topic/axis governance can't attach | docs 08, 09 |
| G6 | Soft-relation substrate (entity_relations) decreed, unbuilt |
Semantic relations crammed into hard-edge table | docs 04, 06, 13 |
| G7 | os_proposal_approvals is a sales module misused as the COMMIT key |
Forgery risk; wrong semantics | doc 02, 13 |
Reuse verdict: ~85% of the substrate this mission needs already exists and should be reused (approval spine, taxonomy/facets, entity_labels/iu_metadata_tag, iu_relation/universal_edges, iu_tree_path/envelope, unit_edit_draft/iu_merge_set/iu_split_set/doc_reviews, collection_registry/meta_catalog/system_issues/event_*). Minimal new substrate is justified only at G1 (build-auth), G2 (axis registry), G3 (semantic assignment), and G6 (when NĐ-36-01 soft relations are built). Everything else is a patch/activation, not a new table.