07 — Governance Issue / Event / Notification Model (2026-06-01)
07 — Governance Issue / Event / Notification Model
Branch G. Design only — no event registration, no emit in this mission (Điều 45 §3.2 register-before-emit; this pack only proposes the registry rows).
7.1 Reuse-first decision
Live substrate already has the routing machinery; the governance layer reuses it:
system_issues(188,250 rows;issue_type/issue_class/sub_classfree-text,coalesce_keyidempotency,severity,occurrence_count) — Điều 31.event_type_registry(40 rows) +event_outbox+event_subscription— Điều 45.systemevent domain already hasissue_opened/issue_resolved/issue_archived(active) — governance issues ride these for open/resolve lifecycle.motherevent domain hasgovernance.blocked/governance.unblocked/proposal.created/proposal.approved/proposal.rejected— allactive=false(dormant). These are the closest existing governance event shapes; the proposal is to activate + generalize them rather than mint parallel types.
Reuse map for the orphan halves: thiếu_quan_hệ (606) + thiếu_mã_định_danh (9) already encode "missing relation / missing id" (the birth-orphan halves); sai_lệch_dữ_liệu (2) = drift; hardcode_violation (11) = Đ28; collection_onboarding_gap (345) = coverage-gap analog. Governance-tier gaps are a new lens, so they get new issue_type values under the existing free-text column (no schema change) but must not duplicate the birth-orphan semantics (Điều 37 §4.12 SSOT).
7.2 The sixteen governance issue/event types
For each: issue_type (proposed system_issues.issue_type), default severity, owner agency, event_type (proposed event_type_registry row, only if event-routed), notification target, cleanup/auto-resolve path, suppression/retire rule, and relation to Registries-Pivot (RP).
Legend: NEW = no such value today; REUSE = existing value generalized.
| # | issue_type (NEW unless noted) | sev | owner | event_type (domain.type) | notify | cleanup / auto-resolve | suppression / retire | RP relation |
|---|---|---|---|---|---|---|---|---|
| 1 | governance_orphan |
high | GOV-SIV | governance.orphan_detected (NEW) |
GOV-COUNCIL queue | resolves when object gains owner path | coalesce by (ref,gap); retire on object retire | RP shows as orphan tile in coverage pivot |
| 2 | local_governance_island |
high | GOV-SIV | governance.island_detected (NEW) |
GOV-COUNCIL | resolves when cluster folded under roof | coalesce by cluster id | island count in summary |
| 3 | owner_gap (sub_class of #1) |
high | GOV-SIV | (rides #1) | GOV-COUNCIL | resolves on owner assignment | — | drill-down dimension |
| 4 | capability_gap |
high | GOV-COUNCIL | (rides #1) | GOV-COUNCIL | resolves on capability grant | — | dimension |
| 5 | approval_path_gap |
high | GOV-COUNCIL | governance.approval_path_gap (NEW) |
GOV-COUNCIL | resolves on APR action-type mapping | — | dimension |
| 6 | audit_gap |
warning | GOV-SIV | (rides #1) | GOV-SIV | resolves on audit-ref wiring | — | dimension |
| 7 | rollback_gap |
high | GOV-SIV | governance.rollback_gap (NEW) |
GOV-DOT | resolves on rollback mechanism | — | dimension |
| 8 | dot_authority_gap |
high | GOV-DOT | governance.dot_authority_gap (NEW) |
GOV-DOT | resolves on dot_tools+paired_dot (already PG-enforced Đ35 §3) |
— | dimension |
| 9 | issue_event_gap |
warning | GOV-SIV | (rides #1) | GOV-SIV | resolves on issue/event route | — | dimension |
| 10 | law_ref_gap |
warning | GOV-NRM-SYS | governance.law_ref_gap (NEW) |
GOV-COUNCIL | resolves on law mapping | — | dimension |
| 11 | design_ref_gap |
info | GOV-SIV | — (no event; info) | none (log) | resolves on design link | Đ31 §4.5 INFO = no issue unless aggregated | tracking only |
| 12 | direct_pg_unratified_exception |
critical | GOV-COUNCIL | governance.unratified_exception (NEW) |
president + GOV-COUNCIL | resolves on ratification or removal | reuse admin_fallback overdue pattern (Đ35 §6.5) |
RP Direct-PG adapter flagged |
| 13 | display_owner_gap |
high | GOV-MOUT | governance.display_owner_gap (NEW) |
GOV-MOUT/COUNCIL | resolves on GOV-MOUT activation + law-28 owner edge | — | RP page ownership tile |
| 14 | pivot_coverage_unowned (PIVOT_MISSING) |
high | GOV-SIV | governance.pivot_coverage_gap (NEW) |
GOV-SIV | resolves on pivot_definition + owner | reuse RP PIVOT_MISSING marker | core RP signal |
| 15 | classification_policy_unowned |
high | GOV-COUNCIL | governance.policy_unowned (NEW) |
GOV-COUNCIL | resolves on policy owner | covers grouping/threshold/label | RP grouping tile |
| 16 | pin_policy_unowned |
high | GOV-COUNCIL | (rides #15) | GOV-COUNCIL | resolves on pin owner | — | RP pin tile |
| + | phantom_definition_gap |
high | GOV-COUNCIL (define) + GOV-SIV (detect) | governance.phantom_definition_gap (NEW) |
GOV-COUNCIL | resolves on phantom law clause (doc 08 Đ31) | LAW_DEFINITION_GAP | RP phantom tile |
(#3/#4/#6/#9 are sub_class of governance_orphan to keep the type count manageable and ride one event; #16 rides #15. This yields ≈10 distinct event_type registrations, satisfying Điều 45 §6.4 "has governance owner + lifecycle" inclusion criteria and avoiding telemetry-as-event.)
7.3 Event discipline (Điều 45)
- Register-before-emit (§3.2/§6.4): every NEW
event_typeabove must be inserted intoevent_type_registryvia the Điều 35-style ratification before any emit. This pack registers nothing; it lists the rows a future doc-06 phase will register. - Signal-not-data (§4): governance events carry
governed_object_ref,gap_type,severity,coalesce_key— never the object body, never secrets.event_outbox.safe_payloadCHECK enforces this; violation ⇒queue.payload_violation(§4.4). - Event vs job (§6.6): detection emits events; remediation (assignment apply) is a job with the 9-state
work_state_machine(§6.7). Do not assume the event covers the job. - Inclusion test (§6.4): each type passes because it is a DOT execution result / governance state change with an owner and lifecycle — not metrics/telemetry.
7.4 Severity → notification routing
Reuses Điều 31 §4.5 severity + Điều 45 §15.4 throttling:
info→ log/report only, no issue (Đ31 §4.5).warning→system_issueswarning; batched digest notification (no per-event ping).high→system_issueshigh + event to owner agency queue.critical(anarchic / unratified exception) →system_issuescritical + event + president/GOV-COUNCIL notification + production block (doc 04 gate).- Throttle: aggregate to one
governance_coverage_degradedsummary event per scope per cycle when an orphan class exceeds a governed threshold (doc 11 §throttle) — prevents 10⁵ events from a single mass-orphan source (thetemplate_gap181k lesson: high-cardinality gaps summarize, not enumerate-as-events).
7.5 Cleanup / suppression / retire
- Auto-resolve: a governance
system_issuesrow flips toresolvedautomatically when the next clean scan no longer finds the orphan (coverage gained). No manual close. - Suppression:
coalesce_keyprevents duplicate rows;occurrence_count/last_seen_attrack persistence. - Retire: when a governed object is
retired(lifecycle), its open governance issues archive (issue_archivedevent) — they are not "fixed", they are out of scope (Điều 36 MT7 retire ≠ delete; Luật Bảo toàn). - Approved-exception suppression: an object with an unexpired approved exception is excluded from orphan emission (it is
approved_exceptions, doc 04 §4.2) — but DOT-GOV-EXCEPTION-REVIEW re-raises it on TTL expiry.
7.6 Relation to Registries-Pivot (the first consumer)
RP's coverage screen (doc 09) renders v_governance_coverage_summary (doc 05 L5) — each issue type above is a drill-down dimension, not a hardcoded tile. The current RP anti-pattern (frontend-injected CAT-ORP/PHA/UNM/017, orphan_count = hd.totalGap) is replaced by a pivot-backed governance-coverage dimension. PIVOT_MISSING (#14) becomes a first-class governance issue rather than a UI string.
Cross-refs: doc 05 L6 (routing), doc 06 DOT-GOV-ISSUE-ROUTE, doc 08 (Điều 45 / Điều 31 clauses), doc 09 (RP display), doc 10 (registration phase 6), doc 11 (throttle/aggregate).