Worktree-isolation guard refuses plain git commands after a PreToolUse hook wraps them in a launcher (rtk)

Status Open
Reported on v2.1.291
Maintainer reply None cached
Activity 1 comment · opened Oct 6, 2026

Version: 2.1.291 (Claude Code), rtk 0.49.0
Platform: macOS, zsh via the Bash tool
Related: #93592 (same guard, same refusal for jj git <subcommand>)

Summary

In a worktree-isolated session, the model writes a plain git command, but the guard refuses it. The cause is the user's own PreToolUse hook, which rewrote the command into rtk git ... before the guard ran. So the refusal is about a command the model never wrote.

rtk is a token-saving output filter. Its hook returns updatedInput.command with the git command wrapped in rtk.

Setup

"PreToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "rtk hook claude" }] }]

What the hook does to each command, from feeding it PreToolUse payloads directly:

| Command written by the model | After the hook | In an isolated worktree |
|---|---|---|
| git diff | rtk git diff | Refused |
| git -C <wt> diff | rtk git -C <wt> diff | Refused |
| git add a | rtk git add a | Refused |
| git add a 2>&1 \| cat | rtk git add a 2>&1 \| cat | Refused |
| git push origin b | rtk git push origin b | Refused |
| git switch b | unchanged | Runs |
| git rebase origin/master | unchanged | Runs |
| git update-index --add a | unchanged | Runs |
| git diff > f | unchanged | Runs |
| /usr/bin/git push origin b | unchanged | Runs |

Repro

  1. Install the hook above.
  2. Enter a worktree with EnterWorktree.
  3. Run git diff origin/master -- package.json via the Bash tool.

Expected: the command runs. It is a git command in the session's own worktree.

Actual:

This session is isolated in the worktree \<wt\>, but this command runs rtk with a git command among its operands: what runs it, and from which directory or root, cannot be read here (name git right after the launcher and its options) in a plain command, so what it runs cannot be shown not to be git. Refusing to run it — a worktree-isolated session's git operations must target its own worktree. Run the plain command from \<wt\>.

The remedy is not actionable. The model already ran the plain command from <wt>, and the hook rewrites every retry the same way. The only way through is to dodge the user's own hook, by calling /usr/bin/git or by redirecting output. Resolving a rebase conflict in a worktree took several refused round-trips for that reason.

Proposal (either one)

  • Check the command the model wrote. When a PreToolUse hook only prepends a launcher to a command, run the isolation check on the command before the rewrite.
  • Allow-list transparent launchers. Add a setting such as "worktree": { "transparentLaunchers": ["rtk"] }. The guard strips the launcher and checks the remaining git ... like a plain command. This would also cover #93592's jj git if jj were listed.

Impact

Every user of rtk, or of any similar wrapper hook, loses git diff, status, add, checkout, show and push inside EnterWorktree sessions and isolation: "worktree" agents.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