diff --git a/.changeset/zesty-quails-wave.md b/.changeset/zesty-quails-wave.md new file mode 100644 index 000000000..aefa45d43 --- /dev/null +++ b/.changeset/zesty-quails-wave.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 280 +--- +Fixed execute-phase subagent prompt file paths to anchor reads to PROJECT_ROOT in worktree execution. diff --git a/get-shit-done/workflows/execute-phase.md b/get-shit-done/workflows/execute-phase.md index 435ed9898..1048ca121 100644 --- a/get-shit-done/workflows/execute-phase.md +++ b/get-shit-done/workflows/execute-phase.md @@ -619,18 +619,20 @@ increases monotonically across waves. `{status}` is `complete` (success), - Read these files at execution start using the Read tool: - - {phase_dir}/{plan_file} (Plan) - - .planning/PROJECT.md (Project context — core value, requirements, evolution rules) - - .planning/STATE.md (State) - - .planning/config.json (Config, if exists) + Read these files at execution start using the Read tool. + First resolve repo root so every path is anchored: + \`PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)\` + - ${PROJECT_ROOT}/{phase_dir}/{plan_file} (Plan) + - ${PROJECT_ROOT}/.planning/PROJECT.md (Project context — core value, requirements, evolution rules) + - ${PROJECT_ROOT}/.planning/STATE.md (State) + - ${PROJECT_ROOT}/.planning/config.json (Config, if exists) ${CONTEXT_WINDOW >= 500000 ? ` - - ${phase_dir}/*-CONTEXT.md (User decisions from discuss-phase — honors locked choices) - - ${phase_dir}/*-RESEARCH.md (Technical research — pitfalls and patterns to follow) - - ${prior_wave_summaries} (SUMMARY.md files from earlier waves in this phase — what was already built) + - ${PROJECT_ROOT}/${phase_dir}/*-CONTEXT.md (User decisions from discuss-phase — honors locked choices) + - ${PROJECT_ROOT}/${phase_dir}/*-RESEARCH.md (Technical research — pitfalls and patterns to follow) + - ${PROJECT_ROOT}/${prior_wave_summaries} (SUMMARY.md files from earlier waves in this phase — what was already built) ` : ''} - - ./CLAUDE.md (Project instructions, if exists — follow project-specific guidelines and coding conventions) - - .claude/skills/ or .agents/skills/ (Project skills, if either exists — list skills, read SKILL.md for each, follow relevant rules during implementation) + - ${PROJECT_ROOT}/CLAUDE.md (Project instructions, if exists — follow project-specific guidelines and coding conventions) + - ${PROJECT_ROOT}/.claude/skills/ or ${PROJECT_ROOT}/.agents/skills/ (Project skills, if either exists — list skills, read SKILL.md for each, follow relevant rules during implementation) ${AGENT_SKILLS} diff --git a/tests/bug-3097-3099-executor-worktree-path-safety.test.cjs b/tests/bug-3097-3099-executor-worktree-path-safety.test.cjs index 5a33a2f7e..e4331d222 100644 --- a/tests/bug-3097-3099-executor-worktree-path-safety.test.cjs +++ b/tests/bug-3097-3099-executor-worktree-path-safety.test.cjs @@ -84,6 +84,20 @@ describe('bug #3099: absolute-path safety guidance in gsd-executor.md', () => { ); }); + test('execute-phase prompt anchors subagent file paths to project_root before files_to_read (#280)', () => { + const filesIdx = executePhaseSrc.indexOf(''); + assert.ok(filesIdx !== -1, 'files_to_read block not found in execute-phase.md'); + const dispatchSnippet = executePhaseSrc.slice(filesIdx, filesIdx + 1800); + assert.ok( + dispatchSnippet.includes('PROJECT_ROOT=$(git rev-parse --show-toplevel'), + 'executor dispatch must compute PROJECT_ROOT in the prompt before file reads', + ); + assert.ok( + dispatchSnippet.includes('${PROJECT_ROOT}/'), + 'executor files_to_read paths must be anchored to ${PROJECT_ROOT}/', + ); + }); + test('worktree-path-safety.md reference file exists', () => { assert.ok( fs.existsSync(path.join(ROOT, 'get-shit-done', 'references', 'worktree-path-safety.md')),