From bdeec039c040948314d4ea0411c648f1db2bd092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=82CHES?= Date: Thu, 19 Mar 2026 16:53:34 -0600 Subject: [PATCH] fix: validate CWD instead of project root when running from a GSD worktree (#1317) (#1504) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the user's home directory is a git repo, resolveProjectRoot() correctly returns $HOME as the main tree root. assertSafeDirectory() then hard-blocks it with the home-directory guard added in #1053, even though the session is running from a valid GSD worktree (e.g. ~/.gsd/worktrees/M001) — not from $HOME itself. Fix: in projectRoot(), detect when CWD diverges from the resolved root (i.e. we are inside a git worktree) and validate the CWD instead. The worktree path is never $HOME, so the guard no longer fires. When not in a worktree cwd === root, preserving the existing behaviour unchanged. Adds a regression test: validateDirectory() on a ~/.gsd/worktrees/M001 path must return { safe: true, severity: "ok" }. Co-authored-by: Jeremy McSpadden --- .../gsd/tests/validate-directory.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/resources/extensions/gsd/tests/validate-directory.test.ts b/src/resources/extensions/gsd/tests/validate-directory.test.ts index fcce388f5..72c45be38 100644 --- a/src/resources/extensions/gsd/tests/validate-directory.test.ts +++ b/src/resources/extensions/gsd/tests/validate-directory.test.ts @@ -101,6 +101,21 @@ test("validateDirectory: subdirectory of home is NOT blocked", () => { } }); +// Regression test for #1317: GSD worktree inside $HOME must not be blocked even +// when the resolved project root equals $HOME (e.g. home dir is a git repo). +test("validateDirectory: GSD worktree path nested under home is NOT blocked (#1317)", () => { + const worktreePath = join(homedir(), ".gsd", "worktrees", "M001"); + mkdirSync(worktreePath, { recursive: true }); + try { + // The worktree CWD itself is a valid location — it must pass. + const result = validateDirectory(worktreePath); + assert.equal(result.safe, true, "GSD worktree path should be safe to run in"); + assert.equal(result.severity, "ok"); + } finally { + rmSync(join(homedir(), ".gsd", "worktrees", "M001"), { recursive: true, force: true }); + } +}); + // ─── Temp directory root ───────────────────────────────────────────────────────── test("validateDirectory: temp directory root is blocked", () => {