KB-3F8C

06 — Governance Coverage Invariant Hardening (Branch F) (2026-06-01)

12 min read Revision 1
one-roof-governanceclause-hardeningbranch-fcoverage-invariantaccounting-identitygovernance-graincontainer-graingate-severityignored-loophole2026-06-01

06 — Governance Coverage Invariant Hardening (Branch F)

Reviews decision-pack doc 04 (…/04-governance-coverage-invariant.md). Adversarial. The invariant is the keystone that makes One-Roof self-enforcing — so its closure rules must be exact.

F0. What the pack says (summary)

Doc 04 states the identity total_governed(S) = covered + governance_orphans + approved_exceptions + retired_or_ignored, which must "close exactly for every scope" (the governance twin of the RP count-integrity invariant). Derived gates: production-eligibility (orphans({o})==0), authority, DOT, issue. Inheritance (§4.4) lets coverage flow parent→child where law permits (DOT never inherits). §4.5: "computed, never remembered." §4.6: GOVERNANCE_COVERAGE_PASS(feature) = every touched object covered==true OR approved-exception. §4.7: honest baseline = FALSE today (draft owners, agency-orphaned laws, unratified exception).

Overall: the accounting-identity approach is excellent and the right model. But there are three contradictions/loopholes that, unfixed, let the identity close while real gaps hide, or make the gate trivially unsatisfiable.


F1 — Contradiction: per-object identity (doc 04) vs container-grain (doc 11)

  • Original: doc 04 §4.2 says the identity holds "for any scope" over "governed objects," counting "at the object grain." Doc 11 §11.1 says "10⁸ records collapse to a few thousand registry-coverage checks … governance coverage is resolved at the owning-container grain, not the leaf-record grain."
  • Contradiction: these describe different populations. If total_governed is per-object (doc 04), 10⁸ records are in it (the explosion doc 11 forbids). If it's container-grain (doc 11), then total_governed is NOT "all governed objects" and the identity is over a reduced set — but doc 04 never says which objects are excluded. An implementer can't build a closing identity from two incompatible population definitions.
  • Hardened wording — define the governance grain precisely (the leaf-vs-meta discipline applied to governance):

    "The coverage identity is computed at the governance grain, defined as the set of objects that require their own coverage: (a) roots (objects with no covered parent), (b) non-inheriting classes (policy, DOT, route/surface, law, pivot, exception — anything in a non-EPHEMERAL profile that does not inherit), and (c) containers (registries/collections that other objects inherit from). Inheriting leaf records are NOT counted individually — they are represented by their container's coverage (one container check stands for all its inheriting children). total_governed(S) = count of governance-grain objects in S, never the leaf-record count."

  • This is the exact analog of the RP v_registry_leaf_set leaf rule that kept count-integrity correct (a meta/rollup row is not summed with its children). State it with equal precision: a governance-grain object is one whose coverage is NOT fully determined by a covered parent.
  • Acceptance test: the identity closes over the governance-grain population; adding 10⁶ inheriting child records to a covered container changes total_governed by 0 (they inherit), proving container-grain; adding one new root changes it by 1 and surfaces as OWNER_GAP if unowned.
  • Open question: none — this is the single most important precision fix in the invariant.

F2 — Loophole: retired_or_ignored lets any object be parked to make the identity close

  • Original: §4.2 term 4 = "retired_or_ignored — lifecycle=retired, or explicitly out-of-governance by law."
  • Loophole: "ignored" is an un-gated escape hatch. To make orphans(S)=0 (pass the gate), one can move an inconvenient object into ignored. Who authorizes "ignored"? The pack doesn't gate it. This is the accounting equivalent of writing off a liability with no approval.
  • Hardened wording — split the term and gate "ignored":

    "retired (lifecycle=retired per Điều 36; Luật Bảo toàn — retire ≠ delete) is free (a retired object legitimately leaves the coverage population). ignored is NOT free: marking an object out-of-governance is itself a permanent exception requiring the same COUNCIL approval + law-ref as any exception (Branch E), and it carries a replacement_plan (why it can stay out forever). An object in ignored with no approval is itself an UNRATIFIED_EXCEPTION (critical)."

  • Rename the term retired_or_approved_ignore to signal the gate.
  • Acceptance test: moving an object to ignored without a COUNCIL-approved out-of-governance record raises critical, not silently shrinks the orphan count.
  • Open question: none.

