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_nodeacceptstype, constrained to the shipped enum, and REQUIRES it fortask/subtask. It stays absent forepic/story/bug, whose deepen packs are selected by kind (MOTIR-3891 point 4).deepen_nodeno 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.bugleavesTYPED_KINDSfor rule-selection purposes. Whether the ENUM changes or only the selector's view of it is settled here and stated in the PR, becauseTYPED_KINDSis read byisTypedKindin more than one place.deepenSelectorForreads the type the skeleton wrote.
Acceptance criteria
propose_node's schema carriestypewith the shipped enum, and the executor REFUSES atask/subtaskproposal that omits it, naming the reason.propose_nodeREFUSES atypeonepic/story/bug, matching the resolver's own rejection rather than ignoring the argument.deepen_nodedoes not write the type; a deepen call whose type differs from the proposal is refused with both values named.- A generation pass over a
taskproposal 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
isTypedKindis enumerated in the PR with a line saying whether it keepsbugor drops it, because the two readings diverge here for the first time. tests/toolSurfaceSinkParity.test.tsstays green — the tool surface and its executors are asserted in lockstep.
Context refs
motir-aisrc/llm/treeGeneration.ts—propose_nodeanddeepen_nodeschemas;deepenSelectorFor; therunDeepenSessioncomposition.motir-aisrc/llm/workItemTypes.ts—TYPED_KINDS = ['task','bug','subtask'],isTypedKind.motir-aisrc/llm/planningRulePacks.ts—resolvePlanningRulePacks's rejection of a type on a container kind.motir-metaprompts/plan-rules/MANIFEST.md— states the current behaviour: "steps 1–3 lay titles and edges, anddeepen_nodeis 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.