fix(gsd): default insertMilestone status to queued instead of active

Hallucinated tool calls could auto-create phantom milestones as
"active", hijacking the state machine. Observed: complete-slice issued
a stray gsd_task_complete for M000, which was auto-created as active
and promoted over the real M028.

Changing the default from "active" to "queued" means phantom milestones
from stray tool calls won't be promoted as active. Combined with the
ghost detection fix (#3645), they'll be cleaned up automatically.

Legitimate callers (plan-milestone, state reconciliation, md-importer)
already pass status explicitly.

Closes #3380

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tibsfox 2026-04-06 19:36:01 -07:00
parent b4c6229360
commit 947ff2ba0a

View file

@ -1119,7 +1119,9 @@ export function insertMilestone(m: {
).run({
":id": m.id,
":title": m.title ?? "",
":status": m.status ?? "active",
// Default to "queued" — never auto-create milestones as "active" (#3380).
// Callers that need "active" must pass it explicitly.
":status": m.status ?? "queued",
":depends_on": JSON.stringify(m.depends_on ?? []),
":created_at": new Date().toISOString(),
":vision": m.planning?.vision ?? "",