diff --git a/.changeset/973-gsd-planner-edit-tool.md b/.changeset/973-gsd-planner-edit-tool.md new file mode 100644 index 000000000..852c99c59 --- /dev/null +++ b/.changeset/973-gsd-planner-edit-tool.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 989 +--- +**`gsd-planner` now ships the `Edit` tool, so it can no longer destroy `ROADMAP.md` via a whole-file `Write`** — the planner had `Write` but not `Edit` (the #571/#581 writer-agent gap), so an in-place ROADMAP edit fell back to a full overwrite that truncated committed milestone history. The `update_roadmap` step now directs scoped `Edit` calls and explicitly forbids passing the full file to `Write`. (#973) diff --git a/agents/gsd-planner.md b/agents/gsd-planner.md index af3d0daf8..f456260a7 100644 --- a/agents/gsd-planner.md +++ b/agents/gsd-planner.md @@ -1,7 +1,7 @@ --- name: gsd-planner description: Creates executable phase plans with task breakdown, dependency analysis, and goal-backward verification. Spawned by /gsd:plan-phase orchestrator. -tools: Read, Write, Bash, Glob, Grep, WebFetch, mcp__context7__* +tools: Read, Write, Edit, Bash, Glob, Grep, WebFetch, mcp__context7__* color: green # hooks: # PostToolUse: @@ -998,6 +998,8 @@ Use template structure for each PLAN.md. These PLAN.md files are the canonical output of this agent. The orchestrator reads each `.planning/phases/{padded_phase}-{slug}/{padded_phase}-{NN}-PLAN.md` from disk after you return; it does NOT read your return message for the file content. +**Write is for net-new PLAN.md only.** For any existing file (`ROADMAP.md`, `.planning/` files) use `Edit` (scoped replacement), never `Write`. See `update_roadmap`. + 1. **Default: write each PLAN.md in a single `Write` call.** On most runtimes this is correct and reliable — do this unless rule 4 applies. 2. **Do NOT return the PLAN.md content in your response.** Your return message is a brief confirmation (see ``); the content lives on disk. 3. **Do NOT use `Bash(cat << 'EOF')` or heredoc** for file creation. Use the `Write` tool. @@ -1062,9 +1064,11 @@ Returns JSON: `{ valid, errors, warnings, task_count, tasks }` Update ROADMAP.md to finalize phase placeholders: +**CRITICAL — use `Edit` (scoped), NOT `Write`, for ROADMAP.md.** A whole-file `Write` destroys all phase entries outside your diff window. Use `Edit` to replace only the target section; use multiple `Edit` calls if needed. NEVER pass the entire ROADMAP.md content to `Write`. + 1. Read `.planning/ROADMAP.md` 2. Find phase entry (`### Phase {N}:`) -3. Update placeholders: +3. Update placeholders using `Edit` (scoped replacement only): **Goal** (only if placeholder): - `[To be planned]` → derive from CONTEXT.md > RESEARCH.md > phase description @@ -1080,7 +1084,7 @@ Plans: - [ ] {phase}-02-PLAN.md — {brief objective} ``` -4. Write updated ROADMAP.md +4. Apply changes with `Edit` (scoped) — use the `gsd roadmap` subcommands (run by the orchestrator) for structural ROADMAP mutations; reserve direct `Edit` for placeholder fills only. diff --git a/docs/AGENTS.md b/docs/AGENTS.md index 85d0fae12..beb3a0f55 100644 --- a/docs/AGENTS.md +++ b/docs/AGENTS.md @@ -161,7 +161,7 @@ GSD uses a multi-agent architecture where thin orchestrators (workflow files) sp |----------|-------| | **Spawned by** | `/gsd-plan-phase`, `/gsd-quick` | | **Parallelism** | Single instance | -| **Tools** | Read, Write, Bash, Glob, Grep, WebFetch, mcp (context7) | +| **Tools** | Read, Write, Edit, Bash, Glob, Grep, WebFetch, mcp (context7) | | **Model (balanced)** | Opus | | **Color** | Green | | **Produces** | `{phase}-{N}-PLAN.md` files | diff --git a/tests/agent-frontmatter.test.cjs b/tests/agent-frontmatter.test.cjs index f39ab5155..9cfe0918f 100644 --- a/tests/agent-frontmatter.test.cjs +++ b/tests/agent-frontmatter.test.cjs @@ -435,6 +435,7 @@ describe('EDITWRITE: section-writer agents must have both Write and Edit in tool 'gsd-phase-researcher', 'gsd-ui-researcher', 'gsd-debug-session-manager', + 'gsd-planner', // #973: planner lacked Edit; whole-file Write truncated ROADMAP.md ]; for (const agent of SECTION_WRITER_AGENTS) {