Repository navigation
Description
🤖 Generated by the Agentic Engineer
Why
GitHub Actions shipped a queue key for concurrency, and it closes a gap this repo is currently exposed to.
cancel-in-progress: false does not mean "every run eventually executes." It protects the run that is already executing; the run waiting behind it is still discarded when a newer one arrives:
By default, any existing
pendingjob or workflow in the same concurrency group will be canceled and the new queued job or workflow will take its place.
So on a burst of three events in one group, run 1 executes, run 2 is silently cancelled, run 3 executes. There is no failure, no annotation, and nothing in the run list to say a run was dropped.
queue |
Meaning |
|---|---|
single (default) |
"At most one job or workflow run can be pending in the concurrency group." |
max |
"Up to 100 jobs or workflow runs can be pending in the concurrency group." — FIFO |
queue: max with cancel-in-progress: true is a validation error, so it only ever applies where cancelling is already switched off.
Announcement: https://github.com/orgs/community/discussions/12835#discussioncomment-16602100
Reference: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#concurrency
Proven in this org already: devantler-tech/agent-skills has run queue: max in its release.yaml since 2026-07-11, with every Release run green since. This is propagating a fix we have already validated, not a trial.
Why it matters here specifically
.github/workflows/enable-auto-merge.yaml sets a job-level group:
concurrency:
group: enable-auto-merge-${{ github.event.pull_request.number || github.event.issue.number || github.run_id }}
cancel-in-progress: falseThe group is per-PR, and this workflow is deliberately triggered by a wide event set — pull_request, pull_request_review, issue_comment, merge_group — precisely so the gate re-evaluates when reviewer results land after the original push. Those events routinely arrive in quick succession on one PR: a synchronize, then a CodeRabbit review, then a Codex result comment.
Under the default queue: single the middle evaluation is cancelled. The file's own comments state the requirement that makes this serious:
any supported reviewer-bot review … every red result must be able to DISARM
A dropped evaluation is therefore not just a missed arming — it can be a missed disarm, leaving a PR armed on evidence that has since been withdrawn. That is a correctness defect in a fail-closed gate.
This is also the highest-leverage instance in the portfolio: this is a reusable workflow consumed across repos, so one fix propagates to every consumer.
What
Add queue: max to the enable-auto-merge job's concurrency block so every triggering event gets its own evaluation, FIFO.
Audit the other workflows in this repo while here — lint.yaml and validate-go-project.yaml use cancel-in-progress: true, which is correct for superseded CI and must stay as-is.
Acceptance criteria
- The
enable-auto-mergejob carriesqueue: max;cancel-in-progress: falseis retained. - A burst of PR events on one PR produces one evaluation run per event, none cancelled.
-
cancel-in-progress: trueworkflows are left unchanged.
Part of devantler-tech/monorepo#2453 · Rough size: XS
Blocker: #277 | upstream | last-verified 2026-10-18: #277 is still open (rollout not complete); as of 2026-10-10 the three repository opt-ins still read true; this repository has now run two eligible evaluations under its opt-in (two Dependabot pull requests on 2026-10-09, both auto-merge jobs succeeded, nothing cancelled in 127 complete runs), but each pull request had exactly one, so no burst of real evaluations has been observed; the blocker issue records the decision to rely on the native three-job queue check plus this steady state, and this issue closes when every repository under the gate has the opt-in
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Effort
Projects
- StatusShow more project fields✅ Done
Activity
coderabbitai commentedon Jul 25, 2026
🔗 Related PRs
devantler-tech/actions#412 - ci: skip the suite on the release-commit push to dodge the self-pin tag race [merged]
devantler-tech/actions#427 - fix: resolve first-party self-references at the same commit [merged]
devantler-tech/actions#575 - fix(auto-merge): harden mutable review evidence [merged]
devantler-tech/actions#594 - fix(validate-go-project): raise govulncheck timeout to survive cold-cache scans [merged]
devantler-tech/actions#599 - fix(auto-merge): complete ineligible required runs [merged]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
You can configure auto-planning by selecting labels in the issue_enrichment configuration.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
concurrency.queue: maxwhere runs must not be dropped monorepo#2453devantler commentedon Sep 20, 2026
This is already implemented — do not build it again
I picked this up as the oldest unblocked bug and found the code already in place. Recording that here so the next run does not re-derive it, which is the waste pattern this portfolio keeps paying for.
It shipped in
81ada4a, "add opt-in retention of queued evaluations" (#1151). Verified at the current tip of the default branch: all three concurrency blocks in the auto-merge workflow carry the key — the workflow-level one and both job-level ones — andcancel-in-progress: falseis retained on the job-level pair.Against the acceptance criteria
What actually remains
Activation, then the behavioural proof. There are two ways in, and they differ in who can do them:
The second is the interesting one, because it means this does not have to wait on a settings toggle. A single caller could opt in, the burst behaviour could be observed there, and the rollout could widen from that evidence.
Suggestion
Re-scope this issue to activation and verification rather than implementation, or close it and open a small successor for the rollout. I have not changed either, since which caller goes first is a judgement about blast radius that belongs with whoever picks the rollout up.
Unassigning myself and releasing the claim — there is no code to write here.
devantler commentedon Sep 21, 2026
Decision: activate with a canary on
devantler-tech/actions, then roll out org-wideI checked the one route I could have taken myself, and it is not available.
enable-auto-merge.yamlthroughworkflow_call. It runs inksail,platform,monorepoand elsewhere as a required workflow, and that ruleset is managed in the UI rather than declaratively in.github/deploy/. A direct required-workflow run has an emptyinputscontext, so the only switch it reads is theQUEUE_PENDING_EVALUATIONSvariable. Adding aworkflow_callcaller just to set the input would run the gate twice on every event, which is worse than leaving it off..github/deploy/manages rulesets, repositories, teams and labels, but not variables. So setting the variable is a settings change, and settings changes belong to the maintainer.Recommended order, smallest blast radius first:
QUEUE_PENDING_EVALUATIONS=trueondevantler-tech/actionsonly. This is the canary: the workflow's own PRs see the most review churn.Rollback at any point is deleting the variable. It changes only how many pending evaluations are kept (up to 100 instead of 1). Cancellation behaviour is unchanged, and GitHub rejects
queue: maxtogether withcancel-in-progress: true, so the two cannot combine.devantler commentedon Sep 21, 2026
I answered you in: https://devantlertech.slack.com/archives/D0B1JG2EWLW/p1790013722580349?thread_ts=1789987000.073659&cid=D0B1JG2EWLW
4 remaining items
devantler commentedon Sep 22, 2026
Correction: the recorded burst protocol cannot fail, so it cannot verify anything
Picked this up again and re-checked the premise and the plan against
mainat0e07438before building anything.The key is real. GitHub's workflow-syntax and concurrency docs define
concurrency.queuewithsingle(default, at most one pending run, a newer one replaces it) andmax(up to 100 pending, FIFO), and rejectqueue: maxtogether withcancel-in-progress: true. The implementation is onmain(all three concurrency blocks), so there is still no code to write.The protocol in the previous comment would report a PASS whatever the queue setting is. Three
issue_commentevents fromdevantleron a PR here never share a concurrency group:statelane when it is a deleted review-bot comment on a trusted-bot PR with merge gates enforced. Every other comment run's group ends in its owngithub.run_id, so each run has a private group.eligibilityclassifies the event as eligible. A comment is eligible only when its author is a trusted review bot (CodeRabbit or Codex) and the PR author is a trusted bot. Adevantlercomment is never eligible, so both mutation jobs are skipped and never enter the lane.So "three runs, none cancelled" is guaranteed by construction. The same applies to any
devantler-authored PR, which covers every agent PR in this repository.What a valid burst needs
Two or more eligible evaluations must be pending in the same group at once. In this repository that means one non-draft PR authored by a trusted bot (Dependabot, Renovate, etc.) and either:
pull_requestlifecycle events close together (for example a close and reopen repeated while the first evaluation is still running). This is only meaningful while actor-trust enforcement is off here: with it on, those events are deliberatelycancel-in-progress: truewithqueue: single, so a cancelled middle run would be expected, not a defect; orPASS = every run in that burst has a job that waited on the group (its
started_atis after the previous job'scompleted_at) and none iscancelled. Runs that never overlapped prove nothing, as the 2026-09-22 sample already showed.I have not triggered either burst. Both mean manipulating a live Dependabot PR, and whether actor-trust and merge-gate enforcement are on in this repository has to be read from its settings first, which I cannot see from here. Leaving this open for the canary verification. Claim released.
Generated by Claude Code
devantler commentedon Sep 23, 2026
Canary exposure measured: zero eligible evaluations so far
I read the job list of every
enable-auto-merge.yamlrun on this repository since the variable was set (2026-09-21T18:01:32Z → 2026-09-23T20:50Z): 155 runs, 131issue_commentand 24pull_request_review, and not one of them ran a mutation job. Onlyeligibilityexecuted in each.That is why the earlier "zero cancellations" reading proves nothing: nothing ever entered the queued lane. The reason is who authored the PRs in the window. Every review-bot event landed on a
botantler-1PR, which is not inTRUSTED_BOT_AUTHORS, and the reviews on the two Dependabot PRs came frombotantler-1, which is not inTRUSTED_REVIEW_ACTORS. So the canary has had no exposure, and waiting passively will not change that on its own.Verification plan, recorded so the next run can execute it without re-deriving: the next time a Dependabot PR is open and non-draft here, post a CodeRabbit review request and a Codex review request on it back to back. Both reviewers are trusted review actors and the PR author is a trusted bot, so both result comments are eligible evaluations in the same per-PR mutation group. PASS = every resulting mutation job either ran or waited (its
started_atis after the previous job'scompleted_at), and none iscancelled.No code change is needed; this stays open for that measurement.
devantler commentedon Sep 24, 2026
Current canary readback on 2026-09-24: the repository variable
QUEUE_PENDING_EVALUATIONS=trueremains present.ENFORCE_ACTOR_TRUSTandENFORCE_MERGE_GATEShave no repository entries and do not appear in the complete applicable organization-variable listing. The only open Actions PR is devantler-tech/actions#1335, authored bydevantler, so it is not an eligible trusted-bot canary. No burst or settings mutation was performed, and this remains unverified.One correction to the latest proposed protocol: requesting CodeRabbit and Codex back to back conflicts with the consumer contract's rule that only one review-provider request may be active at a time. Do not manufacture a second review after a successful first review just to produce queue traffic. A future canary should use an eligible, real trusted-bot PR and a permitted event sequence that demonstrably overlaps in the actual mutation concurrency group. Record pending/start/completion timestamps and eligibility for every event; green eligibility-only runs still prove nothing about retention.
concurrency.queue: maxwhere runs must not be dropped monorepo#2453devantler commentedon Oct 1, 2026
Canary re-measured 2026-10-01: the actions-repo canary has retired, and it never got any exposure
devantler-tech/actions: 400enable-auto-merge.yamlruns between 2026-09-23T20:52Z and 2026-09-25T21:12Z (total_count400, so the list is complete). There were 345issue_commentruns and 55pull_request_reviewruns. All 1,200 jobs wereeligibilitysuccesses, plusauto-mergeanddisarm-untrusted-updateskipped. Not one evaluation reached the queued mutation lane. There have been no runs since 2026-09-25T21:12Z, which matches the actions → .github consolidation. TheQUEUE_PENDING_EVALUATIONS=truevariable there now guards nothing.devantler-tech/.github(the workflow's home now):enable-auto-merge.yamlreadsQUEUE_PENDING_EVALUATIONSonly for direct runs whoseworkflow_refis this file, and only from a repository or organization variable. This repository has no repository variables. The organization variable listing needsadmin:org, which this run does not have, so whether the queue is armed here is UNKNOWN, not "no". There have been 883 runs here since 2026-09-25.Next step: set the repository variable
QUEUE_PENDING_EVALUATIONS=trueon.github, or confirm the organization-level one, so the canary runs where the traffic now is. That is a persistent settings change, so it is not taken from an unattended run. Then repeat the job-level measurement above against.github's runs, using organic trusted-bot traffic only (per the 2026-09-24 correction). No code change is needed.devantler commentedon Oct 25, 2026
Verified after protected merge of #741 as signed commit
d3f31a258a5df8c715fb2a6625e41a1d953e8756, published in v13.1.1 and retained in current released main. Its post-merge CI is successful. Direct and required calls now default both mutation paths toqueue: maxwhile retainingcancel-in-progress: false; explicit workflow-call false remains compatible. Cancelling validation workflows were unchanged.A fresh native census covers all 23 active repositories. The active inherited required-workflow rule selects 22 and binds the maintained workflow at main. The actual
QUEUE_PENDING_EVALUATIONSsetting is true in three selected repositories, absent in the other 19 and explicitly false in none. The complete organization-variable UI shows no organization override, with an existing variable as a positive control. The current merged source has no job environment introducing an additional setting scope. A fresh complete workflow census finds no external workflow-call consumers to retain the old caller default.This closes the production exposure using the two-part acceptance decision already recorded on #277: the two real eligible pilot evaluations 37903680988 and 37903955045 are freshly re-read as successful, while native CI 40136759588 retains and completes all three jobs in its real shared queue. No new organic burst is claimed. #277 remains open for the separate temporary input/variable retirement; that planning work no longer leaves any selected repository on a single pending slot.