A test input of zero cannot see a bit stuck at zero
5,942 runs measured what the known-answer test catches on a lone replica. Stuck results, all of them. Stuck bits, about half, and the half is by construction.
The known-answer test is the last replica’s only check: a fixed input whose answer is known, every 64 ticks. A new fault holds one bit at 0 or 1 from a given tick, in the input, the 4 KB working block, the hash accumulator or the result, and it applies to the test too, so the test runs on the same broken hardware.
The campaign kills two replicas, injects one fault into the last, and records whether it was caught, how long that took, and how many wrong results went out first. 5,942 runs in 295 seconds. A stuck result: caught every time, 31.5 ticks on average, 15.5 wrong results before it. A hang: every time, within a tick. A stuck bit in the result: 50%. In the accumulator: 98%. In the working block: 46%. In the input: 50%, and some of the misses there deliver wrong results.
The halves are not chance. The test input is zero, so a bit stuck at zero in the input is invisible by construction. One input sees about half of the stuck-at bits. A second test input would close most of the gap. It is planned, not built, and the README says which.
The campaign found a bug on the way. In self-check mode the voter computes on even ticks only, and a corrupt fault scheduled for an odd tick was set for that tick alone, so it never reached the replica. Before: detected 0, caught 0. After: 1 and 1.
The test at every 64 ticks costs 1.9% of throughput, within noise. At every 8 it costs 22%. The README now splits what is proved per decision from what is tested per run. Never less than fixed TMR over a whole run is on the second list.