mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #31] [MERGED] fix(cursor-review): recover judge findings after prose, not first JSON region (BE-3160) #44
Labels
No labels
cursor-review-catalog-drift
groom
groom
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/github-workflows#44
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/Comfy-Org/github-workflows/pull/31
Author: @mattmillerai
Created: 7/16/2026
Status: ✅ Merged
Merged: 7/17/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-3160-judge-parse-hardening📝 Commits (1)
8449eb2fix(cursor-review): recover judge findings after prose, not first JSON region (BE-3160)📊 Changes
4 files changed (+133 additions, -169 deletions)
View changed files
📝
.github/cursor-review/extract-findings.py(+47 -24)📝
.github/cursor-review/prompt-judge.md(+6 -0)📝
.github/cursor-review/tests/test_extract_findings.py(+49 -0)📝
.github/workflows/cursor-review.yml(+31 -145)📄 Description
ELI-5
The "judge" AI that combines our 8 code-review opinions into one is supposed to
answer with only a JSON list. On some PRs it instead starts talking first
("Verification changes my adjudication…", "Shell execution isn't available
here…") and puts the real JSON list after that chatter. Our parser grabbed the
first JSON-ish thing it saw and quit — which was a stray object or list from
the chatter — so it declared "couldn't parse" and posted "Review failed"
even though the real answer was sitting right below. This teaches the parser to
keep looking and take the last real findings list, and tells the judge to
stop narrating. Now the review lands instead of failing.
What changed
.github/cursor-review/extract-findings.pyparse_json_findingsnow scans every embedded JSON region and keeps thelast findings-shaped one, instead of returning the first region that
merely parses. This is the core fix: on verification-heavy diffs the judge
emits prose first and the array last, so "first that parses" grabbed the wrong
thing.
coerce_findings_listnow requires array elements to be objects, so ascalar list the judge quotes in prose (e.g.
["contains","startswith"]whilenarrating jq builtins — the PR-146 shape) can't masquerade as findings.
.github/cursor-review/prompt-judge.md+ the retry reminder in.github/workflows/cursor-review.ymlverification or tool attempts — cutting the prose drift at the source. (The
judge's own PR-146 output, "Shell execution isn't available here", is the
evidence the tools genuinely aren't present in this stdin-piped run.)
.github/cursor-review/tests/test_extract_findings.pyarray) and PR-146 (inline scalar list in prose, then real array) shapes,
plus last-block-wins and scalar-list-rejection. Suite: 19 tests, all green.
Root cause
parse_json_findingsreturned the firstlist/dictthatjson.loadsaccepted and stopped. Reproduced against the two captured openings:
{...}then real arrayparse_error(dict had nofindingskey)The BE-1916 judge retry already existed but didn't help 145/146: those diffs
reliably re-trigger the prose mode, so the retry re-hit the same extraction bug.
With extraction fixed, both the first attempt and the retry now succeed.
Acceptance criteria
test_verification_prose_then_array_is_ok_be3160(assertsstatus == ok).the failure notice — ✅ the retry (BE-1916,
cursor-review.yml"Run judge")is preserved; genuinely un-parseable output still probes
!= okand retriesonce, now with a stricter no-tools reminder. This change is what makes the
retry effective on the 145/146 class.
⏳ post-merge runtime step, not verifiable from this PR: it requires
consumer repo
mattmillerai/agent-workto pin itsworkflows_refto a refcontaining this change (or
@main) and a label cycle on those PRs. Once thismerges, cycle
cursor-reviewon #145/#146 to confirm.Testing
python3 -m unittest discover -s .github/cursor-review/tests -p 'test_*.py'→ 19 passed (the CI command in
test-cursor-review-scripts.yml).python3 -m py_compileon the script + YAML parse of the workflow: clean.Notes / judgment calls
extract-findings.pyis shared by theper-cell panel steps too, not just the judge. The stricter "findings are
arrays of objects" + "last valid wins" behavior is equally correct for cells
(their prompts also demand a JSON array of objects), so this is a net
robustness gain across the board, not a judge-only patch.
coerce_findings_listtightening now rejects a list containing non-objectelements (previously returned as-is). A mixed/scalar list is malformed for
this schema anyway; rejecting it routes to the retry rather than posting
garbage — the intended behavior.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.