Describe the bug
restoreConfigFromBase (src/github/operations/restore-config.ts) restores trusted paths from the PR base branch before the CLI starts, so PR-modified instruction files don't shape Claude's behavior. The list is path-literal and root-only:
const SENSITIVE_PATHS = [
".claude", ".mcp.json", ".claude.json", ".gitmodules", ".ripgreprc",
"CLAUDE.md", "CLAUDE.local.md", ".husky",
];
Root CLAUDE.md was added in #1174 because PR-modified instruction files at startup are a prompt-injection surface. The same surface exists for nested CLAUDE.md (Claude Code auto-loads them from cwd at any depth), but the list cannot match them.
Coverage gap
In tag mode (the default), setupBranch (src/github/operations/branch.ts:184-188) checks out PR head into the working tree. restoreConfigFromBase then restores the literal entries above, leaving everything else from PR head on disk:
- Root
CLAUDE.md → restored from base (covered).
- any nested
CLAUDE.md → PR head version remains, loaded by Claude Code.
- Files referenced via
@-imports inside CLAUDE.md → PR head versions remain.
Claude Code's SDK pushes back on obvious same-PR injection patterns; we tested several variants and they were caught. The argument here is consistency with #1174's precedent: rely on the action's restore step, not on SDK pattern-matching for variants it might miss or future regressions.
Expected behavior
restoreConfigFromBase restores nested CLAUDE.md and CLAUDE.local.md from base in addition to root entries.
API Provider
[x] Anthropic First-Party API (default). Provider-independent; gap is in the pre-SDK restore step.
Next Steps
Happy to PR. Sketch: extend SENSITIVE_PATHS with a basename-match recursive pass for CLAUDE.md / CLAUDE.local.md (git ls-files on PR side, git ls-tree -r origin/<base> on base side), behind an opt-out flag.
Describe the bug
restoreConfigFromBase(src/github/operations/restore-config.ts) restores trusted paths from the PR base branch before the CLI starts, so PR-modified instruction files don't shape Claude's behavior. The list is path-literal and root-only:Root
CLAUDE.mdwas added in #1174 because PR-modified instruction files at startup are a prompt-injection surface. The same surface exists for nestedCLAUDE.md(Claude Code auto-loads them fromcwdat any depth), but the list cannot match them.Coverage gap
In tag mode (the default),
setupBranch(src/github/operations/branch.ts:184-188) checks out PR head into the working tree.restoreConfigFromBasethen restores the literal entries above, leaving everything else from PR head on disk:CLAUDE.md→ restored from base (covered).CLAUDE.md→ PR head version remains, loaded by Claude Code.@-imports inside CLAUDE.md → PR head versions remain.Claude Code's SDK pushes back on obvious same-PR injection patterns; we tested several variants and they were caught. The argument here is consistency with #1174's precedent: rely on the action's restore step, not on SDK pattern-matching for variants it might miss or future regressions.
Expected behavior
restoreConfigFromBaserestores nestedCLAUDE.mdandCLAUDE.local.mdfrom base in addition to root entries.API Provider
[x] Anthropic First-Party API (default). Provider-independent; gap is in the pre-SDK restore step.
Next Steps
Happy to PR. Sketch: extend
SENSITIVE_PATHSwith a basename-match recursive pass forCLAUDE.md/CLAUDE.local.md(git ls-fileson PR side,git ls-tree -r origin/<base>on base side), behind an opt-out flag.