F3 — Contradiction: is a warning-severity orphan blocking? §4.6 says yes, §4.7 says no

  • Original: §4.6: GOVERNANCE_COVERAGE_PASS(feature) = every touched object covered == true OR approved-exception. §4.7: a draft-owner object is a warning-severity orphan (covered == false) but is treated as a tolerable baseline, not a production blocker.
  • Contradiction: a draft-owner orphan has covered == false, so §4.6 ("covered==true required") blocks it. But §4.7 treats warning as non-blocking. The gate is not severity-aware, so it either blocks on warnings (too strict — every feature touching anything MOUT-rendered fails because MOUT is draft, J6) or it silently treats warnings as pass (undocumented).
  • Hardened wording — make the gate severity-aware:

    "GOVERNANCE_COVERAGE_PASS(feature) ⟺ for every touched governance-grain object: zero critical and zero high orphans (or covered by an unexpired approved exception). warning orphans are reported and tracked with a remediation deadline but do not block the production gate; info is ignored. The gate blocks on anarchic / authority-critical gaps, not on descriptive ones."

  • This aligns with D2 (anarchic = authority-critical missing link) and §4.7's honest baseline: draft-owner = warning = tracked-not-blocked, with a deadline to activate.
  • Acceptance test: a feature touching only warning-orphan objects passes the gate (with deadlines logged); a feature introducing a high/critical orphan fails. The two clauses (§4.6/§4.7) no longer contradict.
  • Open question: OQ-F3 — what remediation deadline converts a tolerated warning into a blocking high? (Age-based escalation; council sets the window — links to H3.)

F4 — Exception term must align with B5 (exception is NOT covered)

  • Original: §4.2 has approved_exceptions as a separate term (correct), but §4.3 lists "approved exception" as a valid owner path (so it would land in covered) — the B5 contradiction surfaces here too.
  • Hardened wording: as B5 — remove "approved exception" from §4.3's valid-owner-path list; an exception object counts only in approved_exceptions, never covered. This keeps the four identity terms mutually exclusive (no object in two terms), which is required for "closes exactly."
  • Acceptance test: every governance-grain object is in exactly one of the four terms; the four counts partition total_governed with no overlap.
  • Open question: none.

F5 — "covered requires an active agency" makes the baseline mostly-FALSE and the gate near-unusable today

  • Original: §4.3.1: owner paths 2/3 require an active agency; GOV-MOUT/MOW/MOT/MOIT are draft, so objects owned only by them are "not yet covered" (warning). Laws 24/26/28/45 have no owner edge → OWNER_GAP regardless.
  • Risk (not a defect — but needs the F3 fix to be usable): with the strict §4.6, this makes GOVERNANCE_COVERAGE_PASS FALSE system-wide today, which the pack honestly admits (§4.7). But a gate that is always red is ignored. The F3 severity-aware fix is what makes this baseline actionable (draft-owner = warning = non-blocking-with-deadline), so F5 is resolved by F3 — but only if F3 lands. Flagging the dependency.
  • Hardened wording: none new — explicitly note "§4.3.1 is only usable in combination with the F3 severity-aware gate; otherwise the gate is permanently red and will be bypassed."
  • Acceptance test: with F3 applied, today's baseline yields a PASS for features that touch only draft-owner (warning) objects, while still surfacing the backlog.
  • Open question: see J6 (interim render-owner so MOUT-draft doesn't make every UI feature a high orphan).

F6 — Inheritance closure can hide a broken parent (cycle/depth corner)

  • Original: §4.4 inheritance is bounded-depth, cycle-free (RP walk depth-3). A child is covered if covered(parent).
  • Corner case: if the parent's coverage is itself stale (not re-scanned since its owner went draft, G3), the child inherits a stale TRUE. Inheritance propagates stale coverage downward.
  • Hardened wording: inheritance carries the parent's last_scanned_at and the parent's worst severity down to the child; a child's effective coverage freshness = min(own, parent-chain); a stale parent makes the whole subtree STALE (doc 11 §11.9), not silently covered.
  • Acceptance test: marking a parent stale marks its inheriting subtree stale; the subtree cannot satisfy the production gate while stale.
  • Open question: none.

F7 — Numerical anchor (§4.7) is illustrative but states the gate predicate before F3 — must be re-stated

  • Original: §4.7 computes "current GOVERNANCE_COVERAGE_PASS(system, truth-class) = FALSE" using the pre-F3 predicate.
  • Note: after F3, restate it as "PASS = FALSE because there exist high/critical orphans (agency-orphaned laws 24/26/28/45 = OWNER_GAP high; Direct-PG UNRATIFIED_EXCEPTION critical/QUARANTINED), while the 4 draft owners are warning (tracked, non-blocking)." This is more precise and still honest.
  • Acceptance test: the baseline narrative distinguishes the blocking (high/critical) gaps from the tracked (warning) ones.
  • Open question: none.

F-summary — Branch F verdict

ID Severity Type Disposition
F1 high contradiction define governance grain (container + non-inheriting); leaves not counted
F2 high loophole gate "ignored" as a permanent approved exception
F3 high contradiction severity-aware gate: block on high/critical, track warning
F4 high contradiction (=B5) exception is a separate term, not covered
F5 medium usability resolved by F3; note the dependency
F6 medium corner propagate staleness through inheritance
F7 low restate re-state baseline using severity-aware predicate

The invariant is the best idea in the pack and the most dangerous if imprecise: F1 (grain) + F3 (severity-aware gate) + F2 (ignore gating) are all mandatory before the views are rehearsed (P4), or the identity will close while real gaps hide.

Back to Knowledge Hub knowledge/dev/reports/architecture/one-roof-governance-clause-review-hardening-2026-06-01/06-governance-coverage-invariant-hardening.md