mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #17] [MERGED] fix(cursor-review): harden judge against parse_error (lenient extraction + retry + panel fallback) (BE-1916) #27
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#27
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/17
Author: @mattmillerai
Created: 6/29/2026
Status: ✅ Merged
Merged: 6/29/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-1916-harden-judge-parse📝 Commits (1)
6d4a388fix(cursor-review): harden judge against parse_error (lenient extraction + retry + panel fallback) (BE-1916)📊 Changes
6 files changed (+394 additions, -49 deletions)
View changed files
📝
.github/cursor-review/extract-findings.py(+101 -32)📝
.github/cursor-review/post-review.py(+9 -0)📝
.github/cursor-review/prompt-judge.md(+5 -0)➕
.github/cursor-review/tests/test_extract_findings.py(+148 -0)📝
.github/workflows/cursor-review.yml(+93 -17)➕
.github/workflows/test-cursor-review-scripts.yml(+38 -0)📄 Description
ELI-5
Sometimes the "judge" model that combines all the reviewers' notes answers in
plain English ("Based on my review, I think…") and then pastes the JSON we
need. Our old parser only knew a couple of rigid ways to find that JSON, so it
choked on the prose, threw everything away, and the whole PR review showed up as
a scary "Review failed" — even when the judge's answer was actually correct
(this happened on ComfyUI #487 and Alex's PR). This PR teaches the pipeline to
(1) dig the JSON out of the prose, (2) politely ask the judge once more if it
still can't, and (3) if even that fails, show the raw reviewer notes instead of
a blank failure.
What changed
Three layers, cheapest first, all in the cursor-review judge path:
Lenient extraction (
extract-findings.py) —parse_json_findingsnowrecovers JSON wrapped in prose via a string/escape-aware balanced
brace-scan for the first
{…}/[…]region that actually parses, insteadof the old naive first-
[/last-]slice (which broke the moment the prosecontained a stray bracket — exactly the #487 shape). New
coerce_findings_listalso unwraps a
{"findings": […]}-style object. The fast path (clean JSON)and the fenced-
jsonpath are unchanged.Retry once (
cursor-review.yml→ Run judge) — after the judge runs weprobe-parse its output; on a hard parse failure we re-run the judge exactly
once with a terse "Return ONLY the JSON array, no prose" reminder appended.
No loop — one retry, then we stop.
Tighten the judge prompt (
prompt-judge.md) — a bare-JSON-array demand isnow the first line of the prompt.
Plus the degraded fallback: if the judge still can't be parsed after the
retry and the panel produced findings, we post the raw, de-duplicated per-cell
findings under a warning banner — never a bare "Review failed" when there
are real findings to show. A genuine total failure (no panel findings either)
still surfaces the honest error review.
Acceptance criteria
parse_json_findings+ balanced scan; regression-tested..github/cursor-review/tests/test_extract_findings.py(test_prose_wrapped_array_487+ 13 more).Testing
python3 -m unittest discover -s .github/cursor-review/tests→ 14 tests, all green. New CI workflowtest-cursor-review-scripts.ymlruns them on any change under.github/cursor-review/**.post-review.py --noticeagainst a stubgh: the degraded path posts a real review with inline comments + banner, not "Review failed".Judgment calls / not done
enabled. The judge is invoked through the
cursor-agentCLI, which has noreliable per-model knob to force the findings array shape;
--output-format jsonwraps stdout in cursor-agent's own envelope, which would break theexisting parser. Flipping it blind is a net regression risk, so I relied on the
prompt tightening + the strict-JSON retry (which is structured-output pressure
at the prompt level) + the lenient parser. The acceptance criteria are met
without it. Happy to revisit if a confirmed JSON-mode flag exists.
standalone valid JSON array of scalars before the real findings array, the
scanner could pick the wrong one. This is contrived (covered case: prose with a
non-JSON
[…]recovers correctly, tested), strictly better than the oldbehavior, and backstopped by the retry + prompt. Not over-engineered.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.