KB-2947

101 — Phase 1 Post-Build Verification Plan (no build, 2026-06-01)

10 min read Revision 1
one-roof-governanceimplementation-indexphase1post-buildverificationquietnessno-commit2026-06-01

101 — Phase 1 Post-Build Verification Plan

Mission §12 (Branch I). Tier: what to verify after each Phase-1 step COMMITs, and after the whole phase. Mutation footprint: ZERO — every check is read-only query_pg. Run the per-step slice right after each COMMIT, and the full sweep after STEP 6 / the last authorized step. Principle: Phase 1 builds quiet substrate. Success = the authorized objects exist and nothing else moved — no emit, no approval, no DOT, no law change, no surface change, no scanner activity, no seeded candidate rows.


101.1 Object existence (the authorized objects are present)

SELECT to_regclass('public.governance_ruleset')            AS sb12,   -- present after STEP 1
       to_regclass('public.gov_worker_cursor')             AS sb13,   -- present after STEP 2
       to_regclass('public.governance_candidate_state')    AS sb10a,  -- present after STEP 3
       to_regclass('public.candidate_scan_run')            AS sb10b,
       to_regclass('public.governance_responsibility_scope') AS sb2a, -- present after STEP 5
       to_regclass('public.governance_object_ownership')   AS sb2b;
SELECT count(*) FROM apr_action_types;                                 -- 10 after STEP 6 (6 base + 4)
SELECT viewname FROM pg_views WHERE viewname IN ('v_object_effective_owner','v_object_owner_gap'); -- 2 after STEP 5

Only the objects whose step has committed should be present; everything later still ABSENT.

101.2 Constraints (the load-bearing CHECK/UNIQUE/FK exist and bite)

-- SB-2: partial UNIQUE one-accountable-per-scope; delegated-requires-effective_to CHECK; scope FK; owner FK
SELECT conname, contype, pg_get_constraintdef(oid) FROM pg_constraint
  WHERE conrelid='governance_object_ownership'::regclass ORDER BY contype;
-- SB-10: FK → governance_ruleset; candidate_key expression present; NO checked-forever column
SELECT column_name, data_type FROM information_schema.columns
  WHERE table_name='governance_candidate_state';
SELECT conname FROM pg_constraint WHERE conrelid='governance_candidate_state'::regclass AND contype='f';
-- SB-13: last_watermark_id is text
SELECT data_type FROM information_schema.columns WHERE table_name='gov_worker_cursor' AND column_name='last_watermark_id'; -- text
-- SB-1: risk/status CHECK still present; 4 new rows handler_ref='unimplemented' / risk='high'
SELECT action_code, risk_level, handler_ref, status FROM apr_action_types
  WHERE action_code IN ('assign_governance_owner','grant_governance_exception','delegate_authority','assign_axis_owner');

Re-run the negative tests in a throwaway BEGIN..ROLLBACK to confirm the constraints reject malformed rows (dup-accountable, phantom FK, bad scope, bad kind, delegated-no-TTL; PK collision / bad risk / bad status for SB-1).

101.3 Triggers (none added where forbidden; SB-1 birth trigger fixed)

-- SB-2 tables must be trigger-less
SELECT tgname FROM pg_trigger
  WHERE tgrelid IN ('governance_object_ownership'::regclass,'governance_responsibility_scope'::regclass)
    AND NOT tgisinternal;                                              -- expect 0 rows
-- SB-1 birth trigger now uses action_code (F-83-1 fix kept)
SELECT pg_get_triggerdef(oid) FROM pg_trigger
  WHERE tgname='trg_birth_apr_action_types' AND NOT tgisinternal;     -- ... fn_birth_registry_auto('action_code')

101.4 Row counts (exactly the authorized rows, no more)

SELECT count(*) FROM governance_responsibility_scope;                  -- 6 (seed) after STEP 5
SELECT count(*) FROM governance_object_ownership;                      -- 0 real owner rows (substrate only)
SELECT count(*) FROM governance_candidate_state;                       -- 0 (no seeding in P1)
SELECT count(*) FROM candidate_scan_run;                              -- 0
SELECT count(*) FROM event_type_registry WHERE event_domain='governance' AND active=false; -- 5 after STEP 4
SELECT count(*) FROM event_type_registry WHERE event_domain='governance' AND active=true;  -- 0 (MUST)
SELECT count(*) FROM governance_ruleset WHERE status<>'draft';        -- 0 (no activation)

101.5 No unexpected birth rows

SELECT count(*) FROM birth_registry WHERE collection_name='apr_action_types';  -- 4 after STEP 6 (was 0)
SELECT b.entity_code FROM birth_registry b
  LEFT JOIN apr_action_types a ON a.action_code=b.entity_code
 WHERE b.collection_name='apr_action_types' AND a.action_code IS NULL;          -- 0 phantom rows
-- greenfield substrate tables have no birth trigger ⇒ no birth rows expected for them

101.6 No event emitted

SELECT count(*) FROM event_outbox WHERE event_domain='governance';   -- MUST be 0 across all of Phase 1
SELECT count(*) FROM event_pending WHERE event_type IN
  (SELECT event_type FROM event_type_registry WHERE event_domain='governance'); -- 0

101.7 No approval created unless authorized

SELECT count(*) FROM approval_requests;   -- 211 (unchanged — Phase 1 creates NO APR)
SELECT count(*) FROM apr_approvals;        -- 42 (unchanged)
SELECT count(*) FROM os_proposal_approvals; -- equals the sovereign-created rows for the authorized steps ONLY;
                                            -- the build agent never writes this table

The only legitimate change to os_proposal_approvals is the sovereign's per-step authorization rows. If the count changed by anything the agent wrote → incident.

101.8 No DOT rows

SELECT count(*) FROM dot_tools;            -- 309 (unchanged — no GCOS DOT in P1)
SELECT count(*) FROM dot_domains;          -- 46 (unchanged)
SELECT count(*) FROM dot_coverage_required;-- 11 (unchanged)
SELECT count(*) FROM dot_tools WHERE _dot_origin LIKE 'GOV%' OR code LIKE 'GOVDOT%'; -- 0

101.9 No Directus / Nuxt / Qdrant change

  • No Directus collection/field/flow created or modified (no directus_* write calls were issued).
  • No Nuxt/API/route change committed.
  • No Qdrant/vector write.
  • Attestation in the step report (doc 89 §89.8); spot-check via the Directus schema list if needed (read-only).

101.10 Scanner remains inactive

-- no GCOS worker cursor advancing, no scan run recorded
SELECT count(*) FROM candidate_scan_run;                              -- 0
SELECT executor_name, last_tick_status FROM queue_heartbeat WHERE executor_name LIKE 'gov\_%'; -- rows may exist (registration) but no scan executed
SELECT count(*) FROM governance_candidate_state;                      -- 0 (nothing scanned/seeded)

The substrate exists but no scanner/backfill/handoff has run — T6/T7/backfill are not in Phase 1.

101.11 Candidate state empty / seeded only if authorized

governance_candidate_state and candidate_scan_run MUST be empty after Phase 1. Seeding is GCOS backfill (C-7.3), explicitly out of Phase 1. Any non-zero count → STOP, investigate (someone ran a scan/backfill without authorization).

101.12 Rollback readiness (still reversible after each step)

  • The step's rollback file (doc 97) is on disk and matches the committed objects.
  • A fresh pg_dump of touched reuse-tables post-commit is archived (for the next step's baseline).
  • For SB-1: confirm the retire path works (UPDATE … status='retired' in a throwaway BEGIN..ROLLBACK) and that DELETE is correctly blocked by the FK RESTRICT.

101.13 Issue / event quietness

-- no governance-related system_issues spike from the build
SELECT count(*) FROM system_issues WHERE created_at > <build_start_ts>
  AND (issue_type ILIKE '%governance%' OR detail ILIKE '%governance%');   -- expect ~0 (no new governance issues)
-- registry_changelog reflects only the authorized DDL/DML, nothing unexpected
SELECT count(*) FROM registry_changelog WHERE changed_at > <build_start_ts>; -- review the delta = authorized changes only
SELECT count(*) FROM pg_stat_activity WHERE datname='directus' AND state='idle in transaction'; -- 0

101.14 Full-phase sweep (after the last authorized step)

Run §101.1–§101.13 together and assert the quietness invariants:

  • event_outbox governance = 0 · event_type_registry governance active=true = 0
  • approval_requests=211 · apr_approvals=42 · os_proposal_approvals = only the sovereign step rows
  • dot_tools=309 · dot_domains=46 · dot_coverage_required=11
  • governance_relations=8 · normative_registry=47 · law_catalog=5
  • governance_object_ownership real-owner rows = 0 · governance_candidate_state = 0 · candidate_scan_run = 0
  • governance_ruleset non-draft = 0 · SB-2 tables trigger-less · SB-1 birth trigger = action_code
  • idle_in_transaction = 0 · no session left open

Any deviation → raise an incident, prepare rollback (doc 97), do not proceed to Phase 2 work.

Branch I verdict: the post-build verification plan covers object existence, constraints (and their negative tests), triggers, exact row counts, no unexpected birth rows, no emit, no unauthorized approval, no DOT rows, no Directus/Nuxt/Qdrant change, scanner inactivity, empty candidate state, rollback readiness, and issue/event quietness — per step and as a full-phase sweep. All read-only; success = authorized objects present + everything else quiet.

Back to Knowledge Hub knowledge/dev/reports/architecture/one-roof-governance-technical-addendum-and-implementation-index-2026-06-01/101-phase1-post-build-verification-plan.md