MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-3897

The selector re-cut — phase → kind at skeleton, kind OR type at deepen, and the cell space becomes a SUM

Implemented
Description

Replaces resolvePlanningRulePacks and legalPlanningRuleCells with the model MOTIR-3891 states. No rule text moves on this card — this is the selector and its enumeration only, so the re-cut lands against a selector that is already correct and already guarded.

The shape

packs(phase, kind, type?) =
    core                       always
  + phase-{skeleton|deepen}    the phase
  + skeleton ⇒ kind packs      by KIND, for every kind
  + deepen, kind ∈ {epic, story, bug}  ⇒ kind packs
  + deepen, kind ∈ {task, subtask}     ⇒ TYPE packs

At deepen a cell is a kind cell or a type cell, never both. That makes the space a SUM: 5 skeleton cells + 3 deepen-kind cells + 14 deepen-type cells = 22, against the 52 the cross-product currently enumerates.

Acceptance criteria

  • PlanningRuleSelector cannot express an illegal cell: supplying a type with epic / story / bug, or omitting it for task / subtask at deepen, is REJECTED with the cell named — not ignored, and not silently defaulted.
  • legalPlanningRuleCells() enumerates the sum, and a guard asserts the count against the arithmetic above rather than against a copied literal, so a new kind or type moves it on purpose.
  • TOTAL RESOLUTION holds: every legal cell resolves to a non-empty duplicate-free pack list, every pack is reachable from some cell, and no pack is declared empty.
  • A deepen task cell and a deepen bug cell share no kind-or-type pack — the sum is real, not a renamed product.
  • The per-cell composed sizes are measured before and after over BOTH cell spaces and stated in the PR; a cell that grows is named with the reason.
  • PACKS_BY_TYPE and any kind map are TOTAL over their enums by TYPE, not by convention — a new member must not compile until it is routed.

Context refs

  • motir-ai src/llm/planningRulePacks.tsresolvePlanningRulePacks, legalPlanningRuleCells, PACKS_BY_TYPE, PLANNING_RULE_PACK_ORDER, and the module header's TOTAL RESOLUTION / DISJOINT COVER invariants.
  • motir-ai tests/planningRulePacks.test.ts — the cell-count assertion and the type-axis suite added by MOTIR-3853.
  • motir-ai tests/plannerPromptAssemblyGate.test.ts — no-orphan and REACHABILITY.
  • MOTIR-3896 — supplies the type at skeleton, without which the deepen-type cells cannot be reached on a fresh plan.