Claude Code Mastery Series (6/12): Production Codebase Safety
The fear most engineers have about agentic tools is not irrational. An agent that can read your filesystem and run shell commands can also delete a production database, leak a secret, or push a broken migration.
The good news: Claude Code is built around the assumption that you do not trust it. The safety architecture is the product, not an afterthought.
You do not trust the agent. You trust the gates the agent passes through.
1. The 3-Layer Safety Model
Every action a Claude Code agent takes passes through three layers before it touches your system.
Each layer is independent. If one fails, the next catches it.
Defense in depth is not paranoia. It is what makes autonomous execution acceptable in production.
2. The 7-Mode Permission System
Claude Code does not have one permission setting. It has seven modes, each tuned for a different risk profile.
# Run /permissions in any session to see them
> /permissions
# The seven modes (simplified)
1. Ask — agent asks before every tool call (slowest, safest)
2. Auto-allow read — reads pass, writes ask
3. Auto-allow safe — pre-approved bash commands run; rest asks
4. Project-scoped — agent can only touch the current directory tree
5. Read-only — no writes, no shell, only Read/Glob/Grep
6. Sandbox — runs in an isolated tmp directory, no host access
7. Trusted — full auto (use only on personal projects)
A typical production setup uses Mode 3 + project-scoped (option 4 layered on top): pre-approved commands run; everything else asks; nothing escapes the project root.
The right permission mode is the one your most cautious teammate would approve. Default to that.
3. CLAUDE.md as the Safety Contract
CLAUDE.md is not a style guide. It is the constitution of your codebase — and Claude Code reads it at every session start.
This is where you encode what the agent must never do, regardless of what you ask it.
# CLAUDE.md (excerpt)
## Banned patterns
- Never use `eval()` or `Function()` constructors
- Never write to `/etc/`, `/var/`, or `~/.ssh/`
- Never modify files in `migrations/applied/` (only add new files)
- Never run `git push --force` on `main` or `release/*` branches
## Frequent commands (auto-allowed)
- `npm test`, `npm run lint`, `npm run build`
- `git status`, `git diff`, `git add`, `git commit`
## Always require human approval
- Database migrations (anything in `migrations/`)
- Changes to `package.json` dependencies
- Files in `src/payments/` or `src/auth/`
The agent reads this on session start. Every tool call is checked against it. Forbidden actions are refused even if your prompt explicitly asks for them.
Your prompt is the request. CLAUDE.md is the law. The law wins.
4. What Never to Automate
Some operations should never run autonomously, no matter how good your guardrails are.
These belong in your deny-list at the permission layer and in the banned-patterns section of CLAUDE.md. Two layers, same rule.
The cost of a manual approval is seconds. The cost of an automated catastrophe is your job.
5. The Read-Only Audit Pattern
The safest way to introduce Claude Code into a sensitive codebase is to start it in read-only mode for the first week.
# Read-only audit — no risk, full insight
claude --permission-mode read-only
> Audit the auth module.
List every function, its callers, and any pattern inconsistencies.
Identify risks. Do not edit anything.
This pattern lets you build trust before you grant write access. The agent surfaces risks; you decide what to act on.
After a week of read-only runs, your team has seen what the agent does — and your CLAUDE.md is fully calibrated. Then you graduate to write modes.
Trust is not granted by default. It is earned through observable behavior.
The Full Series — Claude Code Mastery (12 Parts)
Follow me to get the next 6 articles in your feed.
What is your team’s “never automate” rule? Drop it in the comments — the best ones become my CLAUDE.md template for next week’s article.