Route isolated checkouts to jj workspaces
bash-guard mapped 20 mutating git verbs to their jj equivalents but not `worktree`, so `git worktree add` passed the hook untouched. Claude Code's built-in EnterWorktree/ExitWorktree tools were a second hole: they create a git worktree directly, never going through Bash, so the guard never saw them. A git worktree in a jj repo is not a jj workspace. jj does not manage it, it never appears in `jj workspace list`, and none of jj's workspace bookkeeping applies to it -- the isolated checkout ends up outside the VCS that owns the repo. Add the `worktree` entry to the git->jj map and a PreToolUse matcher on EnterWorktree|ExitWorktree that exits 2 with the jj workspace commands on stderr. The tool matcher replaces a `permissions.deny` entry in user settings.json: it travels with the plugin and names the replacement command instead of failing silently. Read-only `git worktree list` is blocked along with the rest of the verb. It cannot see jj workspaces, so its empty output reads as "no isolated checkouts exist" when several do -- worse than a denial. Verified by running the guard against `git worktree add ../feature` over socket stdin and confirming both the denial and that the reason names `jj workspace add`. The new checks fail against the 1.1.1 map. Tests: 12 passing (bash-guard).
This commit is contained in:
@@ -11,6 +11,16 @@
|
||||
"statusMessage": "Checking jj/attribution policy; gating push on build + tests..."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": "EnterWorktree|ExitWorktree",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "echo 'BLOCKED: git worktrees are not used here — this repo is managed with jj (CLAUDE.md: version control is jj only). Use a jj workspace instead: jj workspace add ../<name> Remove it with: jj workspace forget <name> then delete the directory.' >&2; exit 2",
|
||||
"timeout": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"PostToolUse": [
|
||||
|
||||
Reference in New Issue
Block a user