Planning bug: a card specified ONE rule delivered to two packs with identical text — which `INVARIANT B — disjoint cover` forbids, and the 88-char segment id collides on
Found while running MOTIR-4056 (the MAY-I-START rule). The correction is already applied and shipped in motir-ai#351; this card is the telemetry.
The defect — two acceptance criteria that cannot both hold
MOTIR-4056 specified, in its own body:
NOT A NEW PACK— "The rule joinsphase-authorandphase-lay… One rule in two packs, each phrased for its own completion."
and, as an acceptance criterion:
"The recovery is stated identically in both packs, including that a not-yet-read answer is a PART 1 failure rather than a WHAT gap."
Jointly unsatisfiable. A recovery stated identically in two packs puts the same LINE in two packs, and motir-ai has shipped a guard against precisely that since the pack split:
tests/planningRulePacks.test.ts—INVARIANT B — disjoint cover, "no line appears in two packs", skipping only blank lines and the═══banner.tests/helpers/planningRuleRouting.ts—SEGMENT_ID_WIDTH = 88: a segment's id is the first 88 characters of its opening line, andplanningRuleRouting.test.tsfails on "a segment id names exactly one rule — no two segments collide after truncation".
Both went red on the card's literal shape, on the first run.
Why the card could not see it, and what would have
The card was authored against planningRulePacks.ts — its own context refs name phase-author, phase-lay and DECISION_AUTHORITY_LADDER in that file, and nothing else. The constraint that falsified it lives in the TEST file, not the source, and the corpus's own composition doc (DECISION.rule-phase.md §2) already carries the answer: core is defined as the intersection — what BOTH surfaces can discharge — so text that is identical on both phases has an existing home and does not need to be duplicated into two.
So the card reached for "put it in both" where the corpus's own structure says "put it in the tier that IS both".
The takeaway, stated as the rule it should have been planned by
Text that is IDENTICAL on both planning phases belongs in core, not copied into phase-author and phase-lay. Only what genuinely DIFFERS per phase goes in a phase pack. A card that asks for the same words in two packs is asking for something the disjoint-cover invariant forbids, and the correct shape is one core segment plus the per-phase remainder.
This generalises past this one card: the same trap is available to any future card adding a rule that fires on both phases, and MOTIR-3944 (the motir-meta mirror pass) will meet it across the whole corpus.
Acceptance criteria
motir-meta's rule corpus states the placement rule above where a planner authoring a rule-pack card will read it — the pack-authoring guidance inprompts/plan-rules/that already covers thecore/ phase / kind / type tiers. CiteDECISION.rule-phase.md§2's definition ofcoreas the intersection rather than restating it.- The rule names the two guards that enforce it by file —
planningRulePacks.test.ts'sINVARIANT Band the 88-characterSEGMENT_ID_WIDTH— so a reader can check the constraint rather than take it on trust. REGISTER.count.py's cautionary count does not rise: this is a placement rule, so it is written as "in situation X, put it incore" rather than as an account of this incident.- The conservation baseline is refreshed only if rule text genuinely relocates, with the word-diff in the PR.
Scope BOUNDARY
- OUT: changing
INVARIANT BorSEGMENT_ID_WIDTH. Both guards are correct and behaved correctly; the plan was wrong, not the guard. This isno-special-case-fix-the-general-rulein the direction that does NOT touch the mechanism. - OUT: MOTIR-4056's own delivery — already shipped, with the deviation recorded on that card.
- OUT:
motir-ai's mirror of the rule corpus. MOTIR-3944 runs the mirror pass over the epic and is where anymotir-ai-side wording lands.
Context refs
motir-aitests/planningRulePacks.test.ts—INVARIANT B — disjoint cover, theno line appears in two packsassertion.motir-aitests/helpers/planningRuleRouting.ts—SEGMENT_ID_WIDTH = 88and the id truncation.motir-metaprompts/plan-rules/DECISION.rule-phase.md§2 (coreis the intersection) and §3 (no new packs).motir-aisrc/llm/planningRulePacks.ts—CORPUS_ORDERand the shipped three-segment shape MOTIR-4056 landed.