FlightRules

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.

Illustration: a small aircraft on a runway during pre-flight checks, control tower behind, a checklist with green ticks in the foreground

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

HookDoes
Guards - stop the accident before it happens
secret-leak-guardBlocks reading .env, key files, and credential stores into context
destructive-bash-guardBlocks rm -rf on dangerous paths, force pushes, mkfs, fork bombs; nine named patterns, each overridable
env-file-write-guardBlocks writes to .env and credential files
git-main-guardKeeps commits and pushes off main/master unless you say so
outbound-network-guardAsks before curl/wget sends data to hosts you didn't allowlist
dependency-change-alertFlags lockfile and manifest edits so they never slip through unnoticed
Quality - close the loop before the session ends
lint-on-stopRuns your linter when Claude tries to finish; failures fed back for self-correction
test-on-stopRuns your test suite before the session ends
format-on-writeAuto-formats every file the moment it's written
typecheck-on-writeRuns tsc/mypy after edits, failures fed straight back
todo-scan-on-stopFlags leftover TODOs and debug prints in added lines
Workflow - context, hygiene, records
context-loaderInjects branch, recent commits, dirty-file count at session start
pr-checklist-on-stopPuts your PR checklist in front of Claude before it finishes, once
commit-message-lintDenies non-conforming commit subjects (conventional commits by default)
notify-on-long-runDesktop alerts when a long run needs attention
transcript-archiverGzips every session transcript with a CSV index
cost-loggerPer-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:

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

$0 MIT license
  • 5 hooks: secret-leak-guard, destructive-bash-guard, lint-on-stop, context-loader, notify-on-long-run
  • The installer
  • Full test suites included
github.com/flightrules/flightrules

The pack

$29 one-time, all updates included
  • 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

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

Illustration: a small robot at a desk, writing in an open ledger

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.