KB-666B

04 — Owner-Resolution & Gap Results (0 effective owners; 18 gap rows = 3 objects × 6 scopes; all no_accountable_owner; honest under-coverage; 2026-06-02)

4 min read Revision 1
one-roof-governancephase1coverage-dry-runf1-readonlyowner-resolutiongaphonest-undercoveragelog-only2026-06-02

04 — Owner-Resolution & Gap Results

Output of S3 (owner resolution) and S4 (gap reproduction). Read-only.

4.1 Owner resolution (S3) — 0 rows

v_object_effective_owner for the 3 subset objects returns 0 rows.

This is the correct inert result: governance_object_ownership is empty (0 rows, doc 01), so the recursive effective-owner view resolves no owner for any object/scope. The path is wired and honestly reports no owner rather than fabricating one.

4.2 Gap reproduction (S4) — 18 rows, all GAP

The production v_object_owner_gap logic (object × active-scope, accountable-owner LEFT JOIN), with the inline inventory substituted, yields 18 rows = 3 objects × 6 active scopes, every row a gap:

object_ref scopes (all GAP / no_accountable_owner)
agents approval, audit, execution, health, policy, render
approval_requests approval, audit, execution, health, policy, render
apr_action_types approval, audit, execution, health, policy, render

The 6 active responsibility scopes: approval, audit, execution, health, policy, render (all status='active').

4.3 Why 18 and not 3

The live v_object_owner_gap definition does inv CROSS JOIN governance_responsibility_scope — so the gap grain is (object × scope), not (object). 3 objects × 6 active scopes = 18. The readiness doc 03 §3.3 headline ("≤3 gap rows") described object grain; the live view fans out per scope. 18 is well within the 38-row hard ceiling, so no abort — but the expectation is corrected here and in doc 06 (finding F-DR-1). Scaled to the full 35 governed collections the gap ceiling is 35 × 6 = 210 rows, not 38.

4.4 Verdict semantics (computed, not stored)

Per doc 06 §6.2 of the readiness pkg, each gap is a log-only finding with computed severity — nothing is written. Example log lines (computed at report time, persisted nowhere):

[DRY-RUN][coverage] object=collection:agents            scope=policy   verdict=GAP reason=no_accountable_owner severity=high(computed)  materiality=above coalesce_key=(agents,policy)
[DRY-RUN][coverage] object=collection:approval_requests scope=approval verdict=GAP reason=no_accountable_owner severity=high(computed)  materiality=above coalesce_key=(approval_requests,approval)
[DRY-RUN][coverage] object=collection:apr_action_types  scope=audit    verdict=GAP reason=no_accountable_owner severity=high(computed)  materiality=above coalesce_key=(apr_action_types,audit)

18 such lines total — one per (object, scope) coalesce grain, below the ≤50-line cap (doc 06 §6.3). Coalescing is the identity here (no duplicates). All "above materiality" because a governed+born object with no accountable owner in an active scope is a real coverage gap.

4.5 Honest-under-coverage confirmation

The path does not produce a false PASS. With empty ownership it returns the maximal honest gap set (every object × every active scope is uncovered). This is exactly the "honest under-coverage" the readiness package required (doc 04 §4 of the readiness pkg; doc 03 §3.7.3). The dry-run thus proves the path is wired correctly and fails safe toward reporting gaps, never toward hiding them.

4.6 Owner-gap verdict

PASS. Owner resolution = 0 (correct, empty ownership). Gap = 18 bounded rows, all explainable as no_accountable_owner, ≤ ceiling. The coverage path is end-to-end sound and honest.

Back to Knowledge Hub knowledge/dev/reports/architecture/one-roof-phase1-coverage-dry-run-f1-readonly-2026-06-02/04-owner-gap-results.md