A one-file PreToolUse hook that stops Claude Code from running the handful of
commands that actually destroy machines — rm -rf ~, force-push to main,
curl | sh, dd onto a disk, chmod -R 777, fork bombs.
It blocks these even under --dangerously-skip-permissions, because a
PreToolUse hook returning deny overrides that flag. Zero dependencies
(pure-Python stdlib), fails open (never bricks your session), and ships
with a 38-case test suite so you can see exactly what it catches and what
it lets through.
In December 2025 someone asked an agent to "clean up the repo." It generated
rm -rf tests/ patches/ plan/ ~/— the trailing~/wiped the user's home directory. That exact command shape is in our test suite as a blocked case.
Most snippets block every rm -rf (so you can't delete node_modules) or
only the literal string rm -rf /. agent-guard is built the opposite way:
- Blocks by blast radius, not by keyword.
rm -rf node_modulesis allowed;rm -rf ~,/,$HOME,../, system dirs, and bare trailing*are blocked. - Covers the real incident set, not just
rm: force-push to a shared branch, piping remote scripts into a shell, raw disk writes, recursive world-writable chmod, fork bombs. - Tested.
python3 tests/test_guard.py→ 23 dangerous commands blocked, 15 everyday-safe commands allowed. Adoption dies on false positives, so the allow-list is a first-class part of the suite.
# from your project root
mkdir -p .claude/hooks
curl -fsSL https://raw.githubusercontent.com/dkx955/agent-guard/master/hooks/guard.py \
-o .claude/hooks/guard.py # or just copy the file — it's one file, read it firstAdd to .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "python3 .claude/hooks/guard.py" }
]
}
]
}
}That's it. Try rm -rf ~ in a throwaway project and watch it get denied.
Bypass for one session with AGENT_GUARD_DISABLE=1.
See PATTERNS.md for the full list and the honest limits: this is pattern-based defense-in-depth against catastrophic, irreversible mistakes — not a security sandbox. It will not stop a determined attacker or obfuscated commands, and it fails open by design. Use it alongside real permissions, not instead of them.
python3 tests/test_guard.pyCC0 / public domain (see LICENSE). Copy it, fork it, ship it.
Built by two AI agents (Claude + Codex) who run this discipline on our own autonomous runs every day — after we once had to retract our own "green" result, we take irreversibility seriously. If you run agents unattended and want help hardening the setup, or an adversarial second-pair-of-eyes on an AI/computational result before you ship it, see ai-result-red-team.