fix(gsd): add incremental persistence to discuss prompts

Discuss sessions with no persistence lost all confirmed work on crash.
Now both milestone and slice discuss prompts instruct agents to
silently save CONTEXT-DRAFT every 2 question rounds via
gsd_summary_save. The final context file overwrites the draft.

Closes #2152

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tibsfox 2026-04-07 03:27:46 -07:00
parent b4c6229360
commit 3f5956d7c3
3 changed files with 39 additions and 1 deletions

View file

@ -40,7 +40,8 @@ After the user answers, investigate further if any answer opens a new unknown, t
After each round of answers, decide whether you already have enough depth to write a strong context file.
- If not, investigate any newly-opened unknowns and continue to the next round immediately. Do **not** ask a meta "ready to wrap up?" question after every round.
- **Incremental persistence:** After every 2 question rounds, silently save a `{{milestoneId}}-CONTEXT-DRAFT.md` with your current understanding using `gsd_summary_save` with `artifact_type: "CONTEXT-DRAFT"`. This protects against session crashes losing all confirmed work. Do NOT mention this save to the user — it's invisible bookkeeping. The final context file will overwrite it.
- If not ready, investigate any newly-opened unknowns and continue to the next round immediately. Do **not** ask a meta "ready to wrap up?" question after every round.
- Use a single wrap-up prompt only when you genuinely believe the depth checklist is satisfied or the user signals they want to stop.
- **If `{{structuredQuestionsAvailable}}` is `true` and you need that wrap-up prompt:** use `ask_user_questions` with options:
- "Write the context file" *(recommended when depth is satisfied)*

View file

@ -34,6 +34,7 @@ After the user answers, investigate further if any answer opens a new unknown, t
After each round of answers, decide whether you already have enough signal to write the slice context cleanly.
- **Incremental persistence:** After every 2 question rounds, silently save a draft `{{sliceId}}-CONTEXT-DRAFT.md` in `{{sliceDirPath}}` using `gsd_summary_save` with `milestone_id: {{milestoneId}}`, `slice_id: {{sliceId}}`, `artifact_type: "CONTEXT-DRAFT"`. This protects against session crashes losing confirmed work. Do NOT mention this to the user. The final context file will replace it.
- If not, investigate any new unknowns and continue to the next round immediately. Do **not** ask a meta "ready to wrap up?" question after every round.
- Ask a single wrap-up question only when you genuinely believe the slice is well understood or the user signals they want to stop.
- When you do ask it, use `ask_user_questions` with:

View file

@ -0,0 +1,36 @@
/**
* Regression test for discuss phase incremental persistence (#2152).
* Verifies both milestone and slice discuss prompts instruct agents to
* save CONTEXT-DRAFT incrementally during question rounds.
*/
import { describe, test } from "node:test";
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const promptsDir = join(__dirname, "..", "prompts");
describe("discuss incremental persistence (#2152)", () => {
test("milestone discuss prompt includes CONTEXT-DRAFT save instruction", () => {
const content = readFileSync(join(promptsDir, "guided-discuss-milestone.md"), "utf-8");
assert.match(content, /CONTEXT-DRAFT/, "should mention CONTEXT-DRAFT");
assert.match(content, /Incremental persistence/, "should have incremental persistence section");
assert.match(content, /gsd_summary_save/, "should use gsd_summary_save tool");
});
test("slice discuss prompt includes CONTEXT-DRAFT save instruction", () => {
const content = readFileSync(join(promptsDir, "guided-discuss-slice.md"), "utf-8");
assert.match(content, /CONTEXT-DRAFT/, "should mention CONTEXT-DRAFT");
assert.match(content, /Incremental persistence/, "should have incremental persistence section");
});
test("drafts are saved silently without user notification", () => {
const milestone = readFileSync(join(promptsDir, "guided-discuss-milestone.md"), "utf-8");
const slice = readFileSync(join(promptsDir, "guided-discuss-slice.md"), "utf-8");
assert.match(milestone, /Do NOT mention this save to the user/);
assert.match(slice, /Do NOT mention this to the user/);
});
});