mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #395] [MERGED] feat(cursor-approve): make the card say WHY, and split "nothing to judge" out of yellow #398
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#398
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/395
Author: @mattmillerai
Created: 10/9/2026
Status: ✅ Merged
Merged: 10/9/2026
Merged by: @mattmillerai
Base:
main← Head:matt/axis-na-and-headline📝 Commits (2)
5e41a5afeat(cursor-approve): make the card say WHY, and split "nothing to judge" out of yellow0b45dfetest(cursor-approve): pin that the headline reaches the uploaded artifact📊 Changes
9 files changed (+460 additions, -54 deletions)
View changed files
📝
.github/cursor-approve/README.md(+32 -4)📝
.github/cursor-approve/aggregate.py(+48 -12)📝
.github/cursor-approve/card.py(+79 -8)📝
.github/cursor-approve/prompt-common.md(+42 -11)📝
.github/cursor-approve/tests/test_aggregate.py(+111 -2)📝
.github/cursor-approve/tests/test_card.py(+99 -5)📝
.github/workflows/cursor-approve.yml(+4 -1)📝
.github/workflows/cursor-axis-base.yml(+5 -2)📝
docs/callers/cursor-approve.md(+40 -9)📄 Description
The problem, from the card itself
This is what a reader got on cloud#12712:
Neither cell says anything. The yellow is the worse half: the PR is blocked and
the card gives no reason for it.
Two separate causes.
1. The column was fed the wrong field. It rendered the first sentence of
summary, andsummaryis where a model writes its process log. The prompteven asked for that ("Say what you checked and what decided the verdict" — the
models answer the first half). So the card reported what the axis did.
2.
yellowmeant three different things.prompt-common.mddefined it as"you are uncertain, or you found a material concern", and added "When the
evidence is thin, answer
yellowwith low confidence". So "I found a problem","I couldn't tell", and "nothing on my axis applies to this change" all came out
yellow and all blocked identically. The screenshot's conformance yellow is the
third kind — that is why no concern is named: there isn't one.
What this changes
n/abecomes its own verdict. For an axis with no purchase on the change.It counts as REPORTING (so it is not a missing axis, which withholds) but not
as a yellow (so it does not block), and the prompt requires it to name what the
axis looked for and where — an
n/athat doesn't is untrusted.It is deliberately not a
green.greenmeans "I checked and it's clean";letting "no applicable standard" claim that would quietly approve a conformance
gap the day guidance does appear, and nobody would learn the axis was never
exercised. And a round where every axis reports
n/ais still withheld —nothing was judged, so there is nothing to approve on. That is the one way this
could have become a path to a free approval, and it is closed.
A required
headline. One line, ≤100 chars, stating what decided theverdict. The prompt gives per-verdict examples and bans the openers models
reach for:
A missing or over-long headline makes that axis untrusted, not truncated —
truncating would reproduce the reason-free row one step later.
The card becomes three columns, and the detail moves behind the link:
.github/.Confidence goes with it.
0.60on its own does not help anyone understand averdict, and it was taking a column from the one thing that does.
The run link now leads somewhere. No axis wrote
GITHUB_STEP_SUMMARYbefore, so "workflow run" led to a job list. The decide step now writes the
full summaries and confidences there. Card = the glance; job summary = the
record.
Scope
No input changes, no caller changes, no permission changes.
aggregate.py extractalready passed the whole object through, soheadlineflows end toend without touching
cursor-axis-base.ymlbeyond its header comment.The one behavioural tightening: an axis that returns no
headlineis untrusted,which withholds the approval. That is the intended failure mode (it is how
every other malformed field already behaves) and it only fires for an axis
running a prompt older than its
aggregate.py— impossible here, since bothload from the same pinned ref.
Tests
196 passedin.github/cursor-approve/tests(+22), cursor-review's1280unaffected,
check_workflow_pins.pyandcheck_agents_md.pyclean.New: the headline contract (required / blank / non-string / the cap / the
whitespace fold / the folded length being what's measured) and the n/a rules
(not counted as yellow, named in the reason, all-n/a withholds, does not rescue
a red, does not excuse a missing axis, exact spelling) in
test_aggregate.py;the three-column card, the ⚪ icon, the rule line, the summary fallback, and the
job summary — including that
card.py decideactually writes it toGITHUB_STEP_SUMMARY— intest_card.py.Card sanitization moved to the headline, since that is now the only model text
the card renders; the job summary's own sanitization is covered too (a
#heading, a mention and a forged card marker in a
summary).Not in this PR
The axes receive no prior-round context at all —
build-ledger.pyfeedsthe review panel, and nothing feeds the axes — so a yellow the author has
already addressed comes back every round, and the card is a plain issue comment
that the ledger's
reviews+reviewThreadsquery never sees either. Worthfixing, separately.
🤖 Generated with Claude Code
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.