Planning bug: a card's scope-boundary OUT list named the sibling that BUILDS the surface its criteria assert against — and the `blocked_by` edge pointed the other way
A motir run on MOTIR-4057 halted at guard #4. Two of that card's six acceptance criteria assert against PART 1's surface, and PART 1's surface is MOTIR-4058's deliverable — which was scheduled AFTER it, because the blocked_by edge between the two ran backwards (4058 blocked_by 4057).
The correction is submitted as plan cmtijiwul00a1hvn8dek1ok8w (one edge, inverted). This card is the RECORD, not the fix — the fix is already on the plan.
What made it invisible
Every mechanical signal agreed the card was startable: readiness.ready: true, openBlockers: [], validate_work_item → valid: true, and its advisories array named MOTIR-4056 / 4058 / 4059 only at plain advisory severity, which is correct — the detector reports that a card's description references a not-done item, and says nothing about which way the dependency runs.
The dependency WAS written down, in prose, on the card, in the one section a planner writes when it is being careful. MOTIR-4057's Scope BOUNDARY read:
OUT: PART 1's construction — MOTIR-4058's. This card puts a tool on a surface that card builds.
That sentence is a blocked_by edge. It names the sibling, it names the artifact, and it says which card creates it — and the graph carried the reverse.
Why the existing gates did not fire
core.mdgate 4 (an AC that names a not-donecard is a missingblocked_byuntil proven otherwise) fires on an acceptance criterion. Here the criteria say "PART 1's surface carries it" — they name the SURFACE, not the card. The card naming is in the boundary section, which gate 4 does not read.phase-skeleton.md's arrow audit asks whether each edge is a same-level sibling DAG. It was: same kind, same parent, no cycle. An edge can be perfectly well-formed and point the wrong way, and the audit has no step that reads an edge as a sentence.core.mdgate 8's OUT-of-scope limb (read siblings' out-of-scope / hand-off declarations) reads a SIBLING's OUT list for work handed TO this card — a scope absorption. It does not read this card's own OUT list for a dependency it declares.
So the gap is narrow and nameable: no gate reads a card's own scope-boundary OUT list as a source of edges. The lesson-store rows that cover the general shape — "Audit which way each dependency edge points" (cstr77ecwfcozfr3frq8l7pxl) and "A readiness verdict reports the edges that exist, not the substrate that exists" (c6uj35kr35ez8klh552wlop1f) — have both been reinforced against MOTIR-4057, and a new global row states the OUT-list limb specifically.
Acceptance criteria
plan-rules/core.mdgate 8 gains an OUT-LIST limb, stated at the same altitude as its existing taker's-seat and audience limbs: a card's own scope-boundary / OUT / "not in scope" list is read as a source ofblocked_byedges, and an entry naming the sibling that BUILDS or PRODUCES something the card's criteria act ON is an edge FROM this card TO that sibling — checked against the graph, because the prose is the one that is right. Cites the fixture below.- The same limb reaches
SHARED_PLANNING_RULESinmotir-ai— gate 19's two-homes rule. The trigger is observable by the shipped planner (it writes the boundary section itself), so the clause is mirrored rather than narrowed; if any clause is excluded, the card says so with the grep that excluded it. - The fixture is recorded verbatim: MOTIR-4057's boundary sentence, the inverted edge, and the three green signals (
ready: true,openBlockers: [],valid: true) that stood while it was wrong. - No new advisory family is proposed here. Whether this is mechanisable — an OUT-list section is greppable and a
MOTIR-<n>inside it is a key thereferencefamily already parses, so the missing half is DIRECTION — is a separate question; state it as an open question on this card rather than deciding it, and do not write prose duplicating a check that could exist in code (run.mdguard #4's do NOT write a prose rule for a shipped check).
Context refs
- MOTIR-4057 — the card, its boundary sentence, and the halt comment carrying the full rung-2 evidence.
- MOTIR-4058 — the card that builds PART 1's surface.
- Plan
cmtijiwul00a1hvn8dek1ok8w— the correction (twomodifyproposals, awaiting approval). motir-metaprompts/plan-rules/core.md— gate 8 and its limbs; gate 4's AC limb; gate 19 (the two homes).motir-metaprompts/plan-rules/phase-skeleton.md— the same-level dependency-arrow audit.motir-aisrc/llm/planningRulePacks.ts—SHARED_PLANNING_RULES, the second home. ⚠️ Usegrep -a.