You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
classify-review-verdict: a verdict that correctly disclaims being a fully-clean claim is read as needs-more-work, failing require-clean-verdict on an approving review #849
review / require-clean-verdict failed on Morrison-Lab/ai-config#3361 at 3dc2ad75 (run) over a review whose stated verdict is Ready for merge and whose findings list is empty.
The reviewer did everything right. It ran check-pr-fully-clean.py, saw validate and review / claude-review still in_progress, and — following the brief's own verdict-semantics instruction, which it quotes — distinguished a content verdict on the diff from a fully-clean claim about the PR. That distinction is what the classifier reads as a rejection.
Reproduction
Fetched the exact comment body and ran the shipped classifier against it:
"it is not a claim that the PR is fully clean end-to-end" → "it describes the diff only"
clean=true ready-for-merge
verdict section alone
clean=false
So it is not the opening prose and not the stopping-point line. It is a negated positive inside the verdict section, which the last-match-wins scan picks over the **Ready for merge** line above it.
Why this is not simply the classifier being wrong
The classifier is behaving to its documented contract: the verdict section must state an affirmative clean conclusion and not state an unnegated rejection, and a negated positive counts. NOT_CLEAN (#827) and payload finding-vocabulary (#819) are the same mechanism. Narrowing the keyword list would re-open those.
The defect is a tension between two instructions, not a bug in either:
The review brief tells the reviewer to qualify a verdict when checks are still in flight ("checks that are merely queued or in progress alongside you are the merge gate's business, not the verdict's").
The classifier forbids expressing that qualification inside the verdict section.
A reviewer that follows the first faithfully fails the second. The more careful the reviewer, the likelier the false red — which is the wrong incentive gradient.
Teach the brief a fixed form for a scope-limited verdict that carries no negated positive — e.g. "Ready for merge (diff content; merge gate pending)" — so the qualification survives the scan. Cheapest to state, but it is a convention the reviewer has to remember, which is the weakest kind of mechanism.
I have no strong view between 1 and 2; 1 looks like it removes the class rather than this instance.
Impact
Every consumer running review / require-clean-verdict as a required check. A false red here blocks merge on an approving review, and the failure reads as a genuine not-clean verdict to anyone who does not open the classifier.
Filed by Claude Code (AI agent) --- not written by a human. Encountered while running a UMS pass on ai-config#3361; that PR is currently blocked by this.
What happened
review / require-clean-verdictfailed on Morrison-Lab/ai-config#3361 at3dc2ad75(run) over a review whose stated verdict is Ready for merge and whose findings list is empty.The reviewer did everything right. It ran
check-pr-fully-clean.py, sawvalidateandreview / claude-reviewstillin_progress, and — following the brief's own verdict-semantics instruction, which it quotes — distinguished a content verdict on the diff from a fully-clean claim about the PR. That distinction is what the classifier reads as a rejection.Reproduction
Fetched the exact comment body and ran the shipped classifier against it:
Bisected by substituting one clause at a time. Exactly one flips it, and it is inside the verdict section:
clean=false needs-more-workclean=false(irrelevant)clean=false(irrelevant)clean=true ready-for-mergeclean=falseSo it is not the opening prose and not the stopping-point line. It is a negated positive inside the verdict section, which the last-match-wins scan picks over the
**Ready for merge**line above it.Why this is not simply the classifier being wrong
The classifier is behaving to its documented contract: the verdict section must state an affirmative clean conclusion and not state an unnegated rejection, and a negated positive counts.
NOT_CLEAN(#827) and payload finding-vocabulary (#819) are the same mechanism. Narrowing the keyword list would re-open those.The defect is a tension between two instructions, not a bug in either:
A reviewer that follows the first faithfully fails the second. The more careful the reviewer, the likelier the false red — which is the wrong incentive gradient.
Relationship to prior issues
checks: read) is what made the reviewer able to read CI at all.review-datapayload, so it fell through to the prose scan. Had it emitted one with"verdict": "CLEAN", classify-review-verdict: triage-exemption verdict ("No action -- does not need code review") reads as unrecognized while review-data says CLEAN #845's precedence would have classified it correctly and this would not have fired.That last point suggests the cheapest fix.
Suggested directions, roughly in order of cost
review-datais immune to every prose-scan trap, this one included. The failing review simply omitted it. This needs no classifier change.I have no strong view between 1 and 2; 1 looks like it removes the class rather than this instance.
Impact
Every consumer running
review / require-clean-verdictas a required check. A false red here blocks merge on an approving review, and the failure reads as a genuine not-clean verdict to anyone who does not open the classifier.Filed by Claude Code (AI agent) --- not written by a human. Encountered while running a UMS pass on ai-config#3361; that PR is currently blocked by this.