Repository navigation
Stop no-op auto-fire reviews from cancelling an in-flight review - #22182
Conversation
Triage runs on every push, so every push chains a workflow_run into claude-review. On an already-reviewed PR that run skips, but it claimed the per-PR concurrency group first and cancel-in-progress killed the review in flight -- e.g. a #new-review dispatch posted right after the push. The cancel landed in a pre-step, so the outcome read "skipped", the supersession guard missed it, the error trap set review:error, and the no-op run then skipped on that label (#21172, #21210). - autofire-gate: a cheap job that reads draft + review-state labels and, when the triage-chained run is certain to skip, moves claude-review into a per-run concurrency group so it can't cancel anything. Fails open. - Classify review outcome: treat a cancelled job whose Opus step never ran as superseded (via job.status), so the error trap leaves labels to the newer run. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_015EbMbem5iFw1cErRVNJXzH
Sentinel — merge gate status (preview)Warning
|
| Gate | What it needs | |
|---|---|---|
| ✅ | G1 review-ran | Nothing to do: review current at 1df0012c1. |
| ✅ | G2 findings-answered | Nothing to do: every finding answered. |
| 🔴 | G3 right-approver | Needs an approval from anyone with write access to this repo — no qualifying human approval at this head (bot approvals count only on the automated lanes bot_approvers lists). |
| ➖ | G4 infra-evidence | Doesn't apply to this PR: no changed path affects the deploy. |
| ➖ | G5 oversized-ack | Doesn't apply to this PR: not oversized. |
Break glass: a member of a routing team (.github/review-routing.yml teams:) can apply review:waived, which is logged.
Evaluated at head 1df0012c1.
|
Your site preview for commit 1df0012 is ready! 🎉 http://www-testing-pulumi-docs-origin-pr-22182-1df0012c.s3-website.us-west-2.amazonaws.com |
Reviewer's guide v1 — not for the authorTip Check the PR author: nothing here is yours. Your to-do list is the "Author action guide" comment. Review requested from: @pulumi/docs-tools — an approval from anyone with write access satisfies the merge gate. Note What this PR changes:
The changes would be wrong if the gate drifted from pr-context's skip guard, or if the Review confidence:
|
Author action guide v1 — nothing blocks mergeNote Nothing here needs an answer from you. A human reviewer still approves the merge. This PR adds an Full evidence: verification trail, investigation log, review history. Review v1 · updated 2026-10-08T14:59:23Z · head commit 1df0012 Please don't edit or delete this comment; it's the review's record. |
#22182 put an autofire-gate job in front of claude-review. That job is skipped on workflow_dispatch, and a skipped ancestor fails the implicit success() check on every job below it, so publish (and redispatch) were skipped on every dispatched run: #new-review, the CLI dispatcher, and the freshness redispatch all reviewed the PR and published nothing, leaving review:in-progress on the PR. claude-review already used !cancelled() for this; publish and redispatch now do too, with an explicit result check so they still only run after a successful upstream job. A test now asserts every job downstream of autofire-gate carries a status function. Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
Proposed changes
Fixes a race in
claude-code-review.ymlwhere a push plus a@claude #new-reviewlands a PR onreview:errorwith no review.How it happened (#21172 / #21210, 2026-10-08):
claude-triage.yml, which runs onsynchronize, and it chains aworkflow_runintoclaude-review.#new-reviewdispatch starts first and claims theclaude-review-<PR>concurrency group (Add blog post: AI Agent Guardrails for Infrastructure #21172: 01:08:11).cancel-in-progress(01:09:37). That chained run was always going to skip: it's theworkflow_runpath on a PR that already has a review-state label.skippedrather thancancelled. The classify step only treatscancelledas superseded, sosuperseded=false. The error trap then setsreview:error.review:errorand skips with "already-reviewed" (01:10:27). There's no review, and the label says error.The other five PRs in that batch got lucky on ordering: their triage-chained run queued first and the dispatch cancelled it.
Fix (two layers):
autofire-gatejob. A cheap job that only runs on theworkflow_runpath. It reads draft status and the review-state labels, which are the same signals pr-context'sworkflow_runskip uses. When the run is certain to skip,claude-reviewmoves into a per-run concurrency group (claude-review-<PR>-noop-<run_id>), so it can't cancel anything.claude-reviewstill runs and publishes its skipped check-run as before. The gate fails open: a lookup error puts the run in the shared group, same as today.claude-reviewgetsneeds: autofire-gatewith a!cancelled()wrapper on itsif, so the gate being skipped onworkflow_dispatchdoesn't skip the review.skippedbutjob.statusiscancelled, the run counts as superseded (or as timed out if past the job budget). The error trap then leaves the labels to the newer run. On its own this would just leavereview:in-progressbehind instead ofreview:error, which is why the first layer is the real fix.Validation:
make test-review-pipeline: passes.test_workflow_sanity.py: 137 passed.Two things to watch after merge:
job.statusreadingcancelledinside analways()step after a concurrency cancel is documented GitHub behavior, but I couldn't exercise it here.needsin a job-level concurrency expression is an allowed context, but this is its first use in the repo.A cheap live check is to push and immediately comment
#new-reviewon a reviewed PR, then confirm the triage-chained run logsautofire-gate: … noop=trueand the dispatch survives.Related issues (optional)
Seen on #21172 and #21210 after the v3-scripts merge batch. Same family as the guard comment in the error trap (a superseded run's
review:errorblocking its replacement).🤖 Generated with Claude Code
https://claude.ai/code/session_015EbMbem5iFw1cErRVNJXzH
Generated by Claude Code