mirror of
https://github.com/Comfy-Org/github-workflows.git
synced 2026-11-05 00:17:37 +00:00
[PR #357] [MERGED] feat(cursor-review): approve_scope — gate auto-approve rounds 2+ on the delta since the last reviewed commit #357
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#357
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/357
Author: @mattmillerai
Created: 10/7/2026
Status: ✅ Merged
Merged: 10/7/2026
Merged by: @mattmillerai
Base:
main← Head:matt/be-19455-approve-scope-delta📝 Commits (1)
d492b6afeat(cursor-review): approve_scope — gate auto-approve rounds 2+ on the delta since the last reviewed commit📊 Changes
7 files changed (+494 additions, -17 deletions)
View changed files
📝
.github/cursor-review/README.md(+1 -0)📝
.github/cursor-review/auto-approve.py(+223 -13)📝
.github/cursor-review/post-review.py(+57 -3)➕
.github/cursor-review/tests/fixtures/incremental-delta.patch(+12 -0)📝
.github/cursor-review/tests/test_auto_approve.py(+154 -0)📝
.github/workflows/cursor-review.yml(+46 -1)📝
docs/callers/cursor-review.md(+1 -0)📄 Description
ELI-5
Auto-approve used to block a fix round on any Medium the panel found, even in code the author never touched that round, so fix rounds never converged. Now, from round 2 on, only findings in this round's new changes, live re-raises of still-open threads, and High/Critical findings anywhere can block. Everything else is still posted, but labelled as not blocking.
What changed
New input
approve_scope(deltadefault, orfull). It only takes effect whenapprove_max_severityis set. It is passed to bothpost-review.pyandauto-approve.py decide, soapprove_gate(and with itdefer_approval/ cursor-approve) sees the same gate.diff-sizeemitsincremental_state:none/built/unavailable/discarded. "No block because it's round 1" used to be indistinguishable from "no block because the build failed" and from "empty block from a pure rebase".auto-approve.py:resolve_scope()falls back tofullwhen the state is notbuilt, the block can't be read, or the ledger status isn'tok/empty. Round 1 (none) also runs asfull. Underdelta,gating_reason()counts an above-threshold finding only if it is:repeat_ofpointing at an unresolved ledger thread;The decision note (a log line plus a
_Scope:_line in the review body) states the scope, the gating and non-gating counts, and why each finding gated.post-review.pyruns the same classifier and appends_Outside this round's changes: not blocking auto-approve._plus a marker to non-gating threads. The marker is stripped from model text first, so a finding can't exempt itself.Open-thread check / auto-resolve: under
delta, a marked thread doesn't hold back the approval, and it doesn't block the other threads from resolving either. It is never resolved itself, so it stays open for a human. Afullround counts marked threads as before.Judgment calls
delta, an earlier round's thread that was marked non-gating doesn't block a later round's approval, unless it is re-raised. Without this, round 3 would block on round 2's non-blocking Medium and rounds still wouldn't converge. I read the ticket's empty-delta rule ("no earlier unresolved finding above the threshold") as applying to gating threads.LAST_REVIEWED_SHA == HEAD_SHA) reads asnone, so it runs asfull.disabled(the kill switch) also runs asfull, because without the ledger there is no live-repeat data.Residual
blockinggate (gate-unresolved.py) still counts a non-gating Medium thread as unresolved. That is consistent with "left open for a human", but ablocking+approve_max_severitycaller will see an approval and a red blocking check together until a human resolves the thread. Whetherblockingshould also honourapprove_scopeis a separate decision.ok.discussion_urlonly. A re-raise whose ancestor was body-only (unanchored) has no thread, so it isn't a live repeat. Underdeltait gates only if it falls in the delta or is severe.Provenance
ApproveScopeTestcases covering every case the ticket lists, plus the marker-injection and constant-parity checks)check_workflow_pins.py,check_agents_md.py,check-org-repo-literals.sh: passcursor-review.ymlparses as YAML🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.