Authority P1 Hardening — 02 Scanner Auto-Apply Control
02 — Scanner Auto-Apply Control
Scanner request path (live)
- Creators (host cron):
dot-orphan-scanner(daily 02h30 CEST) anddot-misclass-scanner(Sunday 03h00) insert pendingapproval_requestswithrequest_type IN (birth_orphan, reclassify),proposed_action_code = NULL. - Applier:
auto_apply_approval()(host cron daily 04h30 CEST) selected pending orphan/misclass rows and updated them toapplied— historically with no vote. - Other executor:
dot-apr-execute --localevery 5 min — currently failing (curl(7) connect localhost:8055, Directus path down), so applying nothing. - pg_cron is NOT installed; all scheduling is host crontab.
Inventory (live, view v_scanner_auto_apply_inventory)
| Source / class | total | applied | pending now | applied zero-vote |
|---|---|---|---|---|
| dot-orphan-scanner | 143 | 143 | 0 | 143 |
| dot-misclass-scanner | 18 | 17 | 0 | 17 |
| reviewed_by=auto-apply-function (bypass-ledger subset) | 18 | 18 | — | 18 |
| reviewed_by=orchestrator-s142b (sanctioned batch, NOT auto-bypass) | 142 | 142 | — | 142 |
Honesty note: the by-source population (orphan 143 + misclass 17 = 160) is larger than the bypass ledger because 142 of the orphan applies were performed by orchestrator-s142b (a sanctioned S142b batch run, reviewed_by=orchestrator), not by the auto-apply-function auto-bypass mechanism. Only 18 scanner rows were applied by auto-apply-function with no vote; those 18 are the back-audit "scanner_apply_without_vote" class. Nothing is hidden — the full reviewed_by breakdown is exposed in the inventory view and in 04.
Patch options considered (view v_scanner_apply_control_patch_plan)
| Option | Description | Decision |
|---|---|---|
| A | scanner requests default to pending/review | not chosen (insufficient: apply path stayed ungated) |
| B | auto-apply only for low-risk/no-side-effect classes | deferred-owner (needs allowlist authoring) |
| C | auto-apply requires explicit allowlist + quorum proof | deferred-owner (needs owner authority) |
| D | block scanner apply when no vote (fail-closed quorum gate) | CHOSEN — APPLIED |
Applied control (reversible)
auto_apply_approval() now checks quorum_passed(rec.code) per row at the top of its loop; rows without proven quorum are skipped with an audit note (Auto-apply SKIPPED ...: quorum/authority not proven), and never produce side effects. Because scanner rows carry proposed_action_code = NULL, quorum_passed returns false for them, so the function applies nothing without genuine votes. Behavior is unchanged for today's run (still returns 0; no matching pending rows) but is now fail-closed for any future scanner output. Defense-in-depth: even if this function were reverted, the data-layer apply-time re-proof (03) independently blocks the apply.
Status (view v_scanner_apply_control_status)
control_state = CONTROLLED; apply_layer_reproof_active = true; pending_scanner_rows_now = 0; historical_scanner_applied (auto-apply-function) = 18. No-go guard v_scanner_auto_apply_no_go_guard: 3/3 PASS.
Forbidden boundaries respected
The scanner cron jobs and the scanner binaries were NOT modified or disabled; the host crontab was NOT touched; no historical scanner row was deleted or rewritten. Only the DB apply function was made fail-closed.