23 — C-1/C-2 Council Decision Packet for SB-1/SB-2 (decision-packet-only, no binding, 2026-06-01)
23 — C-1 / C-2 Council Decision Packet for SB-1 / SB-2
Path:
knowledge/dev/reports/architecture/one-roof-governance-technical-addendum-and-implementation-index-2026-06-01/Doc: 23 (appended after 22). Track: Branch A of the council-packet + scanner/event design bundle. Status: DECISION PACKET ONLY. This is a request for a council/human ruling. It records nothing intogovernance_registry, creates no approval, enacts no law, bumps no version, mutates no PG/Directus/Qdrant/Nuxt. It is not implementation and not an approval. Role: Prepares the two council rulings (C-1, C-2) that are the critical path for SB-1 (T3) and SB-2 (T4). Both substrate designs are design-complete (docs 16, 17, 20). Neither may be built until these rulings exist and the separate enactment/sovereign gates (H-1, H-2/SB-6) are satisfied. Controlling sources (priority order, doc 00 §0.2): this implementation index → concept canon (knowledge/dev/design/one-roof-governance-concepts/00–03) → Round-4 law hardening → earlier rounds; blockers (doc 03) win over ambition; if unclear → STOP. Above all:knowledge/dev/laws/prompt-muc-tieu-mo-for-claude-code.md. Evidence base: doc 18 (SB-1/SB-2 live PG evidence) + re-verified read-only against DBdirectus(contabo containerpostgres) on 2026-06-01 bycontext_pack_readonly(see §6).
0. How to use this packet
This is written so a council member (and the human sovereign for the ratification step) can read one document and rule. Each decision has the same shape:
- Decision question — the single thing being ruled on.
- Recommended option — the default the design recommends, with the reason.
- Alternatives considered and rejected — with why.
- Exact approval wording — copy-paste minute text for an APPROVE or a REJECT/AMEND.
- What approval unlocks — the next allowed step.
- What approval does NOT unlock — the gates that still stand.
- Dependencies.
- Rollback concept.
A No-Self-Approval Statement (§4) and an Implementation-Remains-NO-GO Statement (§5) bind both decisions. Nothing in this packet may be treated as self-approved by an agent; a ruling becomes real only when recorded through the proper council/human channel.
Pairing: C-1 ↔ SB-2 (doc 17, ownership substrate). C-2 ↔ SB-1 (doc 16, action-type vocabulary). The two are complementary legs of one relational-ownership model:
governance_relationsalready carries agency↔law edges;governance_object_ownership(C-1) carries object/axis→agency edges; the SB-1 action-types (C-2) are the only write path into that table. Council may approve them independently, but the owner-write path is not live until both are ruled and built.
1. DECISION C-1 — SB-2 object/axis ownership substrate pattern
1.1 Decision question
Should the One-Roof governance system express object/axis ownership by creating a new additive table
governance_object_ownership(plus a 6-rowgovernance_responsibility_scopereference table and a resolution view), as designed in doc 17 — OR by widening the livegovernance_relationsCHECK constraints to admit object/axis endpoints?
This is blocker SB-2 and council item C-1 (doc 03 §3.1, §3.2).
1.2 Why a decision is needed (live evidence, re-verified 2026-06-01)
governance_relationshas exactly two type CHECKs, both∈ {law, agency}:chk_relations_source_type→CHECK (source_type IN ('law','agency'))chk_relations_target_type→CHECK (target_type IN ('law','agency'))- plus
uq_relations_source_target_type UNIQUE (source_code, target_code, relation_type)andPRIMARY KEY (id).
- All 8 live edges are
agency → law,status='active',discovery_source='manual'. No FK enforces the codes (free-text). - An object (a pivot definition, a collection, an IU class) or an axis can be neither a
lawnor anagency, so it cannot be a relation endpoint today. Object/axis ownership is un-expressible. to_regclass('public.governance_object_ownership')= NULL andto_regclass('public.governance_responsibility_scope')= NULL — both target tables are genuinely absent (greenfield; no migration risk to design against).
1.3 Recommended option — NEW TABLE (additive)
Approve the additive-table pattern of doc 17. Concretely:
- A new table
governance_object_ownershipas the authoritative store of(object × scope) → ownerlinks. Full column contract in doc 17 §2; load-bearing elements:object_type(resolves against the governed class catalogmeta_catalog.entity_type/ coverage-profile class list — not an enum;'axis'is one ordinary value, M-DEF-8);object_ref(the object's code, resolvable in that class'sregistry_collection; for axes =axis_code);scope→ FK →governance_responsibility_scope(scope_code);owner_kind ∈ {accountable, supporting, delegated, exception}(CHECK or small ref);owner_gov_code→ FK →governance_registry(code)(a real FK — stronger than the live, FK-lessgovernance_relations);- lifecycle/effective/approval/audit/rollback/source provenance columns (
lifecycle_status,effective_from/to,approval_ref→approval_requests,audit_ref→registry_changelog,rollback_ref,source_law_ref→normative_registry,source_design_ref,supersedes_idself-FK); - Partial UNIQUE
(object_type, object_ref, scope) WHERE owner_kind='accountable' AND lifecycle_status='active'— this is the machine enforcement of one accountable owner per (object × scope) (M-DEF-3).
- A new 6-row reference table
governance_responsibility_scopeseeding the six law-defined scopes:policy, health, execution, render, approval, audit(a table, not a CHECK, so a 7th scope is a governed row, not DDL). - A resolution view
v_object_effective_owner(object_type, object_ref, scope)implementing owner-link-only inheritance (a queried object resolves to its own owner row, else the nearest ancestor container/anchor's owner row) plus the gap/conflict viewsv_object_owner_gapand a double-owner detector.
Accountable / supporting role model (M-DEF-3, ruled here): exactly one active accountable owner per (object × scope); unlimited supporting; delegated is time-boxed (mandatory future effective_to); exception is scoped to its own object only. Two active accountable owners on the same (object, scope) is a conflict (governance.owner.conflict), not a valid state.
Owner-uniqueness-per-scope (ruled here): uniqueness is per scope, not per object. One object legitimately has up to six different accountable owners — one each for policy/health/execution/render/approval/audit. This is the corrected reading of Điều 37 §4.12 ("one accountable owner" → "one accountable owner per scope").
Anti-hiding rule (ruled here, M-DEF-7, non-negotiable): only the owner-link inherits down a container. Risk-bearing links (approval-path, rollback, DOT-authority, exception) never inherit. A child carrying its own policy under a covered parent still raises APPROVAL_PATH_GAP.
Reason for the recommendation: the additive table is reversible by default (until SB-1 Phase-B handlers exist, nothing writes to it; rollback = DROP TABLE … / DROP VIEW …), introduces zero migration risk to the 8 live edges and the 2 live triggers on governance_relations (it does not touch that table at all), adds a real FK to governance_registry (an integrity improvement), and scales at the governance grain — adding 10⁶/10⁸ children under an anchored container inserts 0 ownership rows (Δtotal = 0; doc 17 §5, §7).
1.4 Alternatives considered and rejected
| Alternative | Why rejected |
|---|---|
Widen the governance_relations CHECK to admit object/axis endpoints |
ALTER on a live CHECK is a migration touching 8 edges + 2 validate triggers; the table has no scope / owner_kind / dates / lifecycle / approval columns (→ many more ALTERs); its UNIQUE(source_code,target_code,relation_type) cannot express one-accountable-owner-per-scope; conflates the agency↔law grain with the object→agency grain. Higher risk, weaker semantics. |
| View-only (no storage) | No existing table stores object→owner; a view has nothing to read. Rejected as storage. |
Add owner_gov_code columns to each domain table |
Violates the system-wide relational-ownership decision (no table system-wide carries owner_gov_code); per-row ownership is an anti-pattern across 169 catalog classes; would re-introduce hardcoded owners. |
Reuse admin_fallback_log for ownership/exception rows |
It is DOT-repair-shaped (dot_code/backup_path/patch_diff NOT NULL; auto-fires a retroactive DOT-repair APR). Wrong shape and wrong semantics (see C-2 §2.4). |
1.5 Exact approval wording (copy-paste minute)
To APPROVE (recommended):
"COUNCIL ruling C-1 (date ____): The object/axis ownership substrate is APPROVED as the additive pattern designed in doc 17 — a new table
governance_object_ownership, a new 6-row reference tablegovernance_responsibility_scope(scopes: policy, health, execution, render, approval, audit), and the resolution viewv_object_effective_ownerwith owner-link-only inheritance. The role model is: exactly one active accountable owner per (object × scope); supporting unlimited; delegated time-boxed; exception object-scoped; the anti-hiding rule holds. The livegovernance_relationsCHECK is NOT widened. This ruling authorizes the SB-2 substrate to enter the build queue; it does NOT itself create the table, write any owner row, or grant the human-enactment/sovereign-sign-off gates (H-1, H-2/SB-6), which remain required before any commit."
To REJECT / AMEND:
"COUNCIL ruling C-1 (date ____): The C-1 recommendation is [REJECTED / AMENDED as follows: ____]. Reason: ____. SB-2 remains OPEN; the substrate does not enter the build queue. The agent must re-design per this ruling and resubmit a packet."
1.6 What C-1 approval UNLOCKS
- SB-2 substrate (
governance_object_ownership+governance_responsibility_scope+ views) becomes eligible for the build queue (T11, behind all gates). - The "create table" step of doc 20 §3.1 moves from blocked-on-council to blocked-only-on-H-1-enactment-path + rehearsal log.
- Enables T6 (scanner) and T9 (Registries-Pivot integration) to design against a ruled ownership shape rather than a proposed one.
1.7 What C-1 approval does NOT unlock
- No table is created. Creating the table is a committed DDL — requires H-1 (a ratified enact/apply path) + a rehearsal log (doc 19) + correct host/backup gate (mission §6).
- No owner row may be written. First live owner-write additionally requires SB-1 resolved (C-2 + Phase-B handler built as a governed DOT), the
governance_responsibility_scopeseed (itself a governed insert), and sovereign sign-off —os_proposal_approvals = 0today ⇒ COMMIT_FORBIDDEN (SB-6/H-2). - No IU ownership. Binding IU owners into the table additionally needs OP-B (C-3) + C-4 (doc 26).
- No
governance_relationschange. The live CHECK and 8 edges stay exactly as they are.
1.8 Dependencies
- Pairs with C-2 for the owner-write path (the table is written only by SB-1 handlers).
- Downstream: H-1 (enactment phase), H-2/SB-6 (sovereign sign-off), rehearsal log (doc 19), SB-8 coverage rows (T6).
- Concept basis: M-DEF-1/2/3/7/8 (concept canon doc 01–02); Điều 37 §4.15-bis OWNs the "one accountable owner per scope" contract, the substrate REFERENCES it.
1.9 Rollback concept
Pre-write (the only state C-1 enables design-for): DROP TABLE governance_object_ownership, governance_responsibility_scope; DROP VIEW v_object_effective_owner, v_object_owner_gap; — zero downstream effect because nothing writes to them until SB-1 Phase-B. Post-write (T11 only): owner rows are never hard-deleted; reversal is supersedes_id chaining + lifecycle_status='revoked'/'expired' + rollback_ref, with a registry_changelog audit row. Detailed rehearsal: doc 19 (author-mode BEGIN..ROLLBACK).
2. DECISION C-2 — SB-1 governance APR action-type vocabulary pattern
2.1 Decision question
Should the four governance action-types be registered as rows in the existing
apr_action_typesreference table, in two phases (Phase A: register fail-closed withhandler_ref='unimplemented'; Phase B: flip the handler after gates) — AND should the M-DEF-6 governed-exception record be stored via the APR payload + a governed-exception register rather thanadmin_fallback_log?
This is blocker SB-1 and council item C-2 (doc 03 §3.1, §3.2), plus the exception-store correction (doc 16 §6).
2.2 Why a decision is needed (live evidence, re-verified 2026-06-01)
apr_action_typeshas 6 rows:add_field(medium),amend_law(high,unimplemented),create_item(low),enact_nrm(high,unimplemented),patch_ops_code(high),update_item(low). None ofassign_governance_owner / grant_governance_exception / delegate_authority / assign_axis_ownerexists (0 of 4 — pre-flight collision = none).approval_requests.proposed_action_codeis FK →apr_action_types(action_code)(fk_apr_action_type, ON UPDATE/DELETE RESTRICT). Adding 4 rows makes them referenceable with zero code change.fn_apr_quorum_check(re-verified verbatim) routes quorum purely fromapr_action_types.risk_level:high⇒ ≥1 president + ≥2 ai_council;medium⇒ ≥1 president;low⇒ ≥1 approve; any reject blocks; self-approve prohibited. Settingrisk_level='high'on each governance action-type is the quorum routing — no code, no hardcoded list.fn_apr_block_unimplemented_handler(re-verified verbatim) RAISESAction % has handler_ref=unimplemented. Reserve-only, cannot execute.on any APR whose action'shandler_ref='unimplemented'. This is the live fail-closed mechanism — exactly howamend_law/enact_nrmsit today.admin_fallback_log(22 rows) is DOT-repair-shaped (forcesdot_code/backup_path/patch_diff/verify_evidenceNOT NULL; trigger auto-creates a retroactive APR). It does not carry the M-DEF-6 11 exception fields.
2.3 Recommended option — bundle of 4 action-types, two-phase, PG-first rows
Approve the four action-types as rows in apr_action_types, registered in two phases:
| Code | risk_level | Phase-A handler_ref | Purpose (M-DEF link) |
|---|---|---|---|
assign_governance_owner |
high | unimplemented |
Propose the accountable owner for a (object × scope) pair → canonical write into governance_object_ownership (M-DEF-3). |
grant_governance_exception |
high | unimplemented |
Record an 11-field, time-boxed, replacement-planned governed exception (M-DEF-6). |
delegate_authority |
high | unimplemented |
Record a time-boxed delegation of a responsibility scope to another agency (e.g. C-5 render delegation; OP-B interim cover). |
assign_axis_owner |
high (default; council may set medium for display-only axes) |
unimplemented |
Assign the accountable owner of an axis (M-DEF-8), object_type='axis'. |
Phase A — vocabulary registration (data, fail-closed, reversible). Insert the 4 rows status='active', risk_level='high', handler_ref='unimplemented'. Consequence: the vocabulary exists and is risk-rated, but fn_apr_block_unimplemented_handler RAISES on any APR referencing them ⇒ zero apply capability. This closes SB-1's "missing vocabulary" gap with no apply risk. (Phase A is a committed INSERT and is not performed here; it requires C-2 + the H-1 enact/approval path + a rehearsal log.)
Phase B — handler activation (T11, gated). Build the real handler (a governed DOT that writes governance_object_ownership / the exception register / a governance_relations delegation), then flip handler_ref from 'unimplemented' to the real ref via an update_item APR on apr_action_types. Only after: (a) council ratifies C-2; (b) the handler exists as a governed DOT; (c) SB-2 is built (owner-write target exists); (d) sovereign sign-off path (H-2/SB-6) is available.
Submission convention (ruled here, ties to Branch E / doc 27): every governance APR is submitted with action ∈ {review, modify, delete} — never action='add' (recommended default action='review'), because fn_auto_approve_add machine-approves action='add' on INSERT before the quorum gate can fire. action≠'add' + handler_ref='unimplemented' are the two independent Phase-A safeties.
2.4 Exception-store correction (part of C-2)
Approve storing the M-DEF-6 governed exception via (1) the APR proposed_action jsonb payload under grant_governance_exception, and (2) a small additive governed-exception register co-located with the SB-2 substrate (sharing its lifecycle/approval/audit columns) — NOT admin_fallback_log. All 11 fields required: exception_type, scope, accountable_owner, reason, risk, approval_ref, expiry (future), review_cadence, rollback_ref, replacement_plan (NON-NULL), issue_on_expiry; plus a state fingerprint (auto-invalidate on signature change), max-2-renewals (3rd auto-escalates to critical), and the non-exemptable floors (no write outside a DOT, no local approval, no UI-counted truth, no unregistered emit, no reconstruction/vector exemption). admin_fallback_log stays reserved for genuine break-glass DOT repair.
2.5 Alternatives considered and rejected
| Alternative | Why rejected |
|---|---|
| PostgreSQL enum for action-types | Adding a value = ALTER TYPE DDL = hardcode-in-schema; defeats no-hardcode and PG-first. |
| Separate config rows / a new action-type table | A parallel vocabulary the Đ32 spine does not read = local governance island. |
| Directus-managed vocabulary as source-of-truth | PG is SSOT and FK-enforced; Directus reads only. |
| One-phase: register with a working handler immediately | Would create live apply capability before SB-2 exists and before sovereign sign-off — violates COMMIT_FORBIDDEN and reversibility. |
Store exceptions in admin_fallback_log |
Wrong shape (DOT-repair columns NOT NULL) and wrong semantics (auto retroactive DOT-repair APR); cannot hold the 11 M-DEF-6 fields. |
2.6 Exact approval wording (copy-paste minute)
To APPROVE (recommended):
"COUNCIL ruling C-2 (date ____): The governance APR action-type vocabulary is APPROVED as four rows in
apr_action_types—assign_governance_owner,grant_governance_exception,delegate_authority,assign_axis_owner— eachrisk_level='high'(council may downgradeassign_axis_ownertomediumfor display-only axes), registered in Phase A withhandler_ref='unimplemented'(fail-closed, likeamend_law/enact_nrm). Phase B handler activation is deferred to a separate build authorization. Governance APRs MUST useaction ∈ {review, modify, delete}, neveradd. The M-DEF-6 governed exception is stored via the APR payload plus a governed-exception register, NOTadmin_fallback_log. This ruling authorizes Phase-A registration to enter the build queue; it does NOT itself insert any row, build any handler, or grant H-1/H-2/SB-6, which remain required before any commit."
To REJECT / AMEND:
"COUNCIL ruling C-2 (date ____): The C-2 recommendation is [REJECTED / AMENDED: ____]. Reason: ____. SB-1 remains OPEN; the vocabulary does not enter the build queue."
2.7 What C-2 approval UNLOCKS
- SB-1 Phase-A registration (4 rows, fail-closed) becomes eligible for the build queue (behind H-1 + rehearsal).
- The four action codes become the agreed write-verbs that T6 (scanner) proposes through and that doc 26 (OP-B) references for landing ruled IU owners.
- Confirms the exception-store shape that T7 (doc 24) registers events for (
governance.exception.granted/.expired).
2.8 What C-2 approval does NOT unlock
- No row inserted. Phase-A INSERT is committed DDL/DML — requires H-1 + rehearsal log + host/backup gate.
- No handler built / no flip. Phase B requires SB-2 built + handler-as-governed-DOT + sovereign sign-off.
- No apply capability. While
handler_ref='unimplemented', every governance APR RAISES at execution — by design. - No approval is created by this packet, and the action-types confer no authority until both phases and all gates clear.
2.9 Dependencies
- Pairs with C-1 (the action-types' only write target is the C-1 table).
- Downstream: H-1, H-2/SB-6, rehearsal log (doc 19), Branch E auto-approve hardening (doc 27) as defence-in-depth, SB-8 coverage rows (T6).
- Concept basis: M-DEF-3/6/8; Điều 32 +
apr_action_typesis the mechanism Điều 37 REFERENCES (never a Đ37-local approver).
2.10 Rollback concept
Phase A: retire via update_item (status='deprecated'/'retired', retired_at=now()) — never delete (FK ON DELETE RESTRICT from approval_requests). Phase B: flip handler_ref back to 'unimplemented' (an update_item APR) to re-arm fail-closed. Rehearsal: doc 19.
3. Combined dependency view (C-1 + C-2)
C-1 (SB-2 table) C-2 (SB-1 action-types)
│ │
▼ ▼
build queue: CREATE table build queue: Phase-A INSERT (fail-closed)
│ │
└──────────┬───────────────────┘
▼
H-1 (ratified enact/apply path) + rehearsal log (doc 19)
│
▼
Phase-B handler built as governed DOT (needs SB-2 table live)
│
▼
Sovereign sign-off (H-2 / SB-6; os_proposal_approvals currently 0 = COMMIT_FORBIDDEN)
│
▼
First live owner-write (action≠'add'; auto-approve hardening, doc 27)
Council may rule C-1 and C-2 in either order or together; the owner-write path is live only when both are ruled, both are built, and every gate below them has a recorded ruling.
4. No-Self-Approval Statement (binds C-1 and C-2)
No gate in this packet may be satisfied by an agent. A council ruling exists only when recorded through the proper council minute / approval path; a sovereign ratification exists only when recorded through os_proposal_approvals (or the ratified human enact path). An agent may propose (this packet) and, after a recorded ruling, design the build — it may never rule, approve, or self-approve. fn_apr_quorum_check independently prohibits proposer==approver self-approval at the substrate. Live state confirms no governance/IU/axis/coverage approval has ever occurred: apr_approvals = 42 (all S178 DOT-repair), os_proposal_approvals = 0.
5. Implementation-Remains-NO-GO Statement (binds C-1 and C-2)
Approving C-1 and/or C-2 authorizes the corresponding substrate to enter the design/build queue. It is not a build authorization. No table is created, no row inserted, no handler built, no owner written, and no approval created by virtue of these rulings. Implementation (T11) remains NO-GO until a separate, explicit build authorization is issued and every upstream gate (doc 03 §3.5; doc 20 §3.1) has a recorded council/human ruling — never self-approval. Mission constitution (prompt-muc-tieu-mo §4H, §6, §7) and doc 00 §0.6 forbid committed DDL/DML, DOT registration, event registration/emit, enactment, version bump, status change, and registry writes at this tier.
6. Live evidence re-verification log (read-only, zero mutation, 2026-06-01)
Role context_pack_readonly, DB directus, contabo container postgres. All read-only SELECT (AST-validated, READ ONLY txn, 5 s timeout, LIMIT 500). No mutation.
| Probe | Result |
|---|---|
apr_action_types rows |
6 — add_field(medium), amend_law(high,unimplemented), create_item(low), enact_nrm(high,unimplemented), patch_ops_code(high), update_item(low). 4 governance codes absent. |
governance_relations constraints |
chk_relations_source_type/chk_relations_target_type both ∈{law,agency}; uq_relations_source_target_type; PK(id). |
to_regclass new tables |
governance_object_ownership = NULL; governance_responsibility_scope = NULL (greenfield). |
governance_registry |
9 rows: 5 active (GOV-COUNCIL/SIV/DOT/KG-SYS/NRM-SYS) + 4 draft mothers (GOV-MOIT/MOT/MOUT/MOW). No GOV-IU. |
| Approval spine | os_proposal_approvals=0; apr_approvals=42; approval_requests=211. |
fn_auto_approve_add / fn_apr_quorum_check / fn_apr_block_unimplemented_handler |
source confirmed verbatim (see doc 27 §1 and doc 18). |
7. Verdict
C-1 / C-2 council decision packet: COMPLETE (Branch A). Both decisions are framed with question, recommended default, rejected alternatives, copy-paste approval wording, unlock/no-unlock boundaries, dependencies, rollback, no-self-approval, and implementation-NO-GO. No ruling has been made; no PG/Directus/Qdrant/Nuxt mutated; no approval created; no law enacted; no version bumped. Critical path: this packet (C-1+C-2) gates SB-1 Phase-A registration and SB-2 table creation — both still NO-GO to commit until H-1 + sovereign sign-off. Next: Branches B (doc 24, T7 events), C (doc 25, T6 scanner), D (doc 26, OP-B), E (doc 27, auto-approve), F (doc 28, readiness).