boucle

Safety hooks for Claude Code. Prevent file deletion, block dangerous commands, enforce your rules.

The problem

Claude Code's CLAUDE.md rules are probabilistic, not deterministic. Its permission system has known bypass patterns. Users have lost 87GB of personal data, had 30+ files destroyed despite 100+ rules, and seen explicit instructions ignored.

These hooks enforce covered tool-call boundaries that text rules and permissions often miss. On macOS and Linux, use bash, python3, and jq. 1,900+ tests. Searchable Claude Code gaps documented with severity ratings and workarounds.

Check your setup

Run the audit from the same project root where you start Claude Code. If you are inside a git checkout, move to the repo root first so project hooks in .claude/settings.json are visible. Outside git, stay in the project directory you use for Claude Code:

$ repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" $ cd "$repo_root" $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/safety-check/check.sh | bash

Audit boundary: this downloads tools/safety-check/check.sh from GitHub raw content and runs it locally on your current project and Claude Code settings. The checker does not upload settings.json, hook files, shell history, repository contents, session logs, or safety summary output.

Scores your Claude Code safety configuration from A to F. Shows one-liner fixes for each gap. No hook installation required for the audit. Its summary counts the 7 standalone hooks plus enforce-hooks as 8 hook slots. For the 10-minute path from audit to verified hooks, follow the safety-check quickstart.

If you want to try the checker before it reads your real Claude Code settings, use the temporary first test. It downloads check.sh from GitHub raw content, runs locally in an isolated temporary HOME, installs nothing, uploads no settings, hook files, shell history, repository contents, or summary output, and cleans up the temporary directories automatically unless you set KEEP_BOUCLE_FIRST_TEST=1.

After installing hooks, verify that they actually block representative hook payloads. Safety-check invokes the hook scripts with Claude-style JSON input; it does not execute the dangerous shell or git commands named in those payloads. Add --strict when a fail-open, skipped, or inconclusive hook check should return a failing exit code:

$ repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" $ cd "$repo_root" $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/safety-check/check.sh | bash -s -- --verify --strict

Read the strict result as boundary evidence, not as a badge. Verify: not run, no hooks found, 0 payload checks, FAIL-OPEN, or skipped PreToolUse checks mean the hook layer is still unproven. When the summary says Verify: 0 FAIL-OPEN with no skipped boundary hooks, start a fresh Claude Code session from the same root and document residual platform warnings instead of reinstalling repeatedly to chase an A. The repair order is in the safety summary triage guide.

When asking for help, use --summary-only to print just the bounded public support block. Share only that block plus OS, shell, Claude Code version, and what changed recently. Do not send raw settings, hook source, transcripts, session logs, repository access, tokens, private URLs, or proprietary CLAUDE.md rules:

$ repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" $ cd "$repo_root" $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- check --verify --summary-only

On native Windows, run the PowerShell verifier from PowerShell 7 (pwsh). It tests the native .ps1 hooks without bash or jq; use WSL or Git Bash only when you need the full bash-based safety-check audit:

PS> $root = if (Get-Command git -ErrorAction SilentlyContinue) { git rev-parse --show-toplevel 2>$null } PS> if ($root) { Set-Location $root } PS> iex "& { $(irm https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.ps1) } verify"

Start with the essentials

Install boundary: these commands download tools/install.sh or tools/install.ps1 from GitHub raw content and run it locally. Installing adds managed hook files under ~/.claude/<hook-name>/ (hook.sh on macOS/Linux, hook.ps1 on native Windows) and updates ~/.claude/settings.json; project settings are inspected from the project root when you verify, check, or run doctor. The installer does not upload your settings, hook files, shell history, repository contents, or safety summary output.

$ repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" $ cd "$repo_root" $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- recommended $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- verify

Installs bash-guard + git-safe + file-guard: the safety net every Claude Code user should have. Block dangerous commands, prevent destructive git operations, protect sensitive files. Once installed, run the installer-managed strict safety audit:

$ repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" $ cd "$repo_root" $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- check --verify --strict

On native Windows, install the same recommended set from PowerShell 7 and verify the native hooks with install.ps1 verify:

PS> $root = if (Get-Command git -ErrorAction SilentlyContinue) { git rev-parse --show-toplevel 2>$null } PS> if ($root) { Set-Location $root } PS> iex "& { $(irm https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.ps1) } recommended" PS> iex "& { $(irm https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.ps1) } verify"

After a clean verification, start a fresh Claude Code session from that same project root before relying on the new hook boundary. When Claude Code updates or starts behaving differently, use the update checklist to back up settings, refresh hooks, and re-run strict verification before trusting a session with real work.

For a borrowed machine, client repository, CI runner, or any other temporary trial, snapshot settings before installing, remove the hooks when done, restore only after inspecting backups, and verify cleanup before leaving the environment:

$ repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" $ cd "$repo_root" $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- backup $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- recommended $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- verify $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- uninstall all $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- backup list $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- restore settings.20260101_120000.json $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/safety-check/check.sh | bash -s -- --verify --summary-only

On native Windows, use the same order with PowerShell 7:

PS> $root = if (Get-Command git -ErrorAction SilentlyContinue) { git rev-parse --show-toplevel 2>$null } PS> if ($root) { Set-Location $root } PS> iex "& { $(irm https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.ps1) } backup" PS> iex "& { $(irm https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.ps1) } recommended" PS> iex "& { $(irm https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.ps1) } verify" PS> iex "& { $(irm https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.ps1) } uninstall all" PS> iex "& { $(irm https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.ps1) } backup list" PS> iex "& { $(irm https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.ps1) } restore settings.20260101_120000.json" PS> iex "& { $(irm https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.ps1) } verify"

Use backup list first, then restore the named backup you intend to use. Replace settings.20260101_120000.json with the backup name you selected. Run bare install.sh restore only when the most recent saved ~/.claude/settings.json is the exact snapshot you want back. The complete walkthrough is in the temporary hook trial recipe.

Install all hooks

$ repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" $ cd "$repo_root" $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- all $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/install.sh | bash -s -- verify

install.sh all installs the 7 standalone hooks. Or pick individual hooks and audit tools:

  • enforce-hooks — turn CLAUDE.md rules into verified runtime checks. Your rules say "never edit .env" but Claude edits it anyway. This reads your rules and blocks covered tool-call violations. One dynamic hook, re-reads CLAUDE.md on every tool call. Self-protection mode (--armor) protects configured hook files from covered file-write paths. ~71 tests. Details.
    $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/enforce/install.sh | bash $ python3 .claude/hooks/enforce-hooks.py --verify $ python3 .claude/hooks/enforce-hooks.py --smoke-test

    Install boundary: this downloads tools/enforce/install.sh and tools/enforce/enforce-hooks.py from GitHub raw content, then runs them locally in the current project. It may create CLAUDE.md, install .claude/hooks/enforce-hooks.py, update project .claude/settings.json, and add armor rules for the generated hook files. It does not upload CLAUDE.md, settings, hook files, shell history, repository contents, or audit output.

  • safety-check — audit your Claude Code setup in 5 seconds. Scores your configuration from A to F, shows one-liner fixes for each gap, detects 20+ platform bugs and permission pitfalls that silently break your setup (colon in paths, deny+denyWrite conflicts, bypassPermissions resets, and more), scans your CLAUDE.md for rules that could be enforced by hooks. No hook installation required for the audit. Covered by hundreds of tests.
    $ repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" $ cd "$repo_root" $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/safety-check/check.sh | bash
  • read-once — stops Claude Code from re-reading files already in context. Diff mode shows only what changed. Saves 30%+ tokens per session.
    $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/read-once/install.sh | bash
  • file-guard — protects .env, certificates, SSH keys, and other sensitive files. Write-protect (default) blocks edits; deny mode blocks all access including reads. Resolves symlinks to prevent bypass via symbolic links.
    $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/file-guard/install.sh | bash
  • git-safe — prevents destructive git operations (force push, push --delete, reset --hard, checkout ., checkout HEAD -- path, restore, clean -f, branch -D, --no-verify). Suggests safer alternatives.
    $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/git-safe/install.sh | bash
  • bash-guard — blocks dangerous bash commands (rm -rf /, sudo/pkexec/doas, curl|bash, chmod -R 777, disk utilities (diskutil erase, fdisk, parted, wipefs), Docker destruction, database drops, credential exposure, cloud infra deletion (terraform destroy, kubectl delete/drain/scale-to-zero, helm uninstall, aws ec2 terminate/rds delete/cloudformation delete-stack, az group delete, doctl destroy, flyctl destroy, heroku apps:destroy, vercel rm, netlify sites:delete), mass file deletion, shred, truncate, data exfiltration, programmatic env dumps, sensitive file reads, system database corruption, git push --force). Detects encoding bypasses (base64/hex decode piped to shell, reversed strings, process substitution downloads). Catches programming language shell wrappers (python subprocess, ruby system, perl exec, node child_process). Evaluates compound commands. Catches multi-line comment bypass (#38119). Covered by hundreds of bash tests, with additional PowerShell coverage when pwsh is available.
    $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/bash-guard/install.sh | bash
  • branch-guard — prevents direct commits to protected branches (main, master, production, release). Forces feature-branch workflow.
    $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/branch-guard/install.sh | bash
  • worktree-guard — prevents data loss when exiting worktrees. Blocks exit if there are uncommitted changes, untracked files, unmerged commits, or unpushed commits. Addresses #38287.
    $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/worktree-guard/install.sh | bash
  • session-log — audit trail that logs routed PostToolUse events to JSONL: covered files read/written, commands run, and timestamps.
    $ curl -fsSL https://raw.githubusercontent.com/Bande-a-Bonnot/Boucle-framework/main/tools/session-log/install.sh | bash

Common problems

Detailed recipes with issue references and install commands →

  • Claude deleted my files — install bash-guard + git-safe. They block rm -rf, git checkout ., git reset --hard, and 25+ other destructive patterns.
  • Claude ignores my CLAUDE.md rules — install enforce-hooks. Turns text rules into verified checks for covered tool calls.
  • Claude runs commands I told it not to — install bash-guard. Evaluates every command segment, catches compound commands and multi-line bypass.
  • I want to see what Claude is doing — install session-log. Logs routed PostToolUse events with timestamps to JSONL.
  • Claude edits sensitive files — install file-guard. Protects .env, certificates, SSH keys. Write-protect or full deny.
  • Claude commits to main — install branch-guard. Forces feature-branch workflow on protected branches.
  • Worktree exit loses my commits — install worktree-guard. Blocks exit until changes are committed, merged, or pushed.
  • I'm on Windows — all seven standalone hooks ship with native PowerShell 7 equivalents (hook.ps1): bash-guard, file-guard, git-safe, branch-guard, read-once, worktree-guard, and session-log. No jq or bash needed for native install, verify, or doctor. Use install.ps1 verify after installing or after Claude Code updates.

Agent framework

The hooks above work standalone. The framework below is for running autonomous AI agents in a loop.

$ git clone https://github.com/Bande-a-Bonnot/Boucle-framework.git $ cd Boucle-framework && cargo build --release $ export PATH="$PWD/target/release:$PATH" $ mkdir my-agent && cd my-agent $ boucle init --name my-agent $ boucle doctor $ boucle run --dry-run $ boucle run

Or download a pre-built binary from the releases page.

  • Loop runner — schedule via cron/launchd, with locking and logging
  • Broca memory — BM25 search, temporal decay, garbage collection. Git-native, no database
  • MCP server — expose memory as Model Context Protocol tools
  • Approval gates — human-in-the-loop for anything with consequences

200+ Rust tests. Pre-built binaries on the releases page.

Links