From 2d3723691a0abaaf913aca9604355e05fe82a739 Mon Sep 17 00:00:00 2001 From: Tibsfox Date: Mon, 6 Apr 2026 19:51:16 -0700 Subject: [PATCH] fix(gsd): set slice sequence at all three insertion sites All slices got sequence=0 because the three code paths that insert slices never set the sequence column. This made positional ordering degenerate to alphabetical-by-ID, causing deadlocks when dependency- free slices were ordered after blocked ones. Now passes sequence at: - plan-milestone: array index from agent-ordered params.slices - reassess-roadmap: existingCount + index for newly added slices - md-importer: parse order from roadmap content Closes #3356 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/resources/extensions/gsd/md-importer.ts | 4 +++- src/resources/extensions/gsd/tools/plan-milestone.ts | 4 +++- src/resources/extensions/gsd/tools/reassess-roadmap.ts | 7 +++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/resources/extensions/gsd/md-importer.ts b/src/resources/extensions/gsd/md-importer.ts index dfea9ad7c..780bfe178 100644 --- a/src/resources/extensions/gsd/md-importer.ts +++ b/src/resources/extensions/gsd/md-importer.ts @@ -586,7 +586,8 @@ export function migrateHierarchyToDb(basePath: string): { // Parse roadmap for slices if (!roadmap) continue; - for (const sliceEntry of roadmap.slices) { + for (let si = 0; si < roadmap.slices.length; si++) { + const sliceEntry = roadmap.slices[si]!; // Per K002: use 'complete' not 'done' const sliceStatus = sliceEntry.done ? 'complete' : 'pending'; @@ -606,6 +607,7 @@ export function migrateHierarchyToDb(basePath: string): { risk: sliceEntry.risk, depends: sliceEntry.depends, demo: sliceEntry.demo, + sequence: si + 1, // Preserve roadmap parse order (#3356) planning: { goal: plan?.goal ?? '', }, diff --git a/src/resources/extensions/gsd/tools/plan-milestone.ts b/src/resources/extensions/gsd/tools/plan-milestone.ts index 51b3120af..e4f3f72dd 100644 --- a/src/resources/extensions/gsd/tools/plan-milestone.ts +++ b/src/resources/extensions/gsd/tools/plan-milestone.ts @@ -256,7 +256,8 @@ export async function handlePlanMilestone( boundaryMapMarkdown: params.boundaryMapMarkdown, }); - for (const slice of params.slices) { + for (let i = 0; i < params.slices.length; i++) { + const slice = params.slices[i]!; // Preserve completed/done status on re-plan (#2558). // Without this, a re-plan after milestone transition would reset // already-completed slices back to "pending". @@ -272,6 +273,7 @@ export async function handlePlanMilestone( risk: slice.risk, depends: slice.depends, demo: slice.demo, + sequence: i + 1, // Preserve agent-ordered sequence (#3356) }); upsertSlicePlanning(params.milestoneId, slice.sliceId, { goal: slice.goal, diff --git a/src/resources/extensions/gsd/tools/reassess-roadmap.ts b/src/resources/extensions/gsd/tools/reassess-roadmap.ts index 2abba6e55..ab0f492fa 100644 --- a/src/resources/extensions/gsd/tools/reassess-roadmap.ts +++ b/src/resources/extensions/gsd/tools/reassess-roadmap.ts @@ -186,8 +186,10 @@ export async function handleReassessRoadmap( }); } - // Insert new slices - for (const added of params.sliceChanges.added) { + // Insert new slices — assign sequence after existing slices (#3356) + const existingCount = getMilestoneSlices(params.milestoneId).length; + for (let i = 0; i < params.sliceChanges.added.length; i++) { + const added = params.sliceChanges.added[i]!; insertSlice({ id: added.sliceId, milestoneId: params.milestoneId, @@ -196,6 +198,7 @@ export async function handleReassessRoadmap( risk: added.risk, depends: added.depends, demo: added.demo ?? "", + sequence: existingCount + i + 1, }); }