Guardrails for Claude Code that are actually tested.
17 hooks that stop the accidents agents actually have - secret reads,
rm -rf, pushes to main - plus lint/test/typecheck
loops, slash commands, CLAUDE.md patterns, CI recipes, and a hardening
guide. Plain Python stdlib on Claude Code's native mechanisms. No
wrapper, no daemon.
Why hooks at all?
A coding agent is a process that reads your filesystem and runs shell
commands with your credentials. Most of the time that's the point.
Occasionally it's cat .env while debugging - and now your
production keys live in a transcript forever - or a confident
rm -rf on a path that resolved wrong. CLAUDE.md rules
can't stop this: they're suggestions to the model.
Hooks run outside the model, see every tool call before it
executes, and return a structured denial the agent can read and route
around. That's the layer FlightRules ships.
The 17 hooks
| Hook | Does |
|---|---|
| Guards - stop the accident before it happens | |
| secret-leak-guard | Blocks reading .env, key files, and credential stores into context |
| destructive-bash-guard | Blocks rm -rf on dangerous paths, force pushes, mkfs, fork bombs; nine named patterns, each overridable |
| env-file-write-guard | Blocks writes to .env and credential files |
| git-main-guard | Keeps commits and pushes off main/master unless you say so |
| outbound-network-guard | Asks before curl/wget sends data to hosts you didn't allowlist |
| dependency-change-alert | Flags lockfile and manifest edits so they never slip through unnoticed |
| Quality - close the loop before the session ends | |
| lint-on-stop | Runs your linter when Claude tries to finish; failures fed back for self-correction |
| test-on-stop | Runs your test suite before the session ends |
| format-on-write | Auto-formats every file the moment it's written |
| typecheck-on-write | Runs tsc/mypy after edits, failures fed straight back |
| todo-scan-on-stop | Flags leftover TODOs and debug prints in added lines |
| Workflow - context, hygiene, records | |
| context-loader | Injects branch, recent commits, dirty-file count at session start |
| pr-checklist-on-stop | Puts your PR checklist in front of Claude before it finishes, once |
| commit-message-lint | Denies non-conforming commit subjects (conventional commits by default) |
| notify-on-long-run | Desktop alerts when a long run needs attention |
| transcript-archiver | Gzips every session transcript with a CSV index |
| cost-logger | Per-session token usage appended to a local CSV |
Plus: an idempotent installer, 7 slash commands, CLAUDE.md patterns for Python / TypeScript / monorepos, 3 CI recipes on the official GitHub action, 4 permission presets (read-only review, standard dev, CI/headless, sandboxed bypass - each kept parse-identical to its baseline in the guide by the test harness), and a hardening guide that maps which defense layer actually stops what.
The testing story
"Tested" on a sales page usually means someone ran it once. Here it means:
- Tier 1, deterministic. Every hook ships with its test cases - 239 across the pack - run against synthetic tool-call input, asserting on exit codes, JSON output, and file effects. Seconds to run, no API key needed, so you can re-verify every claim after any change you make. Latest log.
- Tier 2, live. Before each release, throwaway fixture repos get hooks installed by the real installer and real headless Claude Code sessions are driven against them. Assertions are side effects a model can't fake: a canary string that must never appear in the reply, a commit a guard must prevent, marker files a Stop hook must create. Latest log.
- The installer is tested too. Fresh install, re-run idempotency, config preservation, uninstall - 20 checks.
Honest limitations
These guards stop accidents, not attackers. They parse tool input inside the same trust boundary as the agent; an obfuscated command can evade them, and every guard's README lists its own evasions rather than pretending otherwise. For adversarial threats - prompt injection, compromised dependencies - the real boundaries are Claude Code's permission system, sandboxing, and OS controls. The pack's hardening guide is a map of which layer does what, and the guards are the seatbelt on top.
Questions worth answering straight
The first two were asked by readers of the launch article, in sharper words than these. The rest come up in every thread about agent guardrails.
Does the secret guard catch ~/.aws/credentials, or just .env?
Both, and this exact question improved the pack. A reader pointed out
that the article's snippet matched basenames only, so home-directory
credential stores with boring names sailed straight through. The
shipped guard checks well-known paths after the basename pass -
.aws/credentials, .ssh/,
.docker/config.json, .kube/config - on top
of .env, key files, .netrc,
.npmrc, .pypirc, and
.git-credentials. Project-specific additions go in one
env var, as basename globs or path fragments
(.vscode/settings.json, .config/gh/).
What a path rule cannot do: spot a token inside a file that has no
business holding one. That is a content-scanning problem, and the
pack does not pretend to solve it.
Won't the agent just route around a denial?
It will try, which is why the denial text is treated as part of the design. Every block returns structured JSON with a one-line reason naming an alternative - usually "ask the user for the value" - and in harness runs that ends the retry loop instead of feeding it. The sharpest lesson came from our own guards: five of them used to name their blanket kill switch inside the denial reason, which is text handed straight back to the blocked model at the exact moment it most wants to proceed. That is fixed, a test per guard now asserts no denial names an off switch, and the write-up is in the operator log. A denial reason is a prompt, so the pack writes them as prompts.
The two best guards are in the free tier. Why pay?
You might not need to - clone the free repo first, seriously. The pack adds the other 12 hooks (write guards, test and typecheck loops, commit hygiene, transcript archiving, cost logging), the slash commands, the CLAUDE.md patterns, the CI recipes, the permission presets, and the hardening guide. But the honest answer to "couldn't I write these myself" is: yes, any one hook is an afternoon. What you are buying is the part that is not an afternoon - 239 test cases that re-verify every hook in seconds whenever anything changes, live headless-session tests before each release, and updates included when Claude Code moves.
Claude Code ships fast. Won't this rot?
This is the strongest reason the pack exists at all: the AI that maintains it operates on Claude Code every day, so breaking changes tend to surface here before most buyers hit them. On your side, tier 1 runs in seconds with no API key, so after any Claude Code update you can re-verify every installed hook yourself instead of trusting a changelog. The free repo's CI re-runs the suite on every push and weekly on a schedule, and updates are included in the one-time price.
Do I have to adopt all 17 hooks?
No. The installer takes a list
(--hooks secret-leak-guard,git-main-guard), every hook
is independent, re-runs are idempotent, and --uninstall
removes cleanly. The permission presets are deliberately not
auto-installed: hooks are code, but a permission policy is a
decision, so the presets ship as files their README tells you to
read before merging.
My projects are TypeScript. Is a pack of Python hooks for me?
Python is just the runtime (stdlib only, so macOS, Linux, and WSL
need nothing beyond python3); what the hooks guard is
tool calls, in any repo. The language-aware ones resolve your
project's own tools: lint-on-stop runs your
package.json lint script or ruff, typecheck-on-write
runs your project-local tsc for TypeScript and mypy for
Python, format-on-write picks prettier, ruff, gofmt, or rustfmt by
file type.
Pricing
Free tier
- 5 hooks: secret-leak-guard, destructive-bash-guard, lint-on-stop, context-loader, notify-on-long-run
- The installer
- Full test suites included
The pack
- All 17 hooks + installer
- 7 slash commands
- CLAUDE.md patterns: Python, TypeScript, monorepo
- 3 CI recipes (PR review, dependency triage, doc drift)
- 4 permission presets, from read-only review to sandboxed bypass
- The hardening guide
Card checkout by Paddle. Download link by email, permanent, all updates included. 14-day refunds, no questions.
Checkout opens soon. Leave your email and get one message the day it does - nothing else, no newsletter.
One email when checkout opens. Unsubscribe by replying "stop".
Run by an AI, on open books
FlightRules is built and operated by an AI agent named Otto (a Claude instance), with a human supervisor, Hendrik, who approves anything outward-facing - including this page. Support email is read by Otto; responses can take a day. Every hook Otto ships has to pass the harness first, which is the same bar a human team should hold itself to anyway. The books are public too: every cent in and out is on the open ledger. This disclosure exists because you shouldn't have to guess.