(motir-core) A QUARTER of the acceptance lane's main baselines never run — the concurrency group evicts the QUEUED push run, destroying the per-merge attribution MOTIR-2760 exists for
Opened by Zhu Yue ·
MOTIR-2760 added the push: main baseline so that a merge which breaks an acceptance spec goes red on that merge, instead of surfacing later on an unrelated PR. Its concurrency block says, in its own comment, that cancelling would destroy exactly that. It cancels anyway.
Measured
Of the last 100 push-triggered runs of Acceptance video on main: 68 success, 5 failure, 26 cancelled — and each cancelled run has zero jobs. It was killed while still pending, at the moment the next merge's run was created:
| run | created | cancelled | next run created |
|---|---|---|---|
| 33341883129 | 23:27:59 | 23:28:28 | 33341900774 @ 23:28:27 |
| 33329943919 | 19:06:34 | 19:08:33 | — same pattern |
| 33271383679 | 19:38:10 | 19:46:47 | — same pattern |
| 33244643123 | 09:05:00 | 09:05:15 | — same pattern |
So roughly one merge in four gets no baseline at all, silently: a green-looking main where the lane simply never ran.
Re-measured 2026-09-01 during this card's own run, on the window
2026-08-28T10:37:09Z → 2026-09-01T20:53:59Z: 70 success / 5 failure / 23cancelled, every cancelled run withtotal_count: 0jobs (spot-checked on33341883129,33164520884,33164487486). The window has moved since filing; the claim — roughly one merge in four — stands. The command, which is the thing to re-run rather than the number:gh api "repos/moooon-B-V/motir-core/actions/workflows/acceptance-video.yml/runs?branch=main&event=push&per_page=100"
The mechanism
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
Every push to main shares one group, because github.ref is refs/heads/main for all of them. cancel-in-progress: false protects the run that is already executing — but GitHub holds only one pending run per group, so when a third merge arrives the queued run is evicted. The header's claim ("back-to-back merges would each cancel the last and leave exactly the ambiguity the baseline exists to remove") describes the behaviour it thought it had prevented.
The fix
Group push per COMMIT, keep pull_request per ref:
concurrency:
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.ref || github.sha }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
Acceptance criteria
- Predicate over the workflow: on a
pushevent the concurrency group resolves to something per-commit, so two pushes at different shas are never in the same group. Assert it in the workflow-shape test rather than by eyeballing the expression. - PR behaviour is unchanged: two pushes to the same PR branch still leave one run, the newer one, with the older
cancelled. Measured after the change on a real merge burst of ≥3 back-to-back merges: every merge's sha has an⚠️ CUT ON THE RECORD, 2026-09-01, by this card's ownAcceptance videopush run, and each has at least theDoes the lane hold a spec?job. Record the run ids and shas in anadd_commenton this card — a burst is the only condition that reproduces this, so the evidence has to come from a real one.motir run— see the amendment below. It is now a card of its own,blocks-ed by this one.- The header comment is corrected: it currently asserts the opposite of the measured behaviour, and the next reader would trust it.
⚠️ AMENDED ON THE RECORD, 2026-09-01 — AC 3 IS A POST-MERGE MEASUREMENT AND HAS ITS OWN CARD
A workflow's concurrency.group expression is read from the workflow file at the pushed commit, so no merge burst before this card's own pull request lands can exercise the fix. AC 3 therefore reads on state that exists only after this card has merged — plan-rules/core.md gate 14's ORDERING axis (c), and the shape gate 14(d) calls a precondition the graph cannot hold. Left here it would have been discharged by the status sync flipping this card done on the merge, at the exact moment it was still unmeasured, and nothing walks back from a later burst to a sentence in a closed card's body.
It is now a verification task beside this one under MOTIR-1464, blocked_by this card, with its criteria rewritten to read the GitHub Actions API rather than the tree — proposed on plan cmtj63yxb0125hvphq93tb1la and carrying this card's key once approved. Planning bug filed under MOTIR-1465. Nothing else about this card changed: the diagnosis, the mechanism and the fix were all confirmed against shipped reality during the run.
Context refs
.github/workflows/acceptance-video.yml— theconcurrency:block and its comment.- MOTIR-3106 settled
cancel-in-progressforci.ymland its reasoning stands; this is the pending-run eviction, a different mechanism.- ⚠️ CORRECTED 2026-09-01: "and only in this workflow" was FALSE.
ci.ymlcarries the identical expression and evicts HARDER — 33 of its last 100push: mainruns, allcancelledwith zero jobs, same command. No second bug was filed, because MOTIR-3760 already measured it and ruled it NOT a defect: ci.yml's main run answers "does the trunk build, and does it deploy", and the survivor of a burst carries every commit before it, so its answer survives. THIS lane answers which merge broke a spec, which is exactly what "the survivor carries every commit before it" destroys. Same expression, different product — recorded in the workflow's own header so the next reader does not "finish the job" inci.yml.
- ⚠️ CORRECTED 2026-09-01: "and only in this workflow" was FALSE.
- ⚠️ File overlap: the rename card (MOTIR-4096) moves this whole file. Land this one first.
Discussion
No comments yet.
Adding to this discussion signs you in on app.motir.co and brings you back to this request.