MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-3270

Planning bug: MOTIR-3249 gates four children behind a POST-DEPLOY measurement, so the story cannot be run as a parent

Done
Description

Found while running motir run MOTIR-3249 (2026-08-20). The story is a legal parent-run shape — seven leaf children, no grandchildren — but it cannot be executed as one, and the reason is in the plan rather than in the run.

The deadlock

MOTIR-3250's deliverable is a PRODUCTION measurement: "a table of ≥3 production refreshes, by repo and phase, is recorded on this card", and "the card states which of the three cases holds, and therefore which sibling carries the bulk of the win — that sentence is the actual deliverable." Both need the instrumentation merged, deployed, and then pushed to. Neither is dischargeable at merge.

And MOTIR-3250 blocks MOTIR-3254, which blocks MOTIR-3255, which blocks MOTIR-3256 — four of the seven children, including every part of the warm worker. MOTIR-3254 says so in its own words: the idle policy's N "must be derived from the measured fetch cost (the timings sibling), not picked."

So a parent-run reaches MOTIR-3254 with the graph edge satisfied (3250 is committed) and the substance absent (nothing is deployed and nothing is measured). run.md's parent flow defines readiness as "every depends_on is already committed", which is exactly the wrong test for a dependency whose content only exists after a deploy. This run stopped at the boundary and reported it rather than building MOTIR-3254 on an assumption — the same assumption the story's own explanation warns against: "building the warm worker before knowing that would commit the largest piece of work in the story to an assumption about where the time goes."

The second defect, which is the dangerous one

Had this run followed the parent-run procedure to the letter, it would have opened parent/MOTIR-3249-* pull requests carrying the parent's key. The last of those merging closes MOTIR-3249, and completing a container CASCADES done onto every child, from any status — so MOTIR-3254, MOTIR-3255 and MOTIR-3256 would have gone green with nothing built, and MOTIR-3250/3253's post-deploy criteria would have gone green with nothing measured. That is the MOTIR-3010 shape (run.md step 6's warning, and planning bug MOTIR-3153) reached from a different direction: not one post-deploy child inside a finished parent, but a parent that CANNOT finish while four of its children wait on a deploy.

The run therefore landed the four merge-dischargeable children as per-card pull requests (motir-ai#257, motir-core#2223), deliberately NOT parent-keyed, and stopped.

What the fix probably is

  1. Split the story at the deploy boundary. The indexing half (3250 · 3251 · 3252 · 3253) is one merge-dischargeable story. The warm worker (3254 · 3255 · 3256) is a second story, blocked_by a verification card that owns the production measurement — the shape run.md gate 14(c) already prescribes for a criterion that reads the deployment.
  2. Cut the post-deploy criteria out of MOTIR-3250 and MOTIR-3253 onto that verification card. As written, both cards are unfinishable at merge and will sit at In Review indefinitely, or — worse — be closed by a parent merge that proves nothing.
  3. The general rule this asks for: a card whose acceptance criteria read the DEPLOYMENT may not be an in-parent blocker of a card that ships at merge. The graph cannot express the difference between "committed" and "deployed and measured", so the plan must not lean on it. plan-rules/core.md gate 14's ORDERING axis is the nearest existing rule; this is the case it does not currently name.

Acceptance criteria

  • MOTIR-3249's post-deploy criteria live on a card that is not inside a container whose merge would close it.
  • The worker chain's dependency on the measurement is expressed as a blocker on that card, not on the instrumentation card.
  • The rule above is written where a planning pass reads it (plan-rules/core.md gate 14, or phase-skeleton.md's dependency-arrow audit), with MOTIR-3249 as its fixture.