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
Back to roadmap
Implemented

`type` becomes an output of SKELETON — `propose_node` carries it, and `bug` leaves the typed set

Sub-taskopened by Zhu YueMOTIR-3896

The change that makes the type axis load-bearing. Today propose_node's schema takes kind + title + edges and no type; deepen_node's schema comments that "The FINAL type is set here". So deepenSelectorFor reads record.fields?.type — a field the skeleton never wrote — and on a fresh plan the type axis resolves to nothing.

What changes

  • propose_node accepts type, constrained to the shipped enum, and REQUIRES it for task / subtask. It stays absent for epic / story / bug, whose deepen packs are selected by kind (MOTIR-3891 point 4).
  • deepen_node no longer SETS the type. It may still carry it for validation, and a mismatch against what the skeleton proposed is a refusal rather than a silent overwrite — a card whose type changed between phases was composed against the wrong packs, and that must be visible.
  • bug leaves TYPED_KINDS for rule-selection purposes. Whether the ENUM changes or only the selector's view of it is settled here and stated in the PR, because TYPED_KINDS is read by isTypedKind in more than one place.
  • deepenSelectorFor reads the type the skeleton wrote.

Acceptance criteria

  • propose_node's schema carries type with the shipped enum, and the executor REFUSES a task / subtask proposal that omits it, naming the reason.
  • propose_node REFUSES a type on epic / story / bug, matching the resolver's own rejection rather than ignoring the argument.
  • deepen_node does not write the type; a deepen call whose type differs from the proposal is refused with both values named.
  • A generation pass over a task proposal composes that type's packs — asserted on the composed system prompt of the DEEPEN session, not on the resolver alone. This is the check that would have caught the original defect.
  • Every call site of isTypedKind is enumerated in the PR with a line saying whether it keeps bug or drops it, because the two readings diverge here for the first time.
  • tests/toolSurfaceSinkParity.test.ts stays green — the tool surface and its executors are asserted in lockstep.

Context refs

  • motir-ai src/llm/treeGeneration.tspropose_node and deepen_node schemas; deepenSelectorFor; the runDeepenSession composition.
  • motir-ai src/llm/workItemTypes.tsTYPED_KINDS = ['task','bug','subtask'], isTypedKind.
  • motir-ai src/llm/planningRulePacks.tsresolvePlanningRulePacks's rejection of a type on a container kind.
  • motir-meta prompts/plan-rules/MANIFEST.md — states the current behaviour: "steps 1–3 lay titles and edges, and deepen_node is where the final type is set"; it owes an update in the mirror card.

Comments (0)

No comments yet — be the first to weigh in.

Sign in to comment

Reading is open to everyone; posting needs a Motir account.

Sign in