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

Planning bug: MOTIR-3721's dependency on a sibling's OPEN pull request was written as prose, not a `blocked_by` — and two cards in the same story shipped with a null `explanationMd`

Done
Description

Found by guard #4 during the parent run of MOTIR-3672 (2026-08-27). Two defects, both in cards authored the same day, both in the same story. Neither is a product defect — the correction is to the plan and to the rule that would have prevented it — so this is the planner-bug home rather than the finding story.

1 — A dependency stated in PROSE that the graph should have carried

MOTIR-3721 sealed ready: true, openBlockers: [], and was the first card the parent run's topological order made claimable. It is not startable.

Its AC 5 reads on four texts that exist only on motir-core#2380MOTIR-3722's branch, open and unmerged. The card's author knew: a comment on it says "AC #5 is already satisfied — do not redo it … that sentence is what goes false here". The knowledge was written as a comment; the graph got nothing. A run reading readiness alone would have branched off origin/main and rebuilt the sibling's half — the two-green-PRs-one-red-main shape.

validate_work_item DID see it, at the tier that does not gate: kind: "subsumption" / likely-in-flight, naming docs/mcp.md on the open pull request. It took a by-hand read of every advisory entry to act on.

The standing rule already covers thisplan-rules/core.md gate 4, an acceptance criterion naming a not-done card is a missing blocked_by until proven otherwise. What is missing is not the rule; it is that the rule fires at AUTHORING time and the author had a comment to write the reasoning into instead. Worth asking whether a card's own comment naming an unmerged sibling should raise the advisory's severity, or whether this is simply gate 4 being skipped.

Corrected in the run: link_work_items blocked_by MOTIR-3722 (a sibling under the same parent, so the edge sits at the right level — gate 7), status → Blocked, and the finding commented on the card.

2 — Two cards with a null explanationMd (gate 16)

  • MOTIR-3721explanationMd: null, and its descriptionMd also ends with a stray <parameter name="plannedWithHarness">Claude Code fragment left by the authoring pass.
  • MOTIR-3678explanationMd: null.

Both were authored on 2026-08-27 alongside siblings that DO carry both axes, so this is a per-card slip rather than a convention that was never adopted. Gate 16's both content axes is the rule; the WHY axis is the one a later reader needs most, and it is the one create_work_item cannot set — it always takes a second update_work_item call, which is exactly where a pass drops it.

What would fix it

Nothing in a code repository. The candidates are all corpus/product changes and this card is where they are decided:

  1. Raise likely-in-flight to a severity a dispatch guard cannot skip, OR
  2. state in plan-rules/core.md gate 4 that a comment naming an unmerged sibling is itself the trigger to wire the edge, and
  3. consider whether add_plan_items / create_work_item should refuse a leaf with no explanationMd, since the two-call shape is what makes the omission easy.

Evidence

  • validate_work_item MOTIR-3672{"kind":"subsumption","item":"MOTIR-3721","path":"docs/mcp.md","pullRequest":"moooon-B-V/motir-core#2380","severity":"likely-in-flight","state":"open"}.
  • get_work_item MOTIR-3721explanationMd: null; description tail carries the stray <parameter …> fragment.
  • get_work_item MOTIR-3678explanationMd: null.
  • Seen on branch parent/MOTIR-3672-explicit-link-only (motir-core), base f4b5793d7.