The runbook half of MOTIR-3866 and MOTIR-3869. The shipped planner now has one pack per type, deepen packs for epic / story / bug, and no operation axis; motir-meta still has the old shape.
type-bars.md — type-content, type-copy, type-translate, type-research, type-review, type-verification, type-decision, type-deploy, type-manual, type-legal, type-chore. type-migration.md stays shared (code, chore, deploy).kind-epic-deepen.md, kind-story-deepen.md, kind-bug-deepen.md — the three deepen rule sets authored in motir-ai#329.kind-container.md and kind-story.md load at deepen too. Their current SELECTOR entries in split.py read "and phase = skeleton", which is the same hole motir-ai had: deepening a container is writing its two bodies, and that is exactly the pass the slice and journey rules are about.op-replan.md merges into core.md and the operation axis is retired — replan is plan, and the re-plan REASON is carried by the situation prompt. op-sprint.md STAYS: it is a runbook command with no shipped counterpart, which is a legitimate one-home pack.prompts/plan-rules/MANIFEST.md is generated by split.py, and split.py builds its pending map from the PRE-SPLIT row model in DECISION.numbers.py:
for pack, body in blocks.items():
assert len(body) == P[pack]
assert sum(n for _, n in pending.values()) == dn.TOTAL
A pack with no rows in that model is not in pending, so:
split.py --headers — the only safe write mode, which re-emits headers with bodies read off disk — will not touch a new pack, and its dn.TOTAL assertion pins the model to the pre-split corpus.--force would revert every compression.So the first deliverable is a split.py change, not a markdown one: let a pack exist without pre-split rows — --headers and the MANIFEST tables iterate the packs that exist on disk plus SELECTOR, rather than only the rows of the f7d5723 model. Keep the compression guard and the byte-identical body assertion exactly as they are; they are what make the mode safe.
split.py supports a pack with no pre-split rows: --headers emits its header, and both MANIFEST tables list it. The existing dn.TOTAL assertion still holds over the packs that DO come from the model, and the compression guard is unchanged.kind-container.md and kind-story.md's SELECTOR entries drop the phase = skeleton restriction; type-bars.md and op-replan.md are retired, op-sprint.md is not.COMPRESSION.conserve.py is green, or the PR states which pack diverged and why — a MOVE between packs is a delete plus an insert and must be reviewed, not waved through.REGISTER.count.py is re-run and its per-pack table is in the PR; the corpus-wide cautionary count does not rise.motir-meta prompts/plan-rules/split.py — SELECTOR (~line 47), the pending build (~line 110), --headers (~line 125), the compression guard (~line 155), MANIFEST generation (~line 190).motir-meta prompts/plan-rules/DECISION.numbers.py — the row model split.py reads.motir-meta prompts/plan-rules/type-bars.md, op-replan.md, kind-story.md — the packs that change.⚠️ The MANIFEST already documents the hole this fixes. It states: "Step 4 is the only step that loads a
type-*pack, because it is the only step at which a card has a type: steps 1–3 lay titles and edges, anddeepen_nodeis where the final type is set." That is the same constraint recorded in motir-ai#329 — the type is an OUTPUT of the deepen pass, so a prompt composed once cannot carry the chosen type's rules. Mirroring the packs does not fix that; it is tracked separately.