feat(sf): wire ADR-011 progressive planning dispatch rule
Adds 'planning (sketch + progressive_planning) → refine-slice' rule in auto-dispatch.ts, fired BEFORE the existing 'planning → plan-slice' rule. Activates when: - state.phase === 'planning' - prefs?.phases?.progressive_planning === true - slice has is_sketch=1 in the DB When all three conditions hold, dispatches the refine-slice unit using the existing buildRefineSlicePrompt + prompts/refine-slice.md (both ported in earlier commits). Otherwise falls through to plan-slice (graceful downgrade — current behavior is preserved when the flag is off, which is the default). Why this matters: without progressive planning, the milestone planner has to either fully-plan every slice upfront (rots quickly) or hand- wave each slice (executors overscope). Sketch+refine lets the planner write 2-3 sentences of scope per slice and have refine-slice expand it just-in-time using prior slice summaries as context — keeping each plan sized for the actual current reality. Defensive read of slice.is_sketch with try/catch: pre-migration installs without the column simply fall through to plan-slice, no error. The DB DDL migration will land separately as part of the full progressive- planning rollout. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fef2e4b6f4
commit
0c78b00381
1 changed files with 39 additions and 0 deletions
|
|
@ -22,6 +22,7 @@ import {
|
||||||
buildPlanSlicePrompt,
|
buildPlanSlicePrompt,
|
||||||
buildReactiveExecutePrompt,
|
buildReactiveExecutePrompt,
|
||||||
buildReassessRoadmapPrompt,
|
buildReassessRoadmapPrompt,
|
||||||
|
buildRefineSlicePrompt,
|
||||||
buildReplanSlicePrompt,
|
buildReplanSlicePrompt,
|
||||||
buildResearchMilestonePrompt,
|
buildResearchMilestonePrompt,
|
||||||
buildResearchSlicePrompt,
|
buildResearchSlicePrompt,
|
||||||
|
|
@ -60,6 +61,7 @@ import {
|
||||||
getMilestone,
|
getMilestone,
|
||||||
getMilestoneSlices,
|
getMilestoneSlices,
|
||||||
getPendingGates,
|
getPendingGates,
|
||||||
|
getSlice,
|
||||||
getSliceTasks,
|
getSliceTasks,
|
||||||
isDbAvailable,
|
isDbAvailable,
|
||||||
markAllGatesOmitted,
|
markAllGatesOmitted,
|
||||||
|
|
@ -976,6 +978,43 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// ADR-011 progressive planning: when a slice was created as a sketch
|
||||||
|
// (slices.is_sketch=1) and the phases.progressive_planning preference is
|
||||||
|
// enabled, dispatch refine-slice instead of plan-slice. The refine unit
|
||||||
|
// expands the stored sketch_scope into a full plan using prior slice
|
||||||
|
// summaries as authoritative context. When the preference is off, sketches
|
||||||
|
// fall through to the normal plan-slice rule below — a graceful downgrade.
|
||||||
|
name: "planning (sketch + progressive_planning) → refine-slice",
|
||||||
|
match: async ({ state, mid, midTitle, basePath, prefs }) => {
|
||||||
|
if (state.phase !== "planning") return null;
|
||||||
|
if (!state.activeSlice) return null;
|
||||||
|
if (prefs?.phases?.progressive_planning !== true) return null;
|
||||||
|
const sid = state.activeSlice.id;
|
||||||
|
const sTitle = state.activeSlice.title;
|
||||||
|
let isSketch = false;
|
||||||
|
try {
|
||||||
|
const sliceRow = getSlice(mid, sid);
|
||||||
|
isSketch = sliceRow?.is_sketch === 1;
|
||||||
|
} catch {
|
||||||
|
/* DB unavailable or column missing on pre-migration installs — fall through */
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!isSketch) return null;
|
||||||
|
return {
|
||||||
|
action: "dispatch",
|
||||||
|
unitType: "refine-slice",
|
||||||
|
unitId: `${mid}/${sid}`,
|
||||||
|
prompt: await buildRefineSlicePrompt(
|
||||||
|
mid,
|
||||||
|
midTitle,
|
||||||
|
sid,
|
||||||
|
sTitle,
|
||||||
|
basePath,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "planning → plan-slice",
|
name: "planning → plan-slice",
|
||||||
match: async ({ state, mid, midTitle, basePath }) => {
|
match: async ({ state, mid, midTitle, basePath }) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue