fix: anchor .sisyphus path check to ctx.directory to prevent false positives

- Uses path.join(ctx.directory, '.sisyphus') + sep as prefix instead of loose .includes()
- Prevents false positive when .sisyphus exists in parent directories outside project root
- Adds test for the false positive case (cubic review feedback)
This commit is contained in:
YeonGyu-Kim
2026-02-07 18:49:16 +09:00
parent 2e99e5382e
commit 31f03401b4
3 changed files with 36 additions and 16 deletions
@@ -267,6 +267,25 @@ describe("createWriteExistingFileGuardHook", () => {
await expect(result).rejects.toThrow("File already exists. Use edit tool instead.")
})
test("blocks write when .sisyphus is in parent path but not under ctx.directory", async () => {
//#given
const fakeSisyphusParent = path.join(os.tmpdir(), ".sisyphus", "evil-project")
fs.mkdirSync(fakeSisyphusParent, { recursive: true })
const evilFile = path.join(fakeSisyphusParent, "plan.md")
fs.writeFileSync(evilFile, "# Evil Plan")
const input = { tool: "Write", sessionID: "ses_1", callID: "call_1" }
const output = { args: { filePath: evilFile, content: "# Hacked" } }
//#when
const result = hook["tool.execute.before"]?.(input as any, output as any)
//#then
await expect(result).rejects.toThrow("File already exists. Use edit tool instead.")
// cleanup
fs.rmSync(path.join(os.tmpdir(), ".sisyphus"), { recursive: true, force: true })
})
test("blocks write to existing regular file (not in .sisyphus)", async () => {
//#given
const regularFile = path.join(tempDir, "regular.md")