Summary
In DB-backed projects, active milestone selection can drift to an older queued placeholder milestone instead of the real current active milestone.
What I observed
A project had:
- one older queued milestone shell with only a skeletal roadmap and no slices
- one current active milestone with real
CONTEXT.md, ROADMAP.md, slices, and pending task work
- later queued milestones after that
Some GSD surfaces selected the older queued shell as active instead of the current real milestone.
The practical symptom was:
- the engine wanted to go back to the old queued shell
- instead of continuing the real current milestone and task
Why this looks wrong
The older queued shell is real and should remain visible as pending work.
But it should not outrank the current milestone when the current milestone is already the active one in project state and has substantive material on disk.
Minimal repro shape
I can reproduce this with a generic milestone sequence like:
M068 = queued shell, roadmap exists, no slices, no context
M070 = current real active milestone, has context, roadmap, slices, pending task
M071/M072/M073 = future queued milestones
Then:
STATE.md indicates the current active milestone is M070
M070 has real milestone files and slice/task state
- DB still contains a queued row for
M068
- some GSD paths still resolve
M068 as the active milestone
Expected
The current real milestone should stay active.
Older queued shells should remain pending in the registry, not become active.
Actual
The older queued shell becomes active in some flows.
Notes that may help debug
The issue seems centered in DB-backed milestone ordering / precedence logic in:
src/resources/extensions/gsd/state.ts
The important distinction is:
- queued milestone shells are legitimate future work and should stay in the registry
- but active milestone selection should prefer the current project sequence / current active milestone when it already has real material
I suspect the right fix is to separate:
- "show this milestone in the registry"
from
- "treat this milestone as the current active milestone"
In other words, placeholder queued rows should not be treated as ghosts, but they also should not eclipse the current active milestone.
Summary
In DB-backed projects, active milestone selection can drift to an older queued placeholder milestone instead of the real current active milestone.
What I observed
A project had:
CONTEXT.md,ROADMAP.md, slices, and pending task workSome GSD surfaces selected the older queued shell as active instead of the current real milestone.
The practical symptom was:
Why this looks wrong
The older queued shell is real and should remain visible as pending work.
But it should not outrank the current milestone when the current milestone is already the active one in project state and has substantive material on disk.
Minimal repro shape
I can reproduce this with a generic milestone sequence like:
M068= queued shell, roadmap exists, no slices, no contextM070= current real active milestone, has context, roadmap, slices, pending taskM071/M072/M073= future queued milestonesThen:
STATE.mdindicates the current active milestone isM070M070has real milestone files and slice/task stateM068M068as the active milestoneExpected
The current real milestone should stay active.
Older queued shells should remain pending in the registry, not become active.
Actual
The older queued shell becomes active in some flows.
Notes that may help debug
The issue seems centered in DB-backed milestone ordering / precedence logic in:
src/resources/extensions/gsd/state.tsThe important distinction is:
I suspect the right fix is to separate:
from
In other words, placeholder queued rows should not be treated as ghosts, but they also should not eclipse the current active milestone.