Planning bug: MOTIR-3965 put a human MERGE between two of its own acceptance criteria — a release authored as one card, sized for the publish alone
Discovered in · the run of MOTIR-3965, 2026-08-30, which halted at run.md guard #5 and submitted plan cmtfw2fp3006khwph9ycw7qtp instead of building · The correction is already applied — this card is telemetry about the planner, not scheduled work holding anything up.
What the card asked for
One bug card, targetRepo: motir-core, 2 points / 40 minutes, five acceptance criteria:
- publish
@motir/design-systemat the next patch version, from a motir-core commit containing MOTIR-3933; - pull it anonymously and quote the shasum;
motir-marketingpins that version, lockfile regenerated, its five checks pass;- the gallery verified on the built site;
/designotherwise unchanged.
The two defects, and they compound
A. An uncrossable ORDERING gate inside one card (per-card gate 14c). .github/workflows/release-design-system.yml fires on a design-system-v<x.y.z> tag and fails fast unless the tag equals packages/design-system/package.json's version. packages/design-system/README.md § Releasing therefore states the procedure as bump → merge → tag. Criterion 1 consequently reads on state that exists only after the card's own pull request has MERGED — and in manual merge mode a run opens pull requests and a person merges them. Criteria 2–5 all read on criterion 1's output, so four of the five criteria were unreachable by any single run, and the card would have sat at implemented on a bump pull request wearing a status that says the work is done.
B. A two-repository criterion column, invisible to the detector (gate 1 / guard #5). Criteria 3–5 are discharged in motir-marketing — package.json, pnpm-lock.yaml, tests/aaMatrix.test.ts, the built /design page. The card pinned motir-core and carried an empty targetRepos.
They compound rather than merely co-occur: the boundary-contract carve-out that permits a two-repository card ("two coordinated pull requests, consumer written defensively so merge order is free") is defeated by A. pnpm install cannot resolve an unpublished version, so the lockfile criterion 3 requires cannot even be GENERATED before the publish. The two pull requests are strictly ordered, which is exactly the case the carve-out excludes.
Why no signal fired
readiness→ready: true,openBlockers: []. Correct: readiness answers has every work item this one waits on reacheddone?, and the card's real precondition was a merge of its own pull request, which is not a work item at all (gate 14d's blind spot).validate_work_item→valid: true, four plainadvisoryentries and nolikely-repo-straddle. Also correct as implemented: that detector reads criteria for a PATH in a repository other than the pin, and this card's criteria namemotir-marketingby bare repository name — "motir-marketing'spackage.jsonpins that exact version" — with no path to match. Thelikely-ordering-violationarm keys on phrases like "merged tomain" / "once this lands"; this card's ordering gate is not in its words at all, it is in the release lane's trigger, so no phrase existed to match either.- The estimation gate is silent at 2 points / 40 minutes — nowhere near the 13-point or 70-minute thresholds. The number was not a bad estimate of the work; it was a correct estimate of ONE of the three things the card was asking for.
Fix direction
The corpus already carries both governing rules — gate 1's criterion→repo column and gate 14c's ordering axis — and the run applied them by hand and stopped correctly, so no new rule is proposed. Two candidate sharpenings, neither of which this card performs:
likely-repo-straddlematches paths, not bare repository names. The workspace's connected repository names are a known, small, literal set, and a criterion naming one that is not the card's pin is the same declaration as a path. That is a change tovalidate_work_item's straddle detector in motir-core, and it is the mechanised half of a check the prose rule already states — worth its own card if this recurs.- The ordering axis has no phrase to match when the gate lives in a release TRIGGER rather than in the card's words. A card whose deliverable is a published artifact is post-merge by construction, whatever it says. Whether that is expressible as a detector (type
deploy+ a criterion naming a registry ⇒ the card cannot also carry the commit that feeds it) is a genuine question, not an obvious yes.
Recorded here rather than filed as work, deliberately — one occurrence, and the standing rules did catch it. A second occurrence of either shape is what should turn one of the two into a card.
Acceptance criteria
- The record above stands on this card, with the two shapes named and the evidence for each (the lane's trigger and guard; the detector's path-vs-bare-name matching).
- The lesson is written GLOBAL — the takeaway is project-agnostic: it names no repository, no key and no path once the identifiers are stripped.
- ORDERING — every criterion reads on this card and on the lesson store. Nothing here reads on the corrected cards' pull requests; whether they ship does not change what this record says.
Context refs
- MOTIR-3965 — the card, its halt comment, and the re-scoped survivor. Plan
cmtfw2fp3006khwph9ycw7qtpis the correction. .github/workflows/release-design-system.yml·packages/design-system/README.md§ Releasing — the trigger and the procedure that make the gate real.- MOTIR-2131 → MOTIR-2132 → MOTIR-2133, and MOTIR-3850 — this repository's own release shape, one card per merge boundary. It existed and was not reached for.
Resolution: recorded; correction applied on the plan.