Past a certain number of failed review rounds, a fix for one finding starts reintroducing an earlier one. A hard ceiling that stops the lane and escalates beats letting it iterate its way into a worse diff.
I used to let a review loop run until it passed, on the theory that it would eventually converge — each round would fix what the last round flagged, and the diff would get closer to correct with every pass. What I actually saw, often enough that I stopped treating it as an anomaly, is the opposite: past a certain number of failed rounds, the diff does not converge, it thrashes. A fix for round three’s finding reintroduces round one’s problem in a different form, the reviewer duly flags it again, and you are no longer iterating towards correct — you are oscillating around it.
The reason this happens is that each round is a patch applied under time pressure to satisfy one specific criticism, not a redesign that holds the whole problem in view. A model asked to fix one finding will fix that one finding, sometimes with the narrowest change that makes the complaint go away — and the narrowest change is exactly the kind that breaks something adjacent the reviewer has not looked at yet. Repeat that enough times and you have spent several rounds of review effort making the code worse in aggregate, even though every individual round technically addressed its finding.
So the rule I actually enforce now is a hard ceiling — a fixed number of failed review rounds on the same task, after which the lane stops, fully, and the problem gets escalated rather than re-attempted. Not paused for a status check, not given one more try because it is close. Stopped, because the evidence at that point is that this configuration — this model, this framing, this level of context — is not going to reach a real pass by iterating harder, and the next round is more likely to cost correctness than buy it.
This feels wrong the first time you enforce it, because you are stopping something that is almost there by the reviewer’s own count — two findings left, down from six. But almost-there by finding count is not the same as almost-there in practice, if the two remaining findings are the ones the last four rounds kept re-breaking each other over. Finding count is a poor proxy for convergence. Round-over-round diff stability is the real signal, and a ceiling is the mechanism that stops sunk-cost optimism from letting you ignore it.
What happens after the stop matters as much as the stop itself. A ceiling that just abandons the task is worse than no ceiling at all — the value is in escalating to something that can actually reason about the whole problem: a different model, a human, a redesign of the approach rather than another patch. The ceiling is not a way to give up. It is a way to notice, on a fixed and enforced schedule rather than an optimistic one, that patching has stopped working and something else needs to happen instead.
There is a second reason to stop, and it has nothing to do with the diff. After several rounds the reviewer is no longer grading the change on its merits — it is grading a change that was shaped, round by round, by its own earlier comments, and a reviewer marking work built specifically to satisfy its last complaint is not an independent check any more. The findings get narrower and more procedural, because the obvious ones were spent in round one, and a clean pass on round seven means something considerably weaker than a clean pass on round two would have meant. The ceiling protects the reviewer’s signal as much as it protects the code.
The uncomfortable part of this, and the reason I hold it as a hard rule rather than a guideline, is that I am exactly the person who will talk myself out of it in the moment — one more round is always available and always feels cheap. A ceiling only works if it is enforced regardless of how close the last round looked, because how close it looked is precisely the judgement that has been wrong for the last three rounds running.