]> git.ekhem.eu.org Git - guix.git/commitdiff
[hooks] Harden block-worktrees against branch deletion and rm of worktree dirs
authorJakub Czajka <jakub@ekhem.eu.org>
Fri, 31 Jul 2026 09:24:29 +0000 (09:24 +0000)
committerJakub Czajka <jakub@ekhem.eu.org>
Mon, 24 Aug 2026 14:59:46 +0000 (14:59 +0000)
.claude/hooks/block-worktrees

index ede997baee122305e434fe39bc582425fb496959..6d75e05db2a72dc1e6b1ddb17abd43b2e3741460 100755 (executable)
@@ -5,7 +5,10 @@
 # block-worktrees — Enforce worktree isolation.
 #
 # Matches all tool types (*).  Only active inside a worktree.
-# Denies writes to main, branch switches, and exit-with-remove.
+# Denies writes to main, branch switches, git worktree removal,
+# and filesystem destruction of worktree directories.
+# Silently converts ExitWorktree remove→keep so worktrees are
+# never deleted.
 
 # Pre-flight: critical environment variables.
 if [ -z "$GUIX_BIN" ]; then
@@ -69,8 +72,11 @@ ExitWorktree)
         | $GUIX_BIN/sed -n \
             's/.*"action"[[:space:]]*:[[:space:]]*"\([^"]\+\)".*/\1/p')
     if [ "$action" = "remove" ]; then
-        die "ExitWorktree with action: remove is disabled." \
-            "Use action: keep instead."
+        echo \
+            '{"hookSpecificOutput":{' \
+            '"permissionDecision":"allow",' \
+            '"modifiedInput":{"action":"keep"}}}'
+        exit 0
     fi ;;
 
 Write|Edit)
@@ -94,10 +100,17 @@ Bash)
         *"git checkout"*|*"git switch"*)
             die "Branch switching disabled." ;;
         *"git worktree remove"*|*"git worktree prune"*)
-            if ! echo "$cmd" \
-                | $GUIX_BIN/sed --quiet '/merge-worktree/q0;$q1'
+            die "Worktree removal via git is disabled." ;;
+        *"git branch -d"*|*"git branch -D"*|\
+        *"git branch --delete"*)
+            die "Branch deletion is disabled in worktrees." ;;
+        *"rm "*|*"rmdir "*|*"unlink "*)
+            if echo "$cmd" \
+                | $GUIX_BIN/sed --quiet \
+                    '/\.claude\/worktrees\//q0;$q1'
             then
-                die "Git on main blocked. Use /merge-worktree."
+                die \
+                 "Removal of worktree directories is disabled."
             fi ;;
         *"$proj_root"*|*'$proj_root'*|*'${proj_root}'*)
             if echo "$cmd" \