overview / rules / red-suite-test-write
red-suite-test-writeThe suite is red and this writes to the file that decides whether it is green.
red-suite-test-write — while the suite is red, any write to a test/harness file is refused, weakening or not: an added assertion that encodes the broken behaviour passes test-tamper and is the same move. On a green suite the identical write goes through untouched, because editing tests is the most valuable thing an agent does. If the test really is the thing that is wrong, one command says so and lets the next write through, once: rabadon wrong red-suite-test-write "why the test is wrong".
From README.md.
Red-suite-test-write: a red suite closes the test file. Runs AFTER test-tamper, so the sharper refusal (a skip marker, a lost assertion) speaks first. This one refuses any write to a file that decides green while the suite is red, weakening or not: an added assertion that encodes the broken behaviour is the same move. When the test really is wrong a human should look, and the way out is named in the refusal: rabadon wrong red-suite-test-write "<why the test is the wrong thing>" which records WRONG_REFUSAL on the ledger and leaves a one-shot pass. The green side is untouched: editing tests on a passing suite is ordinary work.
From the comment in native/gate_pre.h above the code that decides it.
testPaths — regexes for what counts as a test file. This arms the test-tamper detector: while the suite is red, an edit that weakens a test file is refused. It also arms red-suite-test-write: while the suite is red, any write to a file matched here is refused, weakening or not. That is a wider net than test-tamper on purpose — "make the judge say yes" does not have to look like weakening — and it has a known false-positive class: sometimes the test is the thing that is wrong. That case has one command, named in the refusal itself: rabadon wrong red-suite-test-write "why the test is wrong". It writes WRONG_REFUSAL on the same hash-chained ledger as the refusal, so this rule's false-positive count is read rather than asserted, and it leaves a one-shot pass: the next write goes through (OVERRIDE_USED on the ledger) and the one after that is refused again. On a green suite the rule is silent.
From docs/guard.md.
Rendered from the strings in native/gate_pre.h, the rule and the envelope (Judge::refuse) both. A word in <angle brackets> is filled in from the command at the moment it is refused.
Only the user can switch it off, by id, in the project's guard:
or by pausing supervision with rabadon off, which records the change. Every other rule keeps running.
1 of the 778 records in the published field dataset (field.jsonl, 2026-07-27 to 2026-08-26) carries this id. STOP is a refusal in enforce mode; WOULD_BLOCK is the same verdict recorded in watch mode, where nothing is stopped.
| event | records |
|---|---|
| WOULD_BLOCK | 1 |
Counted from field.jsonl, the file the field page is built from.