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-3904

Planning bug: a story was authored with three children whose acceptance criteria can only be met after the story's own merge and deploy — the container had no exit, and every gating signal read green

To Do
Description

Found by motir run MOTIR-3876 on 2026-08-29, refused at step 0 before any worktree existed. The correction is already submitted as plan cmtecgvbo0017hvn8wt0e2ldk; this card is the telemetry, not the fix.

The defect

MOTIR-3876 — a story with eleven childless children, a legal parent-run target on shape alone — carried three children that can only be satisfied after the story's own pull request has merged and deployed:

  • MOTIR-3887, the apex cutover (manual / human): its acceptance criteria are dig, fly certs show -a motir-core, fly secrets list -a motir-core, curl -sI https://motir.co/ and fly apps list — every one a read of a deployed motir-core.
  • MOTIR-3888, emptying motir-marketing: blocked_by 3887.
  • MOTIR-3889, archiving the repository: blocked_by 3888, and its own first step is "Confirm the predecessor merged."

There is no ordering of the children that finishes the story. run.md step 6 does not open the parent→main pull request while a child is un-landed; applyStatusTransition refuses the container's flip with CONTAINER_HAS_OPEN_CHILDREN; and those three cannot be done until that pull request merges.

Why nothing caught it

plan-rules/kind-container.md already carries the rule"COUNT THE MERGES A CONTAINER'S OWN CRITERIA IMPLY — two, separated by a DEPLOY, is TWO containers" — and it was not applied when the story was authored (2026-08-29 11:15, planningSource: mcp, Claude Code / claude-opus-5[1m]). So this is a rule that exists and was skipped, not a rule that is missing.

Every automated signal agreed the story was fine. validate_work_item(MOTIR-3876) returned valid: true, blockers: [], and the same call returned valid: true after the correction — the tier is structurally unable to see this shape, because each child's edges are individually legal and the contradiction is between the container's completion and its children's preconditions. readiness.ready was true on the story. Only the by-hand step-0 shape check found it.

The cards said it themselves. 3887's opening paragraph: "It runs LAST, after every code card and both test gates are merged and deployed." 3889's: "It is also structurally impossible to fold in: an archived repository is read-only and accepts no branch and no pull request." Both diagnose the ordering precisely and are then placed inside the container whose merge they wait on — the tenant lesson "Recording a hazard in a card's body is not removing it" (reinforced against this occurrence, recurrenceCount: 2).

What the correction did (plan cmtecgvbo0017hvn8wt0e2ldk, planned)

Applied kind-container.md's two named remedies, one at each boundary: SPLIT at the deploy boundary (a new sibling story for the cutover + the emptying, blocked_by MOTIR-3876) and HANG the remaining post-merge card OUTSIDE (the archive becomes a task beside that story, which blocks it). Two motir-core cards were amended so MOTIR-3876's deploy is behaviourally inert until the cutover — the window the single container was hiding.

The still-open question this bug does NOT settle

Can this shape be MECHANISED? The by-hand check is does any child's acceptance read a deployed environment, or is it blocked_by one that does? validate_work_item already runs a shape family with a likely-ordering-violation member that matches post-merge phrasing on a card's OWN criteria — the missing half is asking the same question of a CONTAINER about its CHILDREN, where the phrase-matching evidence (dig, fly , curl -sI https://, "merged and deployed", "Confirm the predecessor merged") is at least as strong. That is a candidate advisory, not a decided one; sizing and design belong to whoever picks this up.

Acceptance criteria

  • A decision is recorded, either way, on whether the container-level post-deploy check becomes a validate_work_item advisory or stays a runbook step. Both outcomes close this card; silence does not.
  • If it becomes an advisory, it fires on the fixture this card records (a container with a child whose criteria read a deployed environment) and does NOT fire on a container whose manual child is a PREREQUISITE of its code (a secret provisioned before the build), which is the legitimate shape it must not flag.
  • Whatever is decided, the LESSON written for this occurrence is not duplicated by it — a rule and a lesson are different tiers.

Context refs

  • motir-meta/prompts/plan-rules/kind-container.md — the merge-count check that was not applied
  • motir-meta/prompts/run.md — the step-0 refusals of motir run <parent>, the third of which caught this
  • MOTIR-3876 — the card this was found on; its comment carries the full diagnosis and the advisory dispositions