-- Self-check failures per address (see -- docs/changes/2026-10-04_08-01_self-check-exclude-validator-plan.md). -- -- A failed self-check no longer sends the address back to the validator that -- failed it: ClaimNextQueued skips an address for every validator that failed -- it in the current round. ip_self_check_failures is the permanent history of -- those failures; it is keyed by registry_id (like checks and events), so it -- outlives the ip_queue row and is not touched by re-checks. No foreign keys -- on purpose: the manual cleanup in docs/ADMIN_CLEANUP.md deletes freely. -- -- A round is the part of a series of failures in which validators that failed -- stay excluded. ip_queue.sc_round_start_cycle is the first cycle_id of the -- current round: a failure excludes its validator only if its cycle_id is not -- below it. cycle_id (not attempt_number) is used because it never repeats for -- an address, even when the ip_queue row is deleted and created again. -- -- ip_queue.sc_failures counts self-check failures of the current series; a -- manual re-check or re-submission starts a new series. -- -- settings.self_check_max_attempts is the ceiling of self-check failures per -- address, after which the address gets the verdict fail (1..50, default 5). CREATE TABLE ip_self_check_failures ( id INTEGER PRIMARY KEY AUTOINCREMENT, registry_id INTEGER NOT NULL, run_id INTEGER, cycle_id INTEGER NOT NULL, attempt_number INTEGER NOT NULL, validator_id TEXT NOT NULL, failed_at TIMESTAMP NOT NULL, detail TEXT NOT NULL DEFAULT '' ); CREATE INDEX idx_sc_failures_registry ON ip_self_check_failures(registry_id, validator_id); ALTER TABLE ip_queue ADD COLUMN sc_failures INTEGER NOT NULL DEFAULT 0; ALTER TABLE ip_queue ADD COLUMN sc_round_start_cycle INTEGER NOT NULL DEFAULT 0; ALTER TABLE settings ADD COLUMN self_check_max_attempts INTEGER NOT NULL DEFAULT 5;