Context
While unblocking PR #15588, the original head 65304b6e1b5f12268edc61ca9f618e8a0bbc12dd failed the full unit job. The author pushed the contract-test repair as current head 54a8ba339e5f9a77a46ffd0c409056d2331102bf, which started Tests run 29703195785. A failed-job rerun of the obsolete run 29702552420 then began at 2026-07-19T20:50:01Z. The newer head's unit and integration jobs were canceled at 20:49:56Z, leaving the current PR head red even though its focused contract suites pass 50/50 locally.
This is not an adapter defect. It is a CI arbitration defect exposed by a normal maintainer action.
Live latest-open sweep: checked the latest 20 open issues at 2026-07-19T20:59Z; no equivalent found. The recent all-state A2A claim sweep found no competing lane. KB ticket search and exact archive/discussion searches found no prior ticket for stale reruns canceling newer-head CI.
The Problem
.github/workflows/test.yml:9-11 groups every attempt for one pull-request ref together and sets cancel-in-progress: true:
concurrency:
group: tests-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: trueThat correctly lets a newly pushed head supersede tests for the previous head. It does not distinguish a new head from a later rerun of an old workflow attempt.
GitHub's documented semantics make the collision deterministic:
Because the group contains only the stable PR ref, dispatch recency wins over commit freshness. An obsolete rerun dispatched later can therefore kill the only run for the current head. Sixteen workflows currently use cancel-in-progress: true; the same ref-only shape is present across the PR CI family.
The Architectural Reality
- Workflow-run arbitration belongs in
.github/workflows/*.yml, not in application code or the GitHub Workflow MCP service.
.github/workflows/test.yml already has a cheap changes classifier before the expensive unit and integration jobs; that is the natural current-head admission seam.
- Normal first-attempt supersession is valuable and must remain: a new commit should cancel expensive work for the previous commit.
- Rerun attempts expose
github.run_attempt and preserve their original github.run_id; those are the available attempt-authority inputs at workflow-concurrency evaluation time.
- The Agent OS structure map does not inventory
.github/workflows; direct inspection found the owner plus fifteen sibling workflows with cancel-in-progress: true. This ticket owns that CI family rather than creating an ai/ service.
- Exact-head review routing depends on current-head CI. A stale run may remain visible historically, but it must never cancel or substitute for the current head's checks.
The Fix
- Define a monotonic concurrency convention for PR workflows:
- initial attempts for the same workflow/ref remain in one “head stream,” preserving new-head cancellation;
- rerun attempts are isolated from that stream using attempt/run identity, so an obsolete rerun cannot cancel a newer initial run;
- repeated attempts of the same original run may still supersede one another.
- Apply the convention to every PR workflow using the vulnerable ref-only +
cancel-in-progress: true shape, or record an explicit, evidence-backed exclusion.
- In the high-cost Tests workflow, extend the cheap classifier/admission job to compare the event payload head SHA with the live PR head before expensive jobs start. A stale rerun exits cheaply with an explicit summary; a current-head rerun remains valid.
- Add mechanical regression coverage for the workflow family so later ref-only cancellation groups cannot silently reintroduce the asymmetry.
- Preserve
push-to-dev behavior and current permissions; the freshness check needs only pull-request read access.
Contract Ledger
| Target surface |
Source of authority |
Proposed behavior |
Fallback |
Docs |
Evidence |
| PR workflow concurrency group |
GitHub concurrency + rerun context semantics |
newest initial head supersedes older initial work; reruns cannot supersede a different head |
non-PR runs retain a unique/safe fallback group |
inline workflow rationale |
static contract test + controlled PR sequence |
| Tests current-head admission |
live PR head.sha via actions/github-script |
expensive jobs run only for the current PR head |
API failure fails closed before expensive work with visible reason |
job summary |
mocked classifier test + live run receipt |
| CI-green reviewer gate |
current-head check suite |
only current-head results decide routing |
stale historical attempts remain non-authoritative |
existing pull-request workflow docs remain authoritative |
gh pr checks on controlled heads |
Decision Record impact
None. This is an operational GitHub Actions correctness rule and does not amend or challenge an accepted ADR.
Acceptance Criteria
Out of Scope
- Removing maintainers' permission to rerun workflows.
- Treating an obsolete run as valid evidence for a newer head.
- Replacing GitHub Actions or changing branch-protection policy.
- Serializing all PR CI with
queue: max; current-head latency must not regress.
- Refactoring unrelated workflow steps while sweeping concurrency keys.
Avoided Traps
- Append only the head SHA to every group: prevents the wrong cancellation but also prevents a new head from canceling expensive old-head work.
- Disable cancellation or use a FIFO queue: preserves evidence but delays the current head behind obsolete work and still spends the compute.
- Rely on maintainer discipline: “rerun only the latest run” is a social workaround, not a correctness boundary.
- Accept local green as replacement: the current GitHub head still needs its own non-canceled required checks.
Related
PR #15588 (live reproducer) · .github/workflows/test.yml · GitHub Actions runs 29702552420 and 29703195785.
Origin Session ID: b4496dab-2fb9-4548-9293-78b4a3d78f60
Retrieval Hint: stale old-head GitHub Actions rerun cancels current PR head cancel-in-progress github.ref run_attempt run_id
Context
While unblocking
PR #15588, the original head65304b6e1b5f12268edc61ca9f618e8a0bbc12ddfailed the full unit job. The author pushed the contract-test repair as current head54a8ba339e5f9a77a46ffd0c409056d2331102bf, which started Tests run29703195785. A failed-job rerun of the obsolete run29702552420then began at 2026-07-19T20:50:01Z. The newer head's unit and integration jobs were canceled at 20:49:56Z, leaving the current PR head red even though its focused contract suites pass 50/50 locally.This is not an adapter defect. It is a CI arbitration defect exposed by a normal maintainer action.
Live latest-open sweep: checked the latest 20 open issues at 2026-07-19T20:59Z; no equivalent found. The recent all-state A2A claim sweep found no competing lane. KB ticket search and exact archive/discussion searches found no prior ticket for stale reruns canceling newer-head CI.
The Problem
.github/workflows/test.yml:9-11groups every attempt for one pull-request ref together and setscancel-in-progress: true:concurrency: group: tests-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: trueThat correctly lets a newly pushed head supersede tests for the previous head. It does not distinguish a new head from a later rerun of an old workflow attempt.
GitHub's documented semantics make the collision deterministic:
GITHUB_SHAandGITHUB_REF: https://docs.github.com/en/actions/how-tos/manage-workflow-runs/re-run-workflows-and-jobscancel-in-progressis true: https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrencyBecause the group contains only the stable PR ref, dispatch recency wins over commit freshness. An obsolete rerun dispatched later can therefore kill the only run for the current head. Sixteen workflows currently use
cancel-in-progress: true; the same ref-only shape is present across the PR CI family.The Architectural Reality
.github/workflows/*.yml, not in application code or the GitHub Workflow MCP service..github/workflows/test.ymlalready has a cheapchangesclassifier before the expensive unit and integration jobs; that is the natural current-head admission seam.github.run_attemptand preserve their originalgithub.run_id; those are the available attempt-authority inputs at workflow-concurrency evaluation time..github/workflows; direct inspection found the owner plus fifteen sibling workflows withcancel-in-progress: true. This ticket owns that CI family rather than creating anai/service.The Fix
cancel-in-progress: trueshape, or record an explicit, evidence-backed exclusion.push-to-devbehavior and current permissions; the freshness check needs only pull-request read access.Contract Ledger
head.shaviaactions/github-scriptgh pr checkson controlled headsDecision Record impact
None. This is an operational GitHub Actions correctness rule and does not amend or challenge an accepted ADR.
Acceptance Criteria
cancel-in-progress: trueare updated or carry an explicit exclusion justified by a falsifier.pushruns ondev, workflow permissions, path classification, and check names remain unchanged.Out of Scope
queue: max; current-head latency must not regress.Avoided Traps
Related
PR #15588(live reproducer) ·.github/workflows/test.yml· GitHub Actions runs29702552420and29703195785.Origin Session ID: b4496dab-2fb9-4548-9293-78b4a3d78f60
Retrieval Hint:
stale old-head GitHub Actions rerun cancels current PR head cancel-in-progress github.ref run_attempt run_id