01 — Live Substrate Gap Audit (READ-ONLY live evidence, 2026-06-02)
01 — Live Substrate Gap Audit (READ-ONLY live evidence, 2026-06-02)
Package:
one-roof-axis-auth-proposal-operational-hardening-build-ready-design-2026-06-02Mode: DESIGN ONLY · READ-ONLY · NO COMMIT · NO MUTATION Source of truth for this doc: live PostgreSQLdirectus(PG16), read-onlySELECTonly, statement_timeout 5s, hard LIMIT 500. Zero mutation performed. Prior baseline patched by this doc:one-roof-axis-proposal-authorization-operating-substrate-design-2026-06-01/01-live-substrate-audit.mdand Phase-1 implementation-index "doc96 baseline". Rule applied: live evidence wins over old report (muc-tieu v1.3 §1).
This doc replaces stale numbers in all prior One-Roof docs. Where a prior doc states a different count, this doc's live count is authoritative as of 2026-06-02.
1.0 Purpose
Give the hardening design a precise, current picture of what already exists so that:
- the axis/auth/proposal/coverage designs reuse-first and do not duplicate live substrate;
- no design step relies on a stale assumption;
- every "new table" proposed downstream is justified by a confirmed live gap.
1.1 Reuse spine (the substrate the design will build on, not rebuild)
These already-live objects are the load-bearing substrate. The hardened design reuses them; it must not create parallel islands.
| Concern | Live object | Count | Role in hardened design |
|---|---|---|---|
| Axis registry (the set of axes) | taxonomy_facets |
10 | Existing de-facto axis registry: code, name, cardinality, max_labels_per_entity, status. The axis model generalizes this (see 04). |
| Axis nodes (values within an axis) | taxonomy |
58 | code, name, facet_id, parent_id, parent_facet, depth, scope[], status, replaced_by, _dot_origin. Existing node + intra-axis hierarchy. |
| Axis assignment (entity ↔ node) | entity_labels |
787,723 | entity_code, label_code, assigned_by, rule_id, assigned_at. The live assignment substrate at scale. The hardened "axis_assignment" generalizes/aliases this; do not fork. |
| Graph relations (KG) | universal_edges (+ view v_kg_edges_all) |
2,199 | source/target_collection+id+code, edge_type, edge_subtype, weight, valid_time tstzrange, status. Cross-collection edges. |
| IU semantic relations | iu_relation |
60 | source_unit_id/target_unit_id (uuid), relation_type, assertion_mode, valid_time tstzrange. |
| Containment closure | iu_tree_path |
199 | unit_id, root_unit_id, parent_id, depth, path_ids[], path_addresses[], path_hash. Existing tree/closure projection for containment axis. |
| Information units | information_unit |
219 | id uuid, canonical_address, unit_kind, lifecycle_status, identity_profile jsonb, doc_code, section_code. |
| Collection governance ledger | collection_registry |
168 | code, collection_name, coverage_status, coverage_scope_status, birth_code_strategy, governance_role. Live coverage ledger for the coverage scanner (09). |
| Object catalog | meta_catalog |
169 | code, entity_type, registry_collection, identity_class, composition_level, layer. |
| Derived/recompute ledger | derived_objects_registry |
7 | object_type, refresh_strategy, refresh_mode, stale_after, recompute_status, status. Model for candidate-state decay (09). |
| Measurement/law checks | measurement_registry |
142 | measurement_id, law_code, method, severity, comparison, enabled, auto_generated. Ruleset fingerprint source (auth/coverage). |
| Snapshot fingerprint | evolution_snapshots |
1 | snapshot_at, scope, metrics jsonb, delta_previous jsonb. Reuse target for SB-12 snapshot/ruleset version. |
| Approval spine | approval_requests / apr_approvals |
211 / 42 | request + votes; data-driven quorum. See 1.3. |
| Action-type vocabulary | apr_action_types |
6 | PG-native action vocabulary + risk + handler. See 1.3 (drift note). |
| Sovereign e-sign | os_proposal_approvals |
0 | Human e-signature module. L4-only. See 1.4. |
| Event/queue spine (Điều 45) | event_outbox / event_pending / event_read / event_subscription / event_type_registry / queue_heartbeat |
187,826 / 0 / 187,465 / 3 / 40 / 3 | Register-before-emit spine. No governance domain registered (gap). |
| Issue ledger | system_issues |
196,402 | Coverage/anarchy issues ride existing buckets (09). |
| Audit/changelog | governance_audit_log / registry_changelog |
1 / 69,070 | Provenance/audit spine. |
| Birth spine | birth_registry |
1,069,055 | id int, entity_code, collection_name, species_code, composition_level, dot_origin, born_at, certified, status, canonical_address (NULL), owner, jsonb_profile. |
| Birth watermark cursor | iu_route_worker_cursor |
(live) | worker_name, event_domain, last_event_id uuid, last_created_at, events_seen/attempts_written/dead_lettered. |
Design consequence: the axis layer is largely already present as taxonomy_facets/taxonomy/entity_labels. The hardening job is to (a) generalize these into the open axis model, (b) add the candidate/proposal/confidence/provenance dimension they lack, and (c) wire governance coverage — not to build a new axis store from scratch.
1.2 Confirmed-ABSENT objects (true new-build gaps)
Every object below was probed with a negative EXCEPT existence check and is absent in public:
| Absent object | Intended role | Introduced/owned by |
|---|---|---|
governance_build_authorization |
SB-0 / L3 technical build-authorization record (the replacement for "os_proposal_approvals-as-M1") | This package, doc 03 |
axis_registry |
Generalized axis registry (superset of taxonomy_facets) |
doc 04/05 |
entity_relations |
Generalized relation table (only if universal_edges+iu_relation insufficient) |
doc 04/05 (likely reuse, not build) |
governance_object_ownership |
SB-2 ownership keystone (one accountable per scope) | Phase-1 index docs 16-22, 75-81 |
governance_responsibility_scope |
SB-2 scope reference data (6 law scopes) | Phase-1 index docs 16-22, 75-81 |
governance_candidate_state |
SB-10 candidate-state store (decaying verdict) | Phase-1 index docs 38-44 |
gov_worker_cursor |
SB-13 governance worker cursor family | Phase-1 index docs 38-44 |
governance_ruleset |
SB-12 ruleset registry (canonical hash) | Phase-1 index docs 38-44 |
label_registry |
(none — taxonomy/taxonomy_facets already serve) |
n/a — do not build |
No governance event domain exists in event_type_registry (domains present: iu=16, mother=9, piece=6, staging=5, system=4; total 40). Registering a governance domain is the SB-11 gap (register-before-emit, Điều 45).
1.3 Approval spine — exact live capability (and a material drift correction)
Quorum is data-driven and already enforced by three triggers on approval_requests:
fn_apr_quorum_check—BEFORE UPDATE(trg_apr_quorum_check), fires only onpending→approved. Readsapr_action_types.risk_levelfor the row'sproposed_action_code:high⇒ ≥1presidentand ≥2ai_councilapprovals;medium⇒ ≥1president;low⇒ ≥1 approve.- Any
rejectblocks; self-approve prohibited (proposer taken fromsource_context); votes lockedFOR UPDATE.
fn_apr_block_unimplemented_handler—BEFORE UPDATE(trg_apr_block_unimplemented): looks uphandler_refforproposed_action_codeand RAISES ifhandler_ref='unimplemented'(blocks apply/execution, not row creation).fn_auto_approve_add—BEFORE INSERT(trg_apr_auto_approve): DANGEROUS DEFAULT —IF NEW.action='add' AND NEW.status='pending' THEN NEW.status:='approved'(reviewersystem_auto_approve). Any APR inserted withaction='add'is machine-approved at INSERT, bypassing quorum entirely.- Hardening rule (carried forward, now mandatory): every governance/build APR MUST use
action ≠ 'add'(e.g.action='review'), or quorum is silently skipped. See doc 02/03.
- Hardening rule (carried forward, now mandatory): every governance/build APR MUST use
Other live triggers on approval_requests: trg_approval_auto_code (BEFORE INSERT), trg_apr_lifecycle (BEFORE UPDATE).
Material drift vs prior memory — apr_action_types content
Prior design memory (SB-1) described "4 governance action types as Phase-A rows with risk='high', handler_ref='unimplemented'". These do NOT exist live. The live apr_action_types (6 rows) is the implementation set:
| action_code | risk_level | handler_ref | status |
|---|---|---|---|
add_field |
medium | dot-apr-execute:add_field |
active |
amend_law |
high | unimplemented | active |
create_item |
low | dot-apr-execute:create |
active |
enact_nrm |
high | unimplemented | active |
patch_ops_code |
high | dot-apr-execute:patch_ops |
active |
update_item |
low | dot-apr-execute:update |
active |
Correction → consequence: SB-1 ("governance APR action types") is genuinely unbuilt. Only amend_law and enact_nrm carry handler_ref='unimplemented'. The two-phase fail-closed pattern (Phase-A vocabulary exists + handler unimplemented → quorum-passable but apply-blocked) is the correct precedent to copy for new governance action types, but the rows themselves must still be authored (under authorization, later).
1.4 os_proposal_approvals — confirmed L4-only human e-sign module
- Rowcount 0 (COMMIT_FORBIDDEN signal under the prior "M-1" framing).
- Columns confirm a Directus human e-signature module:
id (char), status, sort, user_created/updated, date_created/updated, signature_text, signature_image, signature_type, first_name, last_name, organization, proposal (char FK), email, metadata jsonb, ip_address, esignature_agreement (bool), contact. - Exact column name correction: the agreement flag is
esignature_agreement(prior memory wroteesig_agreement). The proposal FK column isproposal. - Verdict (carried + hardened): this table is the sovereign L4 e-sign surface only. An agent writing a row here is forging a human signature. It MUST NOT be repurposed as a generic technical COMMIT key. doc 02/03 replace its "M-1 master gate" role with
governance_build_authorization(L3) and reserveos_proposal_approvalsfor L4 sovereign acts.
1.5 Birth / candidate substrate facts (axis + coverage relevant)
birth_registry= 1,069,055 rows, 100%status='born'(single group),canonical_addressNULL in all rows,idis integer.- Consequence: any candidate/coverage key must be
collection_name:entity_code, NOTcanonical_address(which is unusable as a key). Carried forward from GCOS docs 31-44, re-confirmed live.
- Consequence: any candidate/coverage key must be
iu_route_worker_cursor.last_event_id= uuid, butbirth_registry.id= integer ⇒ a birth watermark cursor needs a type-generalized text watermark, not a 1:1 reuse. (SB-13 design constraint.)fn_birth_registry_autois argless (() → trigger) and firesAFTER INSERTon bothapproval_requests(trg_birth_approval_requests) andapr_action_types(trg_birth_apr_action_types).- F-83-1 hazard re-confirmed live: inserting into
apr_action_typesfires this argless birth trigger → syntheticentity_codeNULL →birth_registryNOT-NULL violation. Any future SB-1 author step must re-wirefn_birth_registry_auto('action_code')(pass the action-code argument) before inserting action-type rows. This is a build-time prerequisite, not a design blocker.
- F-83-1 hazard re-confirmed live: inserting into
1.6 Stale-assumption corrections (live wins) — quick reference
| Prior assumption | Live 2026-06-02 | Status |
|---|---|---|
| birth_registry ≈ 1,048,181 | 1,069,055 (+~21k organic) | CORRECTED (count); pattern (all born / canonical NULL) HOLDS |
| os_proposal_approvals = 0; e-sign module | 0; confirmed; col esignature_agreement, FK proposal |
HOLDS (+ column-name fix) |
| apr_action_types = 6 "governance Phase-A high/unimplemented" rows | 6 implementation rows; only amend_law/enact_nrm unimplemented | CORRECTED — SB-1 unbuilt |
| axis_registry / governance_build_authorization absent | absent | HOLDS |
no governance event domain |
absent (5 domains, 40 types) | HOLDS |
| entity_labels relevance | 787,723 rows — the live axis-assignment substrate at scale | NEW EMPHASIS |
| system_issues ≈ 191,307 | 196,402 | CORRECTED (organic growth) |
| event_outbox ≈ 182,731 / event_read | 187,826 / 187,465 | CORRECTED (organic growth) |
| measurement_registry 142 / derived_objects 7 / evolution_snapshots 1 | 142 / 7 / 1 | HOLDS |
1.7 Audit method & forbidden-compliance
- Channel: read-only
query_pg(AST-validated, READ ONLY transaction, read-only role) +information_schema/pg_catalogintrospection. - Zero writes, zero DDL, zero COMMIT, zero approval/event/DOT/law mutation.
- One query errored (wrong column name on
apr_action_types) and was re-run successfully; no side effects. - This doc is evidence for docs 03/04/05/09/11/12/13. Cross-reference: prior package doc 01; Phase-1 index doc96 baseline.