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`
Opened by Zhu Yue ·
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#2380 — MOTIR-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 this — plan-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-3721 —
explanationMd: null, and itsdescriptionMdalso ends with a stray<parameter name="plannedWithHarness">Claude Codefragment left by the authoring pass. - MOTIR-3678 —
explanationMd: 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:
- Raise
likely-in-flightto a severity a dispatch guard cannot skip, OR - state in
plan-rules/core.mdgate 4 that a comment naming an unmerged sibling is itself the trigger to wire the edge, and - consider whether
add_plan_items/create_work_itemshould refuse a leaf with noexplanationMd, 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-3721→explanationMd: null; description tail carries the stray<parameter …>fragment.get_work_item MOTIR-3678→explanationMd: null.- Seen on branch
parent/MOTIR-3672-explicit-link-only(motir-core), basef4b5793d7.
Discussion
No comments yet.
Adding to this discussion signs you in on app.motir.co and brings you back to this request.