Skip to content

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

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#83
yakimoto wants to merge 1 commit into
mainfrom
fix/420-pr-agent-concurrency-key

Conversation

@yakimoto

@yakimoto yakimoto commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

User description

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_name stops an issue_comment cancelling the push-triggered pull_request review of the same PR. This is the common case, since that review runs on every synchronize.
  • the pr/issue kind stops issue_comment on PR chore(deps): update dependency python to 3.14 #30 colliding with issue_comment on Issue chore(deps): update dependency python to 3.14 #30 — same event, same number, which event_name alone 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.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]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Note

Low Risk
CI-only concurrency tuning; no application code, secrets handling, or runtime behavior changes.

Overview
Fixes incorrect cancellation of in-flight pr-agent runs by tightening the GitHub Actions concurrency group key in .github/workflows/pr-agent.yml.

The group previously keyed only on PR/issue number (or ref), so cancel-in-progress: true could cancel an active pull_request review when an issue_comment fired on the same number—or when Issue #30 and PR #30 shared a number. The new expression adds github.event_name and a pr / issue kind segment before the number, so push-driven reviews and comment-triggered runs no longer evict each other.

A block comment above concurrency: documents why both discriminators are required and notes fleet-wide scope. Triggers, permissions, and the reusable workflow pin are unchanged.

Reviewed by Cursor Bugbot for commit 9fafeb4. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by Sourcery

Bug Fixes:

  • Prevent pr-agent workflow runs for different event types or PR/issue targets with the same number from cancelling one another.

CodeAnt-AI Description

Prevent unrelated PR and issue reviews from cancelling each other

What Changed

  • Separates workflow runs by event type so issue comments no longer cancel reviews triggered by pull request updates
  • Separates pull requests from issues with the same number so their comment-triggered runs do not conflict
  • Keeps cancellation limited to runs for the same event and target

Impact

✅ Fewer cancelled pull request reviews
✅ Issue comments no longer interrupt PR update reviews
✅ Independent PR and issue processing

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

…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-ai Bot commented Aug 24, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR 9fafeb4 Aug 24, 2026 · 17:15 17:15

@sourcery-ai sourcery-ai Bot 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.

Sorry @yakimoto, you have reached your weekly rate limit of 250000 diff characters.

Please try again later or upgrade to continue using Sourcery

@cursor

cursor Bot 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_bc731de3-6810-4d59-ba4e-02bad21ac861)

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

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: 9502e915-f628-4ecc-9c4e-cbba90951fd9

📥 Commits

Reviewing files that changed from the base of the PR and between bc8c0e4 and 9fafeb4.

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

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

@sourcery-ai

sourcery-ai Bot commented Aug 24, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Updates the pr-agent workflow’s concurrency group to include both the triggering event and whether the numbered target is a PR or issue, preventing unrelated runs from cancelling one another while leaving triggers, permissions, job logic, and cancellation behavior unchanged.

Flow diagram for discriminated pr-agent concurrency groups

flowchart LR
    Trigger[Workflow trigger] --> Key[Build concurrency.group]
    Key --> Event[github.event_name]
    Key --> Kind[pr or issue]
    Key --> Number[PR or issue number]
    Event --> Group[Distinct concurrency group]
    Kind --> Group
    Number --> Group
    Group --> Cancel[cancel-in-progress: true]
Loading

File-Level Changes

Change Details Files
Disambiguate workflow concurrency groups by triggering event and PR-versus-issue identity.
  • Add github.event_name to prevent cross-event cancellation.
  • Add a pr/issue discriminator to prevent same-number PR and issue collisions.
  • Retain the existing numbered-reference or ref fallback and cancellation behavior.
.github/workflows/pr-agent.yml
Document the concurrency defect and rationale for both group-key discriminators.
  • Explain workflow-level concurrency evaluation before job conditions.
  • Document the distinct cancellation scenarios addressed by each discriminator and fleet measurement context.
.github/workflows/pr-agent.yml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codeant-ai codeant-ai Bot 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 event type and PR vs issue

🐞 Bug fix ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

AI Description

• Prevent unrelated issue/PR events from cancelling each other via shared concurrency groups.
• Add event_name and PR/issue-kind discriminators to the pr-agent workflow concurrency key.
• Document why both discriminators are required and reference fleet-wide impact.
Diagram

graph TD
  E{{"GitHub event"}} --> R["pr-agent workflow run"] --> G[("Concurrency group key\n(event + kind + number)")] --> X["Cancel in-progress run"] --> D{"Job runs?"}
  D --> A["Run pr-agent lane"]
  D --> S["Skip lane"]

  subgraph Legend
    direction LR
    _evt{{"Event"}} ~~~ _wf["Workflow/step"] ~~~ _key[("Group key")] ~~~ _dec{"Decision"}
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Split workflows per event type
  • ➕ Hard isolation between pull_request, issue_comment, and other triggers
  • ➕ Simpler concurrency expressions per workflow
  • ➖ More files/duplication and higher maintenance burden
  • ➖ Harder to keep behavior consistent across event-specific workflows
2. Disable cancel-in-progress (queue instead)
  • ➕ Eliminates eviction/cancellation races entirely
  • ➖ Can create backlogs and run many redundant pr-agent executions
  • ➖ Does not address the key-collision root cause; only changes the impact

Recommendation: Keep the current approach: fix the concurrency group key by adding both github.event_name and a PR-vs-issue discriminator. It directly addresses the workflow-level evaluation behavior and prevents known real-world collisions while staying a minimal, low-risk change confined to a single workflow file.

Files changed (1) +11 / -1

Bug fix (1) +11 / -1
pr-agent.ymlHarden pr-agent concurrency key against event and PR/issue collisions +11/-1

Harden pr-agent concurrency key against event and PR/issue collisions

• Adds explanatory comments about workflow-level concurrency evaluation and why collisions occur across events and between PRs and issues. Updates the concurrency.group expression to include github.event_name and a PR/issue-kind discriminator so unrelated runs no longer cancel each other under cancel-in-progress.

.github/workflows/pr-agent.yml

@macroscopeapp

macroscopeapp Bot commented Aug 24, 2026

Copy link
Copy Markdown

Approvability

Verdict: Would Approve

Macroscope's review found this PR approvable — The change narrowly updates the PR-agent workflow’s concurrency key so unrelated event types and PR/issue targets no longer cancel one another. Triggers, permissions, reusable workflow logic, deployment behavior, and application code 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-bot Bot 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 GitHub Actions concurrency group key for the pr-agent workflow to include event name and resource type discriminators, preventing unrelated runs from cancelling each other. 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
Contributor Author

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

This repo already has #82 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 #82 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 #82 is the action here. Nothing is lost by closing this.

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

@yakimoto yakimoto closed this Aug 24, 2026
@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 free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant