Skip to content

fix(pr-agent): discriminate the concurrency group by event and by pr/issue - #30

Closed
yakimoto wants to merge 1 commit into
mainfrom
fix/420-pr-agent-concurrency-key
Closed

fix(pr-agent): discriminate the concurrency group by event and by pr/issue#30
yakimoto wants to merge 1 commit into
mainfrom
fix/420-pr-agent-concurrency-key

Conversation

@yakimoto

@yakimotoyakimoto commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

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:

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 successwith 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.group asserted to contain both discriminators before anything is written.
  • No other file is touched.

Refs wave-pen#420, wave-pen#386


View with [code]smithAutofix with [code]smith
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 fc31dd1. Bugbot is set up for automated code reviews on this repo. Configure here.

Review in cubic

…issue
Concurrency is evaluated at WORKFLOW level, before any job `if:`, so a run the
reusable lane would skip has already joined the group and evicted whatever was
in it. PRs and Issues share one number sequence, so the old key collapsed every
event on number N onto one group under cancel-in-progress.
Measured across the fleet: 118 of 137 callers carried the undiscriminated key.
On claude-workstation, the worst case, that cost 29 success / 1,625 cancelled /
5,735 skipped across 7,389 all-time runs.
Both discriminators are load-bearing: `event_name` separates a push-triggered
pull_request review from an issue_comment on the same PR, and the pr/issue kind
separates issue_comment on PR #N from issue_comment on Issue #N.
Proven live on claude-workstation#3617 before this fan-out: pr_agent concluded
success with the agent step actually run, not cancelled and not skipped.
Refs wave-pen#420, wave-pen#386
@codeant-ai

codeant-aiBot commented Aug 24, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

StatusCommitStarted (UTC)Finished (UTC)
✅ Reviewed your PRfc31dd1Aug 24, 2026 · 17:1517:15

@sourcery-aisourcery-aiBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We failed to fetch pull request #30.

You can try again by commenting this pull request with @sourcery-ai review, or contact us for help.

@cursor

cursorBot commented Aug 24, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_470fe8dc-d33c-497a-af12-6965612b8bc3)

@coderabbitai

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 2 minutes.

View limit details

Limit details: You’ve used the included review currently available. Your 91 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: da7cf5d8-e6ff-4e3f-a939-dba3c9dfc796

📥 Commits

Reviewing files that changed from the base of the PR and between d90796c and fc31dd1.

📒 Files selected for processing (1)
  • .github/workflows/pr-agent.yml

Comment @coderabbitai help to get the list of available commands.

@codeant-aicodeant-aiBot added the size:S This PR changes 10-29 lines, ignoring generated files label Aug 24, 2026
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix pr-agent concurrency key to separate events and PR vs issue runs

🐞 Bug fix⚙️ Configuration changes🕐 Less than 10 minutes

Grey Divider

AI Description

• Prevent GitHub Actions runs cancelling each other across different trigger events.
• Split concurrency groups by event name and PR-vs-issue kind to avoid ID collisions.
• Document why both discriminators are required and reference fleet-wide impact.
Diagram

graph TD
A{{"GitHub event"}} --> B["pr-agent workflow"] --> C["Concurrency group key"] --> D(["Actions scheduler"]) --> E["Reusable pr-agent lane"]
subgraph Legend
direction LR
_evt{{"Event"}} ~~~ _wf["Workflow/Config"] ~~~ _sys(["Scheduler"])
end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Split into separate workflows per event
  • ➕ Eliminates cross-event cancellations without complex key expressions
  • ➕ Event-specific permissions/logic can be clearer
  • ➖ More workflow files to maintain and keep in sync
  • ➖ Still needs PR-vs-issue separation for issue_comment if both are handled
2. Disable cancel-in-progress for pr-agent runs
  • ➕ Avoids unintended evictions entirely (runs queue instead)
  • ➖ Can create a backlog and waste CI minutes on superseded runs
  • ➖ Slower feedback for active PR iteration
3. Use github.workflow + event/subject in key
  • ➕ More robust uniqueness by including workflow identity explicitly
  • ➕ Easier to reuse the pattern across repos with multiple workflows
  • ➖ Not materially better than the current key for this single-workflow repo
  • ➖ Still requires PR-vs-issue discriminator to avoid number collisions

Recommendation: Keep the PR’s approach: adding github.event_name plus an explicit PR-vs-issue discriminator is the minimal, correct fix for workflow-level concurrency evaluation and shared PR/issue numbering. Alternatives either increase maintenance (split workflows) or reduce CI efficiency (disable cancellation) without addressing the root collision as cleanly.

Files changed (1) +11 / -1

Bug fix (1) +11 / -1
pr-agent.ymlDisambiguate concurrency group key by event and PR vs issue+11/-1

Disambiguate concurrency group key by event and PR vs issue

• Updates the workflow-level 'concurrency.group' key to include 'github.event_name' and a PR/issue-kind discriminator, preventing unrelated runs from cancelling each other. Adds inline documentation explaining why both discriminators are required and referencing measured fleet impact.

.github/workflows/pr-agent.yml

@macroscopeapp

Copy link
Copy Markdown

Approvability

Verdict: Would Approve

Macroscope's review found this PR approvable — This is a one-file GitHub Actions concurrency-key fix that only changes how pr-agent runs are grouped and cancelled. Triggers, permissions, job logic, application code, and production behavior remain unchanged.

Not approved because:

  • Credit balance exhausted. Approvability relies on correctness review in order to determine eligibility

Review your spending limits in Billing settings. You can add or adjust custom eligibility rules. Learn more.

@gitar-bot

gitar-botBot commented Aug 24, 2026

Copy link
Copy Markdown

Note

Automatic reviews are paused because your team has used its included automatic processing for this billing period (headroom scales with your seat count). You can still comment "Gitar review" to run one anytime, and automatic reviews resume on their own by September 1. Add seats for more headroom.
Learn more

Code Review✅ Approved

Updates the pr-agent workflow concurrency key to discriminate by event name and resource type, preventing cross-event cancellation between pull requests and issues. No issues found.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose 

Was this helpful? React with 👍 / 👎 | Gitar

@yakimoto

Copy link
Copy Markdown
ContributorAuthor

Closing as redundant — my error, and worth naming rather than deleting quietly.

This repo already has #29 open from the wave-pen#418 wave, on ci/adopt-inline-pr-agent, and that branch already carries the identical full concurrency key:

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 }}

So this PR was a duplicate that would have conflicted on the same file, and #29 is strictly better besides: it also replaces the stale pinned reusable (@150ffae2) with the current inline template, picking up the fork gate, the per-attempt duration stamps and the CONFIG__AI_TIMEOUT correction. This PR fixed only the key and would have left the stale pin in place.

How it happened: the fan-out script checked idempotence by looking for an existing PR from its own branch name, which is the wrong question. The right one is whether any open PR already modifies the target file. Ten repos in the vulnerable set had exactly that, and all ten got a duplicate before the check caught it.

Merging #29 is the action here. Nothing is lost by closing this.

Refs wave-pen#420, wave-pen#418

@yakimoto
yakimoto deleted the fix/420-pr-agent-concurrency-key branch August 24, 2026 17:16
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0)📘 Rule violations (0)📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Tip of the day
💡 Did you know, you can switch off images and animations for a plain-text comment

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@qodo-code-review

Copy link
Copy Markdown

Qodo Fixer

No findings are available for this PR yet. Findings appear here once Qodo has reviewed the PR.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:SThis PR changes 10-29 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@yakimoto