fix: use camelCase parameter names in execute-task and complete-slice prompts (#2933) (#3236)

The prompts told the LLM to pass snake_case params (milestone_id, slice_id,
task_id) but the TypeBox schemas expect camelCase (milestoneId, sliceId,
taskId), causing "Missing named parameter" validation errors.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher 2026-03-30 16:31:38 -04:00 committed by GitHub
parent 4a82bc01dc
commit dff73009c8
3 changed files with 31 additions and 2 deletions

View file

@ -29,7 +29,7 @@ Then:
8. Write `{{sliceUatPath}}` — a concrete UAT script with real test cases derived from the slice plan and task summaries. Include preconditions, numbered steps with expected outcomes, and edge cases. This must NOT be a placeholder or generic template — tailor every test case to what this slice actually built.
9. Review task summaries for `key_decisions`. Append any significant decisions to `.gsd/DECISIONS.md` if missing.
10. Review task summaries for patterns, gotchas, or non-obvious lessons learned. If any would save future agents from repeating investigation or hitting the same issues, append them to `.gsd/KNOWLEDGE.md`. Only add entries that are genuinely useful — don't pad with obvious observations.
11. Call `gsd_complete_slice` with milestone_id, slice_id, the slice summary, and the UAT result. Do NOT manually mark the roadmap checkbox — the tool writes to the DB and renders the ROADMAP.md projection automatically.
11. Call `gsd_complete_slice` with milestoneId, sliceId, the slice summary, and the UAT result. Do NOT manually mark the roadmap checkbox — the tool writes to the DB and renders the ROADMAP.md projection automatically.
12. Do not run git commands — the system commits your changes and handles any merge after this unit succeeds.
13. Update `.gsd/PROJECT.md` if it exists — refresh current state if needed: use the `write` tool with `path: ".gsd/PROJECT.md"` and `content` containing the full updated document reflecting current project state. Do NOT use the `edit` tool for this — PROJECT.md is a full-document refresh.

View file

@ -68,7 +68,7 @@ Then:
17. If you discover a non-obvious rule, recurring gotcha, or useful pattern during execution, append it to `.gsd/KNOWLEDGE.md`. Only add entries that would save future agents from repeating your investigation. Don't add obvious things.
18. Read the template at `~/.gsd/agent/extensions/gsd/templates/task-summary.md`
19. Write `{{taskSummaryPath}}`
20. Call `gsd_complete_task` with milestone_id, slice_id, task_id, and a summary of what was accomplished. This is your final required step — do NOT manually edit PLAN.md checkboxes. The tool marks the task complete, updates the DB, and renders PLAN.md automatically.
20. Call `gsd_complete_task` with milestoneId, sliceId, taskId, and a summary of what was accomplished. This is your final required step — do NOT manually edit PLAN.md checkboxes. The tool marks the task complete, updates the DB, and renders PLAN.md automatically.
21. Do not run git commands — the system reads your task summary after completion and creates a meaningful commit from it (type inferred from title, message from your one-liner, key files from frontmatter). Write a clear, specific one-liner in the summary — it becomes the commit message.
All work stays in your working directory: `{{workingDirectory}}`.

View file

@ -202,6 +202,35 @@ test("reassess-roadmap prompt names gsd_reassess_roadmap as the tool to use", ()
assert.match(prompt, /gsd_reassess_roadmap/);
});
// ─── Bug #2933: prompt parameter names must match camelCase TypeBox schema ───
test("execute-task prompt uses camelCase parameter names matching TypeBox schema", () => {
const prompt = readPrompt("execute-task");
// The gsd_complete_task tool schema uses camelCase: milestoneId, sliceId, taskId
// Prompts must NOT tell the LLM to use snake_case (milestone_id, slice_id, task_id)
const toolCallLine = prompt.split("\n").find((l) => /gsd_complete_task/.test(l) || /gsd_task_complete/.test(l));
assert.ok(toolCallLine, "prompt must contain a gsd_complete_task or gsd_task_complete tool call line");
assert.doesNotMatch(toolCallLine!, /milestone_id/, "must use milestoneId, not milestone_id");
assert.doesNotMatch(toolCallLine!, /slice_id/, "must use sliceId, not slice_id");
assert.doesNotMatch(toolCallLine!, /task_id/, "must use taskId, not task_id");
// Positive: must mention the camelCase names
assert.match(toolCallLine!, /milestoneId/);
assert.match(toolCallLine!, /sliceId/);
assert.match(toolCallLine!, /taskId/);
});
test("complete-slice prompt uses camelCase parameter names matching TypeBox schema", () => {
const prompt = readPrompt("complete-slice");
// The gsd_complete_slice tool schema uses camelCase: milestoneId, sliceId
const toolCallLine = prompt.split("\n").find((l) => /gsd_complete_slice/.test(l) || /gsd_slice_complete/.test(l));
assert.ok(toolCallLine, "prompt must contain a gsd_complete_slice or gsd_slice_complete tool call line");
assert.doesNotMatch(toolCallLine!, /milestone_id/, "must use milestoneId, not milestone_id");
assert.doesNotMatch(toolCallLine!, /slice_id/, "must use sliceId, not slice_id");
// Positive: must mention the camelCase names
assert.match(toolCallLine!, /milestoneId/);
assert.match(toolCallLine!, /sliceId/);
});
test("reactive-execute prompt references tool calls instead of checkbox updates", () => {
const prompt = readPrompt("reactive-execute");
assert.doesNotMatch(prompt, /checkbox updates/);