fix(pr-agent): discriminate the concurrency group by event and by pr/issue
One line of YAML. This repo is one of 118 callers of 137 measured carrying the same defect.
The defect
Concurrency is evaluated at workflow level, before any job if:. A run that the pr-agent lane would go on to skip has therefore already joined the group and evicted whatever was in it. PRs and Issues also share one number sequence. So this group —
group: pr-agent-${{ github.event.pull_request.number || github.event.issue.number || github.ref }}
cancel-in-progress: true
— collapses every event touching number N onto a single key, and each new one kills the last. A comment on Issue #30 cancels the in-flight review of PR #30, then skips itself.
The fix
group: pr-agent-${{ github.event_name }}-${{ (github.event.pull_request.number || github.event.issue.pull_request) && 'pr' || 'issue' }}-${{ github.event.pull_request.number || github.event.issue.number || github.ref }}
Both discriminators are load-bearing:
event_namestops anissue_commentcancelling the push-triggeredpull_requestreview of the same PR. This is the common case, since that review runs on everysynchronize.- the
pr/issuekind stopsissue_commenton PR #30 colliding withissue_commenton Issue #30 — same event, same number, whichevent_namealone does not separate. Three repos carry the event-only key from an earlier pass and retain exactly this residual, so it is an observed gap rather than a hypothetical one.
Why this is not speculative
Proven live before this fan-out. claude-workstation#3617 applied this identical change to the fleet's worst case — 29 success / 1,625 cancelled / 5,735 skipped across 7,389 all-time runs — and its own pr_agent then concluded success with the agent step actually run, not cancelled and not skipped. The retry step correctly skipped because attempt 1 succeeded.
It is also the same expression already running in production on 16 repos from the wave-pen#418 wave (api-spec, wave-foundation-public, wave-realtime-edge, wave-modules, and others).
How this repo was selected
Every repo in the org was enumerated and its .github/workflows/pr-agent.yml read off its default branch — not a working tree, not a code-search index, both of which can disagree with what ships. Classification was four-valued so an unreadable repo could never render as a safe one; 0 came back unreadable, so 118 is a count and not a floor.
A repo was marked vulnerable only if it satisfies all three: it triggers on more than one numbered event, its group carries no discriminator, and cancel-in-progress is true. Repos without cancel-in-progress queue rather than evict and were left alone.
What is deliberately not in this PR
- No pin bump. Some callers pin the reusable workflow at a stale SHA and are missing separate body fixes; that is tracked apart from this and depends on
wave-foundation#1258. - No change to triggers, permissions, or the job body. The diff is the concurrency block and the comment above it.
Receipts
- The patch is applied by exact string match on the old group line. Any repo whose line did not match exactly once, directly under
concurrency:was reported and skipped rather than pattern-rewritten — a regex that quietly rewrites a line it did not fully understand is how a one-line fix becomes 118 defects. - The patched file is parsed as YAML and the resulting
concurrency.groupasserted to contain both discriminators before anything is written. - No other file is touched.
Refs wave-pen#420, wave-pen#386
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.
[!NOTE]
Low Risk
CI-only concurrency key change in pr-agent; no application code, secrets, or job triggers modified.
Overview
Fixes pr-agent GitHub Actions runs cancelling each other when unrelated events share the same PR/issue number.
The workflow concurrency.group now keys on github.event_name, a pr vs issue discriminator (so Issue #N and PR #N do not share a group), and the existing number/ref suffix. cancel-in-progress is unchanged.
A block comment documents why both discriminators matter (workflow-level concurrency runs before job if: skips) and notes this matches a fleet-wide fix pattern.
Reviewed by Cursor Bugbot for commit fc31dd153ee3540602491e2bafbab0a9976fc36c. Bugbot is set up for automated code reviews on this repo. Configure here.