Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-4095Done

(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

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:

runcreatedcancellednext run created
3334188312923:27:5923:28:2833341900774 @ 23:28:27
3332994391919:06:3419:08:33— same pattern
3327138367919:38:1019:46:47— same pattern
3324464312309:05:0009: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 / 23 cancelled, every cancelled run with total_count: 0 jobs (spot-checked on 33341883129, 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

  1. Predicate over the workflow: on a push event 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.
  2. PR behaviour is unchanged: two pushes to the same PR branch still leave one run, the newer one, with the older cancelled.
  3. Measured after the change on a real merge burst of ≥3 back-to-back merges: every merge's sha has an Acceptance video push run, and each has at least the Does the lane hold a spec? job. Record the run ids and shas in an add_comment on this card — a burst is the only condition that reproduces this, so the evidence has to come from a real one. ⚠️ CUT ON THE RECORD, 2026-09-01, by this card's own motir run — see the amendment below. It is now a card of its own, blocks-ed by this one.
  4. 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 — the concurrency: block and its comment.
  • MOTIR-3106 settled cancel-in-progress for ci.yml and its reasoning stands; this is the pending-run eviction, a different mechanism.
    • ⚠️ CORRECTED 2026-09-01: "and only in this workflow" was FALSE. ci.yml carries the identical expression and evicts HARDER — 33 of its last 100 push: main runs, all cancelled with 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" in ci.yml.
  • ⚠️ File overlap: the rename card (MOTIR-4096) moves this whole file. Land this one first.