When a milestone has only CONTEXT-DRAFT.md, the survivor branch check sets hasSurvivorBranch=true and skips all showSmartEntry calls. Auto-mode then dispatches needs-discussion->stop, creating an infinite loop on every /gsd run. Add a pre-check: when hasSurvivorBranch is true AND phase is needs-discussion, route to the interactive discussion handler. Closes #1726 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a95d420972
commit
dda01fa648
2 changed files with 57 additions and 0 deletions
|
|
@ -315,6 +315,32 @@ export async function bootstrapAutoSession(
|
|||
}
|
||||
}
|
||||
|
||||
// Survivor branch exists but milestone still needs discussion (#1726):
|
||||
// The worktree/branch was created but the milestone only has CONTEXT-DRAFT.md.
|
||||
// Route to the interactive discussion handler instead of falling through to
|
||||
// auto-mode, which would immediately stop with "needs discussion".
|
||||
if (hasSurvivorBranch && state.phase === "needs-discussion") {
|
||||
const { showSmartEntry } = await import("./guided-flow.js");
|
||||
await showSmartEntry(ctx, pi, base, { step: requestedStepMode });
|
||||
|
||||
invalidateAllCaches();
|
||||
const postState = await deriveState(base);
|
||||
if (
|
||||
postState.activeMilestone &&
|
||||
postState.phase !== "needs-discussion"
|
||||
) {
|
||||
state = postState;
|
||||
// Discussion succeeded — clear survivor flag so normal flow continues
|
||||
hasSurvivorBranch = false;
|
||||
} else {
|
||||
ctx.ui.notify(
|
||||
"Discussion completed but milestone draft was not promoted. Run /gsd to try again.",
|
||||
"warning",
|
||||
);
|
||||
return releaseLockAndReturn();
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasSurvivorBranch) {
|
||||
// No active work — start a new milestone via discuss flow
|
||||
if (!state.activeMilestone || state.phase === "complete") {
|
||||
|
|
|
|||
|
|
@ -200,6 +200,37 @@ async function main(): Promise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
// ─── 7. Survivor branch + needs-discussion routes to showSmartEntry (#1726) ─
|
||||
console.log("\n=== 7. Survivor branch + needs-discussion routes to showSmartEntry ===");
|
||||
{
|
||||
const source = readAutoStartSource();
|
||||
|
||||
// When hasSurvivorBranch is true AND phase is needs-discussion, the code
|
||||
// must route to showSmartEntry instead of falling through to auto-mode.
|
||||
const survivorNeedsDiscussion = source.match(
|
||||
/if\s*\(hasSurvivorBranch\s*&&\s*state\.phase\s*===\s*"needs-discussion"\)\s*\{[^}]*showSmartEntry/s,
|
||||
);
|
||||
assertTrue(!!survivorNeedsDiscussion,
|
||||
"hasSurvivorBranch && needs-discussion must route to showSmartEntry");
|
||||
|
||||
// Verify the handler checks if the discussion succeeded
|
||||
const handlerBlock = source.match(
|
||||
/if\s*\(hasSurvivorBranch\s*&&\s*state\.phase\s*===\s*"needs-discussion"\)\s*\{([\s\S]*?)\n \}/,
|
||||
);
|
||||
assertTrue(!!handlerBlock,
|
||||
"found survivor + needs-discussion handler block");
|
||||
if (handlerBlock) {
|
||||
assertTrue(
|
||||
handlerBlock[1].includes('postState.phase !== "needs-discussion"'),
|
||||
"handler must check if phase advanced after discussion",
|
||||
);
|
||||
assertTrue(
|
||||
handlerBlock[1].includes("releaseLockAndReturn"),
|
||||
"handler must abort if discussion didn't promote draft",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
report();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue