fix: add filesystem safety guard to complete-slice.md (#3304)

* fix: add filesystem safety guard to complete-slice.md (closes #2935)

Port the EISDIR prevention instruction from complete-milestone.md to
complete-slice.md so the LLM never passes a directory path to the
read tool when task summaries are truncated by the 30k-char cap.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: retrigger CI (flaky #2912 MERGE_HEAD test)

* chore: retrigger CI

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: trek-e <trek-e@users.noreply.github.com>
This commit is contained in:
Tom Boucher 2026-04-05 01:04:52 -04:00 committed by GitHub
parent 34e73b01d1
commit 7bbc0dd621
2 changed files with 27 additions and 0 deletions

View file

@ -35,6 +35,8 @@ Then:
**Autonomous execution:** Do not call `ask_user_questions` or `secure_env_collect`. You are running in auto-mode — there is no human available to answer questions. Make reasonable assumptions and document them in the slice summary. If a decision genuinely requires human input, note it in the summary and proceed with the best available option.
**File system safety:** Task summaries are preloaded in the inlined context above. If you need to re-read any of them, use `find .gsd/milestones/{{milestoneId}}/slices/{{sliceId}}/tasks -name "*-SUMMARY.md"` to list file paths first — never pass `{{slicePath}}` or any other directory path directly to the `read` tool. The `read` tool only accepts file paths, not directories.
**You MUST call `gsd_complete_slice` with the slice summary and UAT content before finishing. The tool persists to both DB and disk and renders `{{sliceSummaryPath}}` and `{{sliceUatPath}}` automatically.**
When done, say: "Slice {{sliceId}} complete."

View file

@ -231,6 +231,31 @@ test("complete-slice prompt uses camelCase parameter names matching TypeBox sche
assert.match(toolCallLine!, /sliceId/);
});
// ─── File system safety: complete-slice parity with complete-milestone (#2935) ──
test("complete-slice prompt includes filesystem safety guard against EISDIR", () => {
const prompt = readPrompt("complete-slice");
assert.match(
prompt,
/File system safety/i,
"complete-slice.md must include a 'File system safety' instruction to prevent EISDIR errors when the LLM passes a directory path to the read tool"
);
assert.match(
prompt,
/never pass.*directory path.*directly to the.*read.*tool/i,
"complete-slice.md must warn against passing directory paths to the read tool"
);
});
test("complete-milestone prompt still has its filesystem safety guard (regression)", () => {
const prompt = readPrompt("complete-milestone");
assert.match(
prompt,
/File system safety/i,
"complete-milestone.md must keep its filesystem safety guard"
);
});
test("reactive-execute prompt references tool calls instead of checkbox updates", () => {
const prompt = readPrompt("reactive-execute");
assert.doesNotMatch(prompt, /checkbox updates/);