Evan Cates explains how to gate dangerous Claude Code actions with PreToolUse hooks
Evan Cates walks through Claude Code's PreToolUse hook system, showing how small shell scripts can inspect and block dangerous agent actions — like force-pushes to main or secret leaks — before they execute.
Score breakdown
The PreToolUse hook is the last deterministic checkpoint before Claude Code executes a destructive or secret-leaking command, making it the primary mechanism for keeping an autonomous coding agent from causing irreversible damage.
- 01PreToolUse is the only Claude Code hook that can block a tool call before it executes, via `exit 2`
- 02The harness serializes the pending tool call as JSON and pipes it to the hook on stdin
- 03Stderr output from a blocking hook is fed back to the model so the agent can adjust its behavior
Evan Cates's guide focuses on Claude Code's `PreToolUse` hook — the lifecycle event that fires before a tool call runs and is the only hook that can block execution. When the agent is about to invoke a tool, the harness serializes the call as JSON to stdin; the hook reads it, inspects the payload, and returns `exit 0` to allow or `exit 2` to block. Stderr output from the hook is passed back to the model, giving the agent context to change course rather than blindly retry. The guide includes a complete bash example that blocks force-pushes to main by pattern-matching the command string, and shows how to register the hook via a `hooks.json` file using a `matcher` on the `Bash` tool.
Second, blast-radius command gating: patterns like `rm -rf "$DIR"` with an unset variable, `git reset --hard`, `chmod 777`, and `curl ...
Three practical gate patterns are covered in depth. First, pre-push secret scanning: hooks should scan outgoing commits (not just the working tree) for credential-shaped strings and forbidden filenames like `.env` or private keys, using `gitleaks` if available with a regex fallback. Second, blast-radius command gating: patterns like `rm -rf "$DIR"` with an unset variable, `git reset --hard`, `chmod 777`, and `curl ... | sh` should be surfaced to a human before running. Third, shared worktree protection: in multi-agent setups, one session can accidentally destroy another's git worktree; the guide recommends gating writes to `.claude/worktrees/` and blocking `git add -A` in repos containing worktrees.
The post also addresses portability: hooks run in the user's shell where `jq` may not be present, so the guide provides a fallback extraction function using `python3`. A hook that errors due to a missing dependency fails open — the dangerous command runs anyway — making graceful degradation critical. Cates also mentions a free, MIT-licensed Claude Code plugin called `cc-powerpack` on GitHub that packages all three gates, and references a paid handbook called *The Claude Code Operator's Handbook* for deeper coverage.
Key facts
- 01PreToolUse is the only Claude Code hook that can block a tool call before it executes, via `exit 2`
- 02The harness serializes the pending tool call as JSON and pipes it to the hook on stdin
- 03Stderr output from a blocking hook is fed back to the model so the agent can adjust its behavior
- 04Three recommended gates: pre-push secret scanning, blast-radius command blocking, and shared worktree protection
- 05A hook that errors due to a missing dependency (e.g., no `jq`) fails open, allowing the dangerous command to run
- 06The guide provides a `python3` fallback for JSON extraction when `jq` is unavailable
- 07Cates published a free MIT-licensed plugin called `cc-powerpack` on GitHub implementing all three gates
Topics
Summary and scoring are generated automatically from the original article. We always link back to the publisher and never republish images or paywalled content. Last processed Jun 12, 2026 · 10:05 UTC. How this works →