@@ -48,6 +48,7 @@ A Claude Code plugin that acts as a safety net, catching destructive git and fil
4848- [ Advanced Features] ( #advanced-features )
4949 - [ Strict Mode] ( #strict-mode )
5050 - [ Paranoid Mode] ( #paranoid-mode )
51+ - [ Worktree Mode] ( #worktree-mode )
5152 - [ Shell Wrapper Detection] ( #shell-wrapper-detection )
5253 - [ Interpreter One-Liner Detection] ( #interpreter-one-liner-detection )
5354 - [ Secret Redaction] ( #secret-redaction )
@@ -300,6 +301,7 @@ The status line displays different emojis based on the current configuration:
300301| Paranoid mode | ` 🛡️ Safety Net 👁️ ` | ` SAFETY_NET_PARANOID=1 ` — all paranoid checks enabled |
301302| Paranoid RM only | ` 🛡️ Safety Net 🗑️ ` | ` SAFETY_NET_PARANOID_RM=1 ` — blocks ` rm -rf ` even within cwd |
302303| Paranoid interpreters only | ` 🛡️ Safety Net 🐚 ` | ` SAFETY_NET_PARANOID_INTERPRETERS=1 ` — blocks interpreter one-liners |
304+ | Worktree mode | ` 🛡️ Safety Net 🌳 ` | ` SAFETY_NET_WORKTREE=1 ` — relax local git discards inside linked worktrees |
303305| Strict + Paranoid | ` 🛡️ Safety Net 🔒👁️ ` | Both strict and paranoid modes enabled |
304306
305307Multiple mode emojis are combined when multiple environment variables are set.
@@ -398,6 +400,7 @@ npx cc-safety-net explain --cwd /tmp "git status"
398400| rm -rf /var/tmp/... | System temp directory |
399401| rm -rf $TMPDIR/... | User's temp directory |
400402| rm -rf ./... (within cwd) | Limited to current working directory |
403+ | git restore / checkout -- / reset --hard / clean -f (in linked worktree) | Relaxed only when ` SAFETY_NET_WORKTREE=1 ` and cwd is a linked worktree |
401404
402405## What Happens When Blocked
403406
@@ -631,6 +634,48 @@ Paranoid behavior:
631634- ** interpreters** : blocks interpreter one-liners like ` python -c ` , ` node -e ` , ` ruby -e ` ,
632635 and ` perl -e ` (these can hide destructive commands).
633636
637+ ### Worktree Mode
638+
639+ Linked git worktrees are designed as disposable, isolated workspaces — discarding
640+ changes inside one doesn't risk the main working tree. Worktree mode relaxes
641+ local-discard rules when (and only when) the command is proven to run inside a
642+ linked worktree:
643+
644+ ``` bash
645+ export SAFETY_NET_WORKTREE=1
646+ ```
647+
648+ When enabled, these commands are allowed inside a linked worktree:
649+
650+ - ` git restore <file> ` and ` git restore --worktree <file> `
651+ - ` git checkout -- <file> ` , ` git checkout <ref> -- <file> ` , ` git checkout --force ` ,
652+ and ambiguous multi-positional checkout forms
653+ - ` git switch --discard-changes ` and ` git switch -f / --force `
654+ - ` git reset --hard ` and ` git reset --merge `
655+ - ` git clean -f ` (and combined short flags like ` -fd ` )
656+
657+ These remain blocked even in linked worktrees because they reach beyond the
658+ local working tree:
659+
660+ - ` git push --force ` (affects remote)
661+ - ` git branch -D ` (affects shared refs)
662+ - ` git stash drop ` / ` git stash clear ` (stash is shared across worktrees)
663+ - ` git worktree remove --force ` (could delete another worktree)
664+
665+ Detection is fail-closed and mostly filesystem-based:
666+
667+ - A linked worktree is identified by a ` .git ` * file* containing ` gitdir: ` whose
668+ resolved git directory contains a ` commondir ` file. Main worktrees and
669+ submodules don't satisfy this and are not relaxed.
670+ - The cwd walk uses ` realpath ` so symlinked paths resolve correctly.
671+ - ` git -C <path> ` (including chained ` -C ` and attached ` -Cpath ` ) is honored;
672+ unresolved targets keep the command blocked.
673+ - Relaxation is disabled if cwd becomes unknown (e.g., after ` cd ` /` pushd ` ),
674+ if ` --git-dir ` / ` --work-tree ` is passed, or if ` GIT_DIR ` / ` GIT_WORK_TREE `
675+ / ` GIT_COMMON_DIR ` is set in the environment.
676+ - Git may be invoked from a trusted system path to inspect effective config that
677+ could make submodule operations recursive.
678+
634679### Shell Wrapper Detection
635680
636681The guard recursively analyzes commands wrapped in shells:
0 commit comments