Skip to main content
← All episodes

Episode 4

Guardrails

Clicking loads the video from YouTube (youtube-nocookie.com). Nothing is sent to YouTube before that. Privacy policy

In this episode (≈ 40 min of hands-on work)

  • You know which hooks really block and which only check.
  • Three task files that tell every session where you stand.
  • Your project, backed up in a private GitHub repo.

Your step

Paste this into Claude Code in your project folder. Claude checks the guardrails with you.

Check the guardrails in this project with me. I am not a developer, so explain everything in plain words.
1. Read .claude/settings.json (if it lists no hooks, also ~/.claude/settings.json) and tell me which hooks are registered and which of them really block. The table is in ~/ailoopwise-blueprint/course/04-guardrails.md.
2. Test one guard. If a .env already exists here, skip the test and tell me. Otherwise try to create a file .env containing TEST=1 and tell me the exact message you got. If the file got created anyway, say so plainly.
3. Compare tasks/current.md, tasks/lessons.md and tasks/todo.md with the filled examples in ~/ailoopwise-blueprint/course/examples/. Tell me what mine are missing, above all an "Exact Next Action" a fresh session could follow without asking me.
4. Check that .gitignore contains the lines .claude/settings.local.json, .mcp.json and .env. Show me what is missing and add it only after I say yes.
5. Change nothing outside this folder. Never show the contents of .env or .mcp.json. Never run git commit or git push unless I ask, and never print a password, key or token.

Files for this episode

Questions about this episode? Just email us: hello@ailoopwise.com

Step-by-step guide

What this episode is about

Once your project is set up with the blueprint, the AI works inside fixed guardrails. Scripts (hooks) run automatically at fixed points; the AI cannot skip them. Three text files keep the context small, so a fresh session knows where things stand within seconds. Finally you back everything up to a private GitHub repo.

The wall: writing the guardrails is the work nobody sees. For us it took months.

What you need
What the hooks actually do

The scripts live in blueprint/hooks/, registered in .claude/settings.json:

Script When What it does Effect
block-dangerous-commands.sh before every shell command stops rm -rf on root, home and project paths, git reset --hard, git clean -fd, force push, git checkout/git restore of files, DROP TABLE and friends, mass deletion via find, commands that could expose secrets (cat .env, printenv), npm/yarn/pnpm publish blocks, Claude sees why
protect-sensitive-files.sh before every write locks .env files (templates like .env.example allowed), lockfiles, .git/, node_modules/, .ssh/, .aws/, credentials, .pem, .key blocks
detect-secrets-in-code.sh before every write looks for AWS, GitHub, Stripe, Slack and sk- keys, private keys, database URLs with passwords (skips .md, templates, test fixtures) blocks
format-and-lint.sh after every JS/TS write eslint --fix if there is a package.json fixes silently
owasp-check.sh after every code write warns on SQL injection, innerHTML, eval, shell=True and similar warning only
audit-dependencies.sh after npm/pnpm/yarn/bun install runs the package manager's security audit warning only
quality-check.sh when Claude finishes typecheck, lint, format check and, if code changed, tests (JS/TS, Python, Go, Rust) blocks the stop once when types or tests fail; everything else is a warning only
session-start.sh at session start warns if jq is missing and points to tasks/current.md and tasks/lessons.md goes into context

Honestly: the three guards before the step really block, and quality-check.sh blocks the stop exactly once when the typecheck or the tests fail (Claude sees the reason and fixes it; the second attempt goes through so nothing hangs forever). The remaining checks exit with code 0, and per the hooks reference their output then goes to the debug log only: "Claude never sees it." That Claude tests after every task and fixes its own errors comes from the "Mandatory Quality Checks" rule in your CLAUDE.md. That is context, not a lock. The docs put it this way: Claude treats CLAUDE.md "as context, not enforced configuration" (source). So ask which check actually ran.

Step by step
  1. Open your project and type /hooks. You see the entries under PreToolUse, PostToolUse, Stop and SessionStart with the source Project Settings.
  2. Trigger a guard on purpose:
    Create a file .env in the project folder containing TEST=1.
    
    Expected: Claude reports BLOCKED: Protected file pattern and creates nothing. If a .env shows up anyway, the guard isn't running: see "If something goes wrong". Delete the file yourself.
  3. Start every session with the line from blueprint/MASTER-BLUEPRINT.md:
    Read tasks/current.md and tasks/lessons.md. Summarize where we left off.
    
    current.md is where things stand, lessons.md the mistakes already made, todo.md what's next.
  4. End every task with:
    Which checks (typecheck, lint, tests, build) did you just run? Give the command and the result. Say explicitly what did not run.
    
  5. Create a private repo at https://github.com/new, without README, licence or .gitignore.
  6. Add a .gitignore to the project. The first three lines come from /new-project; .env is added:
    .claude/settings.local.json
    .mcp.json
    tasks/current.md
    .env
    
    To back up your working state too, remove the tasks/current.md line. .mcp.json and .env stay out; tokens live there.
  7. In the project terminal (Ctrl+` in VS Code):
    git init -b main
    git add .
    git commit -m "First setup"
    git remote add origin <YOUR-REPO-URL>
    git push -u origin main
    
Example to copy

Filled task files for the newsletter example: examples/current.md · examples/lessons.md · examples/todo.md. The key section is "Exact Next Action" in current.md:

## Exact Next Action
Create src/routes/unsubscribe.ts with GET /unsubscribe?token=... . Verify the token with
verifyToken from src/lib/tokens.ts; on success set the subscriber's status to "unsubscribed"
[...] Done when npm test passes.
Before the next episode

Open your repo on github.com and check: it is private, and .mcp.json and .env are not in it.

If something goes wrong

Free by email

New guides by email, plus the complete Blueprint package

With every new video you get the full guide with the ready-to-paste AI brief. Once you confirm your address, the complete Blueprint package is the first thing we send you.

Free. Unsubscribe any time.

Episode 4: Guardrails | Claude Code course by AILoopwise