Problem
The executed check's exit code is the only verdict ringer records. When the check itself is wrong (over-strict grep, unsatisfiable assertion), the FAIL lands on the model's eval row, and since first_try_pass_rate drives the promotion ladder, check bugs demote models invisibly.
The only correction channel today is a prose annotation in docs/MODEL-NOTES.md - human-read, not machine-read. The scoreboard math never hears about it.
Evidence
- Run
stm-nav-restructure (2026-07-17): two recorded FAILs (task-05-pipeline-trim-admin, task-09-condense-tableau) were orchestrator check bugs; the worker output was audited fully correct both times. One check's negative phrase-grep matched the exact link-out stub the spec requested; the other demanded a repo state the spec forbade the worker from creating.
docs/MODEL-NOTES.md already carries at least three earlier "recorded FAIL was a check bug" annotations from other runs - this is a recurring class, not a one-off.
Proposal
Append-only amendment rows, written by an explicit command, excluded from aggregation:
./ringer.py amend <run_id> <task_key> --reclassify check_bug --note "why"
- Appends
{"type": "amendment", "run_id", "task_key", "reclassify", "note", "amended_at", "identity"} to runs.jsonl; never edits existing rows.
aggregate_model_log_rows (ringer.py:5357) skips attempts whose (run_id, task_key) is amended; groups gain a visible amended count on the models table and HTML page.
- Amendment covers the whole task (all attempts) - if the check was wrong, everything it graded is meaningless.
- Non-goal: auto-detecting check bugs. Attribution requires judgment; the command trusts its caller and requires the
note for the audit trail.
Full design note with schema, touch points, and acceptance criteria: docs/AMENDMENT-ROWS.md (committed alongside a planned patch).
Problem
The executed check's exit code is the only verdict ringer records. When the check itself is wrong (over-strict grep, unsatisfiable assertion), the FAIL lands on the model's eval row, and since
first_try_pass_ratedrives the promotion ladder, check bugs demote models invisibly.The only correction channel today is a prose annotation in
docs/MODEL-NOTES.md- human-read, not machine-read. The scoreboard math never hears about it.Evidence
stm-nav-restructure(2026-07-17): two recorded FAILs (task-05-pipeline-trim-admin,task-09-condense-tableau) were orchestrator check bugs; the worker output was audited fully correct both times. One check's negative phrase-grep matched the exact link-out stub the spec requested; the other demanded a repo state the spec forbade the worker from creating.docs/MODEL-NOTES.mdalready carries at least three earlier "recorded FAIL was a check bug" annotations from other runs - this is a recurring class, not a one-off.Proposal
Append-only amendment rows, written by an explicit command, excluded from aggregation:
{"type": "amendment", "run_id", "task_key", "reclassify", "note", "amended_at", "identity"}toruns.jsonl; never edits existing rows.aggregate_model_log_rows(ringer.py:5357) skips attempts whose(run_id, task_key)is amended; groups gain a visibleamendedcount on themodelstable and HTML page.notefor the audit trail.Full design note with schema, touch points, and acceptance criteria:
docs/AMENDMENT-ROWS.md(committed alongside a planned patch).