KB-D809

F-3 Consolidation Rollback-Only Coverage Dry-Run — 06 Negative Tests

5 min read Revision 1
one-roofphase-1f3negative-testsuniquefkcheckfail-closed

06 — Negative Tests (FK / CHECK / UNIQUE rejection)

Live output of N1–N7. Each isolated in its own SAVEPOINT … <failing insert> … ROLLBACK TO SAVEPOINT, so the expected error never aborts the transaction. ON_ERROR_STOP toggled off for this block, back on after. Objective 9 (invalid row rejected) — exceeded: 7 distinct rejections, one more than F-2 (added the lifecycle CHECK).

6.1 Results

# Constraint exercised Insert attempted Server error (verbatim) Verdict
N1 partial-UNIQUE uq_gov_obj_accountable 2nd active accountable for workflows/policy duplicate key value violates unique constraint "uq_gov_obj_accountable" · Key (object_type, object_ref, scope)=(collection, workflows, policy) already exists. ✅ rejected
N2 FK …_owner_gov_code_fkey owner GOV-PHANTOM (not in registry) violates foreign key constraint "governance_object_ownership_owner_gov_code_fkey" · Key (owner_gov_code)=(GOV-PHANTOM) is not present in table "governance_registry". ✅ rejected
N3 FK …_scope_fkey scope nonexistent_scope violates foreign key constraint "governance_object_ownership_scope_fkey" · Key (scope)=(nonexistent_scope) is not present in table "governance_responsibility_scope". ✅ rejected
N4 CHECK …_owner_kind_check owner_kind='owner' (not in enum) violates check constraint "governance_object_ownership_owner_kind_check" ✅ rejected
N5 CHECK chk_delegated_ttl owner_kind='delegated', effective_to=NULL violates check constraint "chk_delegated_ttl" ✅ rejected
N6 CHECK …_lifecycle_status_check (new in F-3) lifecycle_status='pending' (not in enum) violates check constraint "governance_object_ownership_lifecycle_status_check" ✅ rejected
N7 FK …_ruleset_version_fkey (candidate fail-closed) governance_candidate_state with ruleset_version='RULESET-DOES-NOT-EXIST' violates foreign key constraint "governance_candidate_state_ruleset_version_fkey" · Key (ruleset_version)=(RULESET-DOES-NOT-EXIST) is not present in table "governance_ruleset". ✅ rejected

6.2 What each proves

  • N1 — the one-accountable-per-(object,scope) invariant is enforced by the partial-unique index; a second accountable owner cannot be created. This is why E6 (doc 05) returns 0 on the real store. (Here exercised on workflows/policy, which already holds the D2 direct owner.)
  • N2/N3 — ownership cannot reference a non-existent governance actor or responsibility scope; the owner taxonomy and scope set are closed.
  • N4owner_kind is restricted to {accountable, supporting, delegated, exception}; arbitrary roles rejected.
  • N5 — a delegated owner must carry an expiry (effective_to); delegation cannot be perpetual — TTL is structurally mandatory.
  • N6 (new)lifecycle_status is restricted to {active, superseded, revoked, expired}; an ad-hoc 'pending' is rejected. Confirms the ownership lifecycle is a closed enum, complementing the supersession model.
  • N7fail-closed candidacy: a candidate verdict cannot exist without a registered ruleset version. Verdicts are always anchored to a known ruleset (the decaying-candidacy design depends on it).

6.3 Transaction survived all seven

After each ROLLBACK TO SAVEPOINT the transaction stayed alive and the next step ran (the INTX_OUT_OF_SCOPE and INTX_TRANSIENT_PERSISTED probes after the negative block both returned — doc 07). No negative-test row persisted: the final ROLLBACK + the independent post-run census confirm governance_object_ownership=0 and governance_candidate_state=0.

Note on output interleaving: under 2>&1, psql flushes the seven ERROR:/DETAIL: lines (stderr) at buffer boundaries, so they appear grouped rather than each directly under its \echo. Pairing is unambiguous — each error names the exact constraint expected for its N-step, and all 7 expected constraints appear exactly once.

6.4 Negative-test verdict

PASS (exceeded). 7 of 7 invalid rows rejected by the exact constraint intended — UNIQUE, two FKs, three CHECKs (owner_kind, delegated-TTL, lifecycle), and one fail-closed candidate FK. The substrate's integrity rails are live and enforced at the broader scope.

Back to Knowledge Hub knowledge/dev/reports/architecture/one-roof-phase1-coverage-dry-run-f3-consolidation-rollback-only-2026-06-02/06-negative-tests.md