Skip to content

fix(ci): dedupe strix.yml's cancel-superseded-pr-runs cleanup job - #1784

Merged
seonghobae merged 1 commit into
mainfrom
fix/cleanup-job-concurrency-dedup
Sep 3, 2026
Merged

fix(ci): dedupe strix.yml's cancel-superseded-pr-runs cleanup job#1784
seonghobae merged 1 commit into
mainfrom
fix/cleanup-job-concurrency-dedup

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • cancel-superseded-pr-runs (the job that retires superseded/closed-PR Strix scan runs) had no concurrency group of its own, so a push burst spawned N independent instances that each competed 1:1 for the same scarce 60-job Actions-plan admission ceiling this job exists to relieve.
  • Adds a PR-scoped (repo+PR-number), cancel-in-progress: true concurrency group, matching codeql-pr.yml's established group-key style. This is the identical failure class cbd1280 (fix(actions): coalescer needs queue:max, not just cancel-in-progress:false #1775) already fixed for current-head-run-coalescer.yml, just not yet applied here.
  • cancel-in-progress: true (not queue: max, which the coalescer needs because each of its queued instances carries a different specific expected-head only it can act on) is correct here: every sweep re-verifies live PR state before selecting or cancelling anything, so a fresh instance always fully subsumes whatever an older, not-yet-run instance would have done — nothing is lost by cancelling a stale queued/running sweep.

What changed from the original design

The design also proposed the same fix for opencode-review.yml's sibling cancel-superseded-opencode-review-runs job. That half was dropped after discovering 8141b99 (landed on origin/main mid-session, after the design was written) already restructured opencode-review.yml's workflow-level concurrency group to repo+PR-scoped/cancel-in-progress: false — a strictly stronger fix that caps the entire run (bootstrap, poll, and this cleanup job) to at most one active instance per PR, for every event type. A job-level dedup on top would have been redundant on the common path, and its planned comment (asserting the outer group "must stay head-scoped") would no longer have matched the file. strix.yml has no such workflow-level group — changed-scope and cancel-superseded-pr-runs remain fully exposed to push-burst admission waste regardless of the recent #1779/#1781 changes (those only touched the strix: job's own group) — so this half of the fix remains fully necessary.

Test plan

  • coverage run -m pytest tests — 2681 passed, 1 skipped
  • coverage report --show-missing — 100% (this PR touches no scripts/ci files; the one required companion test edit still runs green)
  • interrogate — 100%
  • actionlint .github/workflows/strix.yml — clean except one pre-existing, unrelated shellcheck style note (verified present on unmodified origin/main too, just at a different line offset)
  • python3 -c "import yaml; yaml.safe_load(open('.github/workflows/strix.yml'))" — OK
  • Required companion test edit (test_strix_serializes_provider_evidence_per_repository_and_pr) updated to isolate the strix: job's own text before locating its concurrency: block, since cancel-superseded-pr-runs above it now carries its own block and would otherwise win the naive first-match string split.

🤖 Generated with Claude Code


Devin Review

The cleanup job that retires superseded/closed-PR Strix scan runs had no
concurrency group of its own, so a push burst spawned N independent instances
that each competed 1:1 for the same scarce 60-job Actions-plan admission
ceiling the job exists to relieve -- the identical failure class cbd1280
already fixed for current-head-run-coalescer.yml, just not yet applied here.

Adds a PR-scoped (repo+PR-number), cancel-in-progress:true concurrency group,
matching codeql-pr.yml's established group-key style. cancel-in-progress:true
(not queue:max, which the coalescer needs because each of its queued
instances carries a different specific expected-head only it can act on) is
correct here because every sweep re-verifies live PR state before selecting
or cancelling anything, so a fresh instance always fully subsumes whatever an
older, not-yet-run instance would have done -- nothing is lost by cancelling
a stale queued/running sweep.

Originally designed to apply the same fix to opencode-review.yml's sibling
cancel-superseded-opencode-review-runs job. Dropped that half after
discovering 8141b99 (landed on origin/main mid-session, after the design was
written) already restructured that workflow's WORKFLOW-level concurrency
group to repo+PR-scoped/cancel-in-progress:false -- a strictly stronger fix
that caps the entire run (including this cleanup job) to at most one active
instance per PR, for every event type. A job-level dedup on top would have
been redundant on the common path, and its planned comment (asserting the
outer group "must stay head-scoped") would no longer match the file.

Required companion test edit: test_strix_serializes_provider_evidence_per_repository_and_pr
isolates the strix: job's own text before locating "concurrency:", since
cancel-superseded-pr-runs above it now carries its own block and would
otherwise win the naive first-match split.

Verified: coverage run -m pytest tests (2680 passed, 1 skipped), coverage
report --show-missing (100%), interrogate (100%), actionlint (clean except a
pre-existing unrelated shellcheck style note), yaml.safe_load on the touched
workflow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 19 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 3b03af87-2474-469f-998c-b1d7752ed0df

📥 Commits

Reviewing files that changed from the base of the PR and between 87352d9 and 9bfb6fc.

📒 Files selected for processing (2)
  • .github/workflows/strix.yml
  • tests/test_required_workflow_queue_contract.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@seonghobae
seonghobae merged commit fc6cd63 into main Sep 3, 2026
7 of 20 checks passed
@seonghobae
seonghobae deleted the fix/cleanup-job-concurrency-dedup branch September 3, 2026 06:08

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

Devin Review

cancel-superseded-pr-runs-${{
github.event.pull_request.base.repo.full_name || github.repository }}-${{
github.event.pull_request.number || github.run_id }}
cancel-in-progress: true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔴 Late events cancel current cleanup

When an older webhook arrives late, cancel-in-progress: true cancels newer cleanup before either job verifies live pull-request state. The stale replacement exits, leaving obsolete scans active.

Prompt for agents
Redesign cancel-superseded-pr-runs concurrency so a delayed older pull_request_target event cannot preempt the worker for newer live state and then no-op. The current PR-scoped cancel-in-progress group cancels by admission order, while live_target_matches binds each replacement to its event payload. Consider making every cleanup instance operate idempotently from freshly fetched live PR state, including the live head or closed state, so even a stale event fully subsumes an interrupted worker. Preserve the bounded admission objective and add a regression for an old synchronize event arriving while a current synchronize or close cleanup is running.
Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

seonghobae added a commit that referenced this pull request Sep 3, 2026
No conflicts; picked up main's strix.interface shadow-crash fix
(#1783, peer 1) and strix.yml cleanup-job dedup (#1784). Full suite
(2705 tests) passes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant