Stop Claude Code repeating the same mistakes with mechanical PreToolUse guards
Install the zero-config self-kill Bash guard as a Claude Code plugin (or copy the seven hooks/tools), merge the hooks block into settings.json, turn optional rules on only with real values, then prove a blocked command with their test suite — each guard exists because an agent made that mistake more than once.

Tools used
- Claude CodeRuns PreToolUse / Stop hooks the guards register
- claude-code-mistake-guardsPlugin + hook/scripts repo with tests for each gate
- Python 3Runtime for the guard scripts (stdlib only for most)
Step navigator
A working PreToolUse Bash guard that denies a bare pkill -f matching the shell's own command line (or your configured optional rules), plus a green run_all.sh if you copied the full set.
Developers who already run Claude Code daily and keep seeing the same irreversible mistakes after writing them down in CLAUDE.md.
Before you start
From June–October 2026 the synuracore / hadiux0295 team logged 300+ real Claude Code mistakes while shipping apps and marketplace listings. Written "be careful" notes did not survive into next week's session, so they replaced repeats with mechanical gates: three Claude Code hooks and four pre-ship scripts. Show HN landed 30 Oct 2026. This guide follows their README: plugin install for the self-kill guard, copy-install for the rest, merge-don't-overwrite settings, and "one rule = one mistake that actually happened." Marketplace-specific tables in ship_check / gen_gate stay examples you replace — we do not invent your banned-word list.
Step-by-step instructions
Install the zero-config self-kill plugin first
Their default path: add the marketplace and install the plugin so a PreToolUse Bash hook runs python3 hooks/guard_bash.py. It reads the pending command from stdin and denies when a rule matches. Only self_kill is on in the plugin. The bug it blocks: pkill -f server.js matches the shell that runs it (pattern appears in that shell's own command line), so the tool call dies with exit 143/144 and nothing after it runs; a while pgrep -f … wait never ends. Fix the guard tells Claude: pkill -A -f server.js (-A = ignore ancestors, procps-ng 4.0.3+). Override one command with GUARD_OK=self_kill in it.
/plugin marketplace add hadiux0295/claude-code-mistake-guards /plugin install synura-mistake-guards@synuracore

Why this works
Written \"don't pkill -f\" rules did not stop the repeat; the hook does.
Or copy all seven guards and merge settings — do not overwrite
Full set: clone the repo, mkdir -p .claude/hooks tools, copy hooks/*.py and tools/*.py, then merge the hooks block from their settings.json into your project's .claude/settings.json. Do not overwrite an existing file. If you already have a Bash PreToolUse entry, put guard_bash.py inside that same entry — with three separate Bash entries their blocking inside one long session was unreliable; merged into one, it blocked every time (observed, cause unknown). Then edit values at the top of each file / via env: GUARD_SAFE_PULL, GUARD_BLOCKED_SITES, GUARD_UPLOAD_ROOT, GUARD_FIRST_COMMIT_LINE, short-save matcher, Stop-hook RULES, and the tables inside tools/*.py.
Why this works
Copy without merge wipes hooks you already rely on.
Know what each guard blocks — only from mistakes that already happened
Their table (condensed): (1) guard_bash.py — self-kill pkill/pgrep -f, optional bare git pull, blocked marketplace headless pages, upload-root scatter, first-commit said: line; (2) guard_short_save.py — save under ~300 chars to an overwrite MCP tool (placeholder body wiped a record twice); (3) stop_check.py — replies that judge eligibility from web search or read bot traffic as demand without the required fact; (4–7) pre-ship scripts for tag limits / banned words / preview video, generation fact gates, duplicate titles, sprite baseline feet. Principle they state: one rule = one mistake that actually happened; fail open on checker bugs; overrides are explicit tokens.
Why this works
Speculative rules get disabled after false positives; theirs had to earn their keep.
Prove it in a real session, then run their test suite
After install: type one command that must be blocked in a real Claude Code session and watch it get denied. For the full copy install, run bash run_all.sh and expect == result: ALL PASS. Each test_*.sh checks both directions — what must block blocks, and ordinary replies like "I set up the users table" still pass. They verified live on Claude Code 2.1.310 / 2.1.316 (2026-10/11): bare git pull denied when configured; Stop hook forced a rewrite of a "traffic grew, so there's demand" reply; on Linux 2.1.316 a plain pkill -f still exited 144 without the plugin, and the plugin denied it before run.
Why this works
A guard you never trigger in a real session is documentation, not a gate.
End of guide · Reviewed Nov 1, 2026
Pro tips2
- One rule = one mistake that already happened twice; no speculative gates.
- Merge the hooks block into existing .claude/settings.json — three separate Bash PreToolUse entries were unreliable in their tests; one merged entry blocked every time.
Common mistakes2
- Relying on CLAUDE.md apologies — they watched the same pkill -f self-kill and fake-green-tests repeat after written rules.
- Overwriting settings.json instead of merging; you lose your other hooks.







