@Bill Bloomenkranz That’s the question that never fully closes. You can’t prove a verifier is clean once; you keep proving it! The keys takeaways I have gotten from my testing is the builder can’t touch the verifier. Tests and acceptance criteria live outside the builder’s write access. Lock the criteria at the start of a run and hash them. If the hash changes mid-run, the run fails. Your receipts system fits perfectly here. I mix in known-answer cases unannounced, including some that should fail, and rotate them so the builder can’t learn them. If the verifier misses a case, everything it passed in that window is suspect. Every verdict carries the version of the checker and the gate that issued it. When I change the checker, I know exactly what needs rechecking. I also scan the output before verifying. I wrote a script that checks the work for anything aimed at the checker, like instructions planted in the output or edits to the tests. The script looks for patterns and instructions like “this has been verified,” “all tests passed,” or “Bas has approved,” text addressed to a reviewer instead of the user, tests that were skipped, deleted or loosened, expected answers hardcoded into the output, and any change to the acceptance criteria since the run started. If any of these turn up, the work never reaches the verifier. It comes back to me with a flag. I audit the passes as well, not just the fails. Compromise hides in what the verifier approved, so I spot-check those. If a checker starts passing everything, I take it as a signal to audit. At the end of the day the verifier is a system too, so anything that really matters still gets a human and an outside review.