96% of developers don't fully trust AI-generated code. Only 48% of them verify it before it ships.
That number — from Sonar's 2026 survey — is the reason this product exists. The whole pitch is that you see every AI change as a diff before it touches your project.
Last week I found out our review gate was off by default.
The feature worked. Nobody met it.
The mechanism was never the problem. The agent is intercepted at the tool boundary, before anything reaches disk. You get a real unified diff — old line, new line, gutters, line numbers. It waits. There is no timeout, because a user who walked away has not approved anything.
There is also an "Approve the rest" button, and that is deliberate. A cold build writes dozens of files. Asking dozens of times produces rubber-stamping, which is measurable: repeat reviewers of agent changes approve more often over time while commenting less. A gate without a one-click exit does not prevent that. It just makes people angrier while they do it.
All of that shipped and worked. And reviewChanges defaulted to false.
So a new user got the same write-without-asking behaviour as every prompt-to-app tool we describe as the problem. We had quietly joined the 52% who do not verify.
I found it the only way this class of bug can be found: by running a real build and watching the agent create a file in the workspace without asking me a single question.
Two things underneath were worse
The diff you approved was not always the diff that got written
The gate ran on the original tool arguments. Hook modifications — our own pre-write hooks, which can rewrite file content — were applied after the user answered.
So if a hook rewrote content, you approved one change and a different one reached disk.
That was survivable while review was opt-in and rarely on. It is not survivable as the default, because the entire promise is that the bytes you saw are the bytes that land. The order is now: safety hooks, then hook modifications, then user review of the final arguments, then write.
One retry ended the whole run
When a user rejects a change, the model sometimes re-proposes it. We cap that. The constant reads:
const MAX_REPEATS = 2; // repeats allowed before the turn is ended outright
The check read seen + 1 >= MAX_REPEATS, and seen is already the count of previous rejections. So the first repeat satisfied it, and the orchestrator turns that into a full run abort.
One innocuous retry killed everything the user was doing.
The existing test asserted that the third request stopped the run. It never asserted the second one did not. That assertion exists now.
What I actually take from this
A feature flag defaulting to off is indistinguishable from never having built the feature. Your tests pass either way. Your changelog says you shipped it either way. Nothing in your pipeline knows the difference between "built" and "reachable".
61% of developers say AI produces code that looks correct but is not — silent failures. A review gate that quietly defaults to off is exactly that failure mode, turned on your own product.
The fix was one boolean. Finding it took running the thing like a user and watching what it actually did.
It is on by default now
Review is armed for every new run. Changes is a first-class tab that selects itself when the agent stops, so a gate firing while you are looking at the preview cannot read as a stalled build.
I verified it by running a build in production and watching it stop, then checking the file on disk to confirm that rejecting left it untouched and approving wrote exactly what the diff showed.
If you want to try breaking it, it is free and there is no card: nocoder.codes. I would rather you find the next one than not.