KB-172E

07 — Fail-Closed Test Plan (no APR-0415 vote)

3 min read Revision 1

07 — Fail-closed test plan (NO APR-0415 approval recorded)

Because dot-apr-approve is not built/deployed (HOLD), the mutating tests are specified, not executed. The only test runnable read-only this turn is the APR-0415 dry-check, which records no vote.

Required fail-closed cases (each must REJECT / no-write)

# case expected
T1 wrong token reject — auth fail, no row
T2 missing token reject — no anonymous vote
T3 claim president with an ai_council token reject — seat mismatch (G3/G4)
T4 claim ai_council_1 with president token reject — seat mismatch
T5 duplicate vote (same apr_id, approver) no-op/reject — UNIQUE(apr_id,approver), never double-count (G6)
T6 missing/empty rationale reject (G7)
T7 approve a non-pending APR reject (G2)
T8 approve own APR when proposer known reject — self-approval (G5)
T9 reject vote recorded as decision='reject'; blocks quorum downstream (G9)
T10 APR-0415 dry-check only read-only; no vote recorded
T11 null-proposer self-approval (APR-0415 shape) reject unless explicit override rationale + self_approval_risk flag (G5, file 06)
T12 caller secret resolves to operator/root reject — no convenience approval (G11)
T13 invalid input (bad decision / bad type / 2 APRs) reject; no PASS/seal emitted (anti-overclaim)

T10 — the only test executed this turn (read-only)

quorum_passed('APR-0415')                 = false
fn_pa_president_vote_present('APR-0415')   = false
apr_approvals WHERE apr_id=415             = 0 rows   (unchanged, before==after)
vote recorded                              = NONE

APR-0415 was only inspected. No approve/reject row was written. This satisfies macro §6 ("APR-0415 dry-check only, no vote recorded") and the hard lock.

Execution status

T1–T9, T11–T13 (mutating) ... NOT RUN — tool not deployed (HOLD). Specified for the post-warrant session.
T10 (read-only) ............. RUN — passed (no vote recorded).

Acceptance rule for the future run: if ANY invalid input emits a PASS/digest/seal, or any vote is double-counted, or any anonymous/operator vote is accepted → REJECT the build (GOVERNED_C1_DRYRUN_REJECT_*), do not deploy.