Type · code · Repo motir-meta · One PR.
Parent · MOTIR-1465, the planner-bug home. Found in · motir run MOTIR-3557, 2026-08-26, at the point of writing the fixture for that card's AC 3.
MOTIR-3557's third acceptance criterion, as authored, read:
No ghost anchor reachable from either path renders with the
'—'/defaultTitlefallback: a fixture asserts every anchor node the two levels emit carries a resolvedidentifierandtitle.
tests/components/workItemLevel.test.tsx:193 in motir-core is a deliberate, shipped test that guarantees the opposite — "an off-level blocker with NO stub still anchors, named by its bare id" — and states the intent in its own comment: "The stub list is best-effort: a blocker the read could not resolve still gets an anchor, so the edge never dangles — it just has nothing but an id to say."
So the criterion forbade shipped behaviour, and the only way to discharge it literally was to delete a guarantee. It was caught while writing the fixture, amended on MOTIR-3557 with the evidence (rung 2 — shipped code outranks a card's prose), and the card shipped with the invariant it was actually reaching for. Cost: one re-write. It could have cost a deleted guarantee.
Per-card gate 2's ABSENCE limb is exactly this rule: "a card whose own deliverable is an EDIT asserts that its target text is NOT THERE — grep the target before asserting the gap." It fires on a card that says "add X to Y", because Y is a name to grep from.
This criterion had no target to grep from. It asserted a negative about RENDERED OUTPUT — no anchor renders with the fallback — and named no file, no symbol and no test. The thing a grep would have had to find is a test that ASSERTS THE OPPOSITE, which is not a target the criterion mentions and not a shape the limb describes. So the gate read clean on a criterion that a two-minute grep falsifies.
The near-miss shape is worth naming precisely, because it is the general one: a criterion phrased as "the product never does X" is a claim about shipped code wearing the costume of a requirement. It is checkable — but only by grepping for a guarantee of X, i.e. by searching for the contradiction rather than for the target, which is a different move from the one the limb currently prescribes.
Extend gate 2's ABSENCE limb in prompts/plan-rules/core.md with the OUTPUT-NEGATIVE case: a criterion asserting that a surface NEVER renders / NEVER emits / NEVER shows something owes a grep of the guarantees, not of a target it does not name — the suite that covers that surface, read for a test that establishes the behaviour deliberately. A shipped test whose comment says why it wants the behaviour is a rung-2 fact, and it outranks the criterion.
And it has a SECOND home (the two-homes rule): motir-ai SHARED_PLANNING_RULES carries gate 2's mirror for the productized planner. This card ships the motir-meta half only — ONE SUBTASK = ONE REPO = ONE PR. The motir-ai mirror is a sibling this card does not create and does not assume; name it in the PR body so the pair is visible rather than implied.
prompts/plan-rules/core.md gate 2's ABSENCE limb states the OUTPUT-NEGATIVE case: a criterion of the form "nothing renders / emits / shows X" is discharged by grepping the covering suite for a test that GUARANTEES X, and a shipped guarantee outranks the criterion.motir-ai SHARED_PLANNING_RULES mirror as the owed sibling and states that this PR does not carry it.prompts/plan-rules/core.md only, and prettier --check is clean over it.prompts/plan-rules/core.md — gate 2, the ABSENCE limb this card extends.motir-core tests/components/workItemLevel.test.tsx:193 — the shipped guarantee the criterion contradicted.Open.