02 — Governed Object Contract (2026-06-01)
02 — Governed Object Contract
Branch B. Supplemental decision pack — no enactment, no schema change. This defines a logical contract (a resolution model), not a new table.
2.1 What is a "governed object" (scale-broad definition)
A governed object is anything that can affect any of:
- system structure (tables, collections, registries, schema);
- registry / list membership (what is in a list, what is counted);
- classification (labels, taxonomy, grouping, species);
- counting truth (pivots, invariants, integrity);
- display truth (what a screen asserts to a human/agent);
- execution authority (who/what may mutate);
- automation behavior (DOTs, workflows, triggers, queues);
- issue / notification (what is raised, to whom);
- cleanup (retire/merge/delete-as-retire);
- approval, audit, rollback;
- the user/agent-visible interpretation of the system.
The test is effect on truth or authority, not table-ness. A route that renders a count is governed; a comment is not.
2.1.1 Object-type catalogue (non-exhaustive, extensible)
registry · collection · table · pivot · DOT · label_rule · taxonomy_facet · grouping_policy · threshold_policy · pin_policy · phantom_definition · route/API surface · workflow design · queue/event type · cleanup workflow · direct_pg_exception · ui_display_contract · agent_capability · information_unit · law/normative_doc · design_template · approval_action_type · future_object_type.
"Future_object_type" is first-class: the detection architecture (doc 05) discovers object types from source inventory, so a newly-created class of object is covered automatically without editing the contract — satisfying the user requirement "future expansion must be automatically covered."
2.2 The governance link set (logical contract)
Every governed object resolves to a set of governance links. These are not proposed as new columns on every table (that would violate Điều 37's relational-ownership model and the live reality that no table system-wide carries owner_gov_code — ownership is relational). They are resolved by the coverage views (doc 05) from existing substrate.
| Link | Meaning | Resolved from (live substrate) |
|---|---|---|
governed_object_type |
which catalogue class | source inventory (doc 05 layer 1) |
governed_object_ref |
stable id of the object | the source table PK / registry code |
owner_gov_code or governance relation |
who owns it | governance_registry.code via governance_relations / law_jurisdiction.domain / inherited from parent |
capability_code |
what capability authorizes it | governance_registry.capability JSON (can_create/must_not_own/can_reference) |
law_ref |
governing law | law_jurisdiction / normative_registry.code / governance_registry.created_by_law |
design_ref |
governing design doc | KB knowledge/dev/design/** (relational, by convention) |
approval_required |
does change need APR? | derived from risk_level (doc 02 §2.3) |
approval_request_ref |
the APR that authorized it | approval_requests.code (+ apr_approvals) |
lifecycle_status |
born/active/deprecated/retired | object's own status col / lifecycle_log |
risk_level |
low/medium/high/critical | apr_action_types.risk_level analog |
audit_ref |
where its changes are logged | governance_audit_log / vps_deploy_log / system_issues / lifecycle_log |
rollback_ref |
how it is reverted | Điều 20 §9.1 rollback mechanism / Điều 30 contract |
effective_from / effective_to |
validity window | object timestamps / approval applied_at |
dot_authority_ref |
if executed by DOT | dot_tools.code (+ paired_dot) |
system_issue_ref |
if flagged as a problem | system_issues.code (via coalesce_key) |
event_type_ref |
if event-routed | event_type_registry.event_type |
substrate_ref / registry_ref |
the SoT substrate it lives in | the registry/collection/table it belongs to |
Design rule (anti-island, anti-bloat): Governance links are resolved relationally, not stamped per-table. The One-Roof model therefore reuses the relational ownership model of Điều 37 and does not add owner_gov_code columns across the schema. The only structural extension contemplated (future, separately approved) is enabling agency → object edges — see doc 08 §Điều 37 draft (the current CHECK target_type ∈ {law,agency} cannot express object ownership).
2.3 Minimum required links by object class
Coverage is risk-graded — a low-risk read-only object needs far fewer links than a mutating DOT. This is the governance analog of Điều 20's Tier 0–3 and Điều 32's risk_level quorum.
| Object class | owner |
capability |
law_ref |
approval |
audit |
rollback |
dot_authority |
issue/event |
|---|---|---|---|---|---|---|---|---|
| Low-risk read-only (a read-only view, a report pivot) | ✅ | — | ✅ | — | ✅ (scan log) | — | A-tier only if executed by DOT | on failure only |
| Policy object (grouping/threshold/pin/label policy) | ✅ | ✅ | ✅ | ✅ (medium) | ✅ | ✅ (retire) | if DOT-applied | ✅ on conflict |
| Mutating DOT (tier B) | ✅ | ✅ | ✅ (Đ35) | ✅ (per apr_action_types.risk_level) |
✅ (vps_deploy_log) |
✅ (Đ35 §6.4) | ✅ + paired_dot |
✅ (dot_bug/issue) |
| Production route / API | ✅ (GOV-MOUT) | ✅ | ✅ (Đ28) | ✅ if it can mutate; exception-record if Direct-PG | ✅ | ✅ | if DOT-served | ✅ coverage |
| Law / policy change | ✅ (GOV-COUNCIL) | — | ✅ (self) | ✅ high (Đ32 §4.2: president + 2 ai_council) | ✅ (governance_audit_log minute) |
✅ (amendment) | — | ✅ |
| Cleanup workflow | ✅ | ✅ | ✅ (Đ30/Đ45) | ✅ (destructive ⇒ high) | ✅ | ✅ mandatory | ✅ DOT + paired | ✅ |
| Exception / temporary bypass | ✅ | — | ✅ (Đ33 §13) | ✅ + TTL (cf. Đ30 waiver 72h, Đ35 §6.5 fallback 24h) | ✅ | ✅ | — | ✅ on overdue |
Notes:
- A policy object that is missing
approvalis exactly the "standalone policy table without central approval" that One-Roof rule 4 forbids (doc 01 §1.3). - A mutating DOT missing
paired_dotis already rejected by the live Điều 35 §3 trigger (DOT Cấp B PHẢI có paired_dot); the coverage scanner re-asserts this as a governance link, not a new rule. - An exception must carry a TTL and an overdue path, mirroring the live
admin_fallback_log→fn_admin_fallback_overdue_scan()→system_issues kind='fallback_audit_overdue'mechanism (Điều 35 §6.5). This is the reuse template fordirect_pg_unratified_exception.
2.4 "Covered" vs "not covered" (binding for the invariant, doc 04)
A governed object is covered iff it can resolve a valid owner path and the required-by-risk approval/audit/rollback links per §2.3.
Counts as a valid owner path:
- direct
owner_gov_codeon the object (future, where object-edges exist); or - a
governance_relationsedge to an owning agency; or - a
law_jurisdictionowner (law→domain primary) whose law is owned by an active agency; or - an approved exception (an
approval_requestsrow, action-type for exception, with TTL); or - an explicit delegated owner recorded centrally; or
- an inherited owner from a parent object only where a law explicitly allows inheritance (e.g. a pivot inheriting its source collection's owner).
Does NOT count as coverage (these are exactly the "anarchic" tells):
- a comment-only / docstring "owner";
- a frontend-declared owner (e.g. a Vue constant);
- a local/per-module approval flag;
- an unratified design doc as the sole authority;
- a machine-generated pseudo-approval (e.g.
system_auto_approvemachine rows — the liveapproval_requestsreality where the only non-machine approvals are 6 S178 DOT-repair rows;os_proposal_approvals=0); - a stale
law_catalog-only /normative_registry-only entry with no active owner edge.
This last clause is why laws 24/26/28/45 are agency-orphaned today: they exist in normative_registry but have no governance_relations owner edge to an active agency (doc 00 §0.3). They are "law-present but agency-orphaned" — covered at the law tier, orphaned at the agency tier.
Cross-refs: doc 03 formalizes the gap types; doc 04 turns §2.4 into the accounting identity; doc 05 builds the views that resolve every link in §2.2.