Skip to main content
AI-Developer/AI Engineering
Part 1 of 16

Claude Code in Production: How Senior Engineers Actually Use It

Claude Code is powerful enough to change how you ship software, but only if you treat it like a production tool instead of a magic terminal. Here is the field guide: permissions, CLAUDE.md, hooks, failure modes, review habits, and the guardrails I use before letting it touch real systems.

May 14, 2026
17 min read
#Claude Code#AI Engineering#Production Engineering#Developer Tools#Agentic Engineering#Code Review#Automation

Claude Code is not interesting because it can write code.

It is interesting because it can sit inside a real repository, read the messy parts, run the same commands your team runs, fail, recover, and keep moving.

Primary Objective
Agentic Development | Production Guardrails | CLAUDE.md Mastery

Most Claude Code articles read like CLI documentation: install this, run that, try these commands. That is useful for the first hour. It is not enough for the first month.

The real question is not "Can Claude Code edit files?" The real question is: Can you put it inside a serious codebase without letting it create expensive, invisible damage?

My answer is yes, but only if you stop treating it like a clever autocomplete and start treating it like a junior engineer with root-level enthusiasm, uneven judgment, and unlimited stamina.

This is the production angle: what to allow, what to block, how to write CLAUDE.md, how to structure tasks, how to catch bad work, and what breaks when the demo becomes a real team workflow.


The Mental Model: Agent, Not Chatbot

Claude in the browser is a conversation. Claude Code is an agent with tools.

It can read files, search the repo, edit code, run shell commands, inspect failures, and continue iterating. That makes it useful for real engineering work:

  • Tracing a failing test across several modules.
  • Migrating one pattern across a codebase.
  • Writing missing tests against existing behavior.
  • Producing a plan before a risky refactor.
  • Doing boring cleanup work that senior engineers avoid until it becomes debt.

But there is a cost: once the model has tools, your prompt is no longer just text. It becomes operational intent.

🚫
Production Rule

Never ask Claude Code to "clean things up" in a repository you care about. Ask it to make a specific change, in a specific area, with a specific verification command.

Prompting for Safety

The Prompting Difference

BAD PROMPT (HAZARDOUS)

"Clean up the auth code and improve the tests."

PRODUCTION PROMPT (SECURE)

"In the auth module only, remove duplicated token parsing logic. Keep the public API unchanged. Add or update tests for expired tokens, malformed tokens, and missing headers. Run npm test -- auth before summarizing the diff. Do not edit database migrations or environment files."

That difference is not style. It is operational safety.


The First Production Scar: The .env Problem

Here is the kind of failure that changes how you configure Claude Code.

An engineer asks an agent to "make local setup easier." The agent sees .env.example, .env.local, Docker compose files, and a README. It decides the cleanest solution is to normalize environment variables. Helpful idea.

Then it reads or rewrites files it should never touch. Maybe it doesn't leak secrets anywhere. Maybe it only replaces local values with placeholders. Maybe it adds a new required variable and breaks every developer's machine the next morning.

The issue is not that the model is malicious. The issue is that secrets and local config look like normal project files unless you teach the tool otherwise.

I do not rely on CLAUDE.md for this. CLAUDE.md is guidance. Permissions are enforcement.

Recommended .claude/settings.json
{
  "permissions": {
    "deny": [
      "Read(**/.env)",
      "Read(**/.env.*)",
      "Edit(**/.env)",
      "Edit(**/.env.*)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)",
      "Read(~/.config/gcloud/**)"
    ],
    "allow": [
      "Bash(npm run test *)",
      "Bash(npm run lint)",
      "Bash(npm run build)",
      "Bash(git diff *)",
      "Bash(git status *)"
    ]
  }
}

Then reinforce the behavior in CLAUDE.md:

- Never read, print, modify, summarize, or copy .env files.
- Use .env.example when environment variable names are needed.
- Never change secrets, credentials, tokens, or local machine config.
- If a task appears to require secrets, stop and ask for a safer path.

Why both? Because they solve different problems. CLAUDE.md shapes what Claude attempts. settings.json controls what Claude Code is allowed to do.


Install It, But Do Not Stop There

The basic install is the easy part.

# macOS / Linux / WSL
curl -fsSL https://claude.ai/install.sh | bash

# verify
claude --version
claude doctor

Then open a repository and run:

claude
/init

/init gives you a starting CLAUDE.md. Treat it like a draft, not a contract. Your first serious session should not be "build a feature." It should be:

The Initial Bootstrapping Prompt

"Read this repository and propose a production-grade CLAUDE.md. Include only instructions that will affect future work: commands, architecture boundaries, testing expectations, naming conventions, deployment constraints, and files that must not be touched. Do not edit yet. Show me the proposed file first."


The CLAUDE.md I Want in a Real Repo

Most CLAUDE.md files become junk drawers. A useful CLAUDE.md tells the agent what a senior engineer would tell a new teammate on day one.

Production-Grade CLAUDE.md Template
# Project Operating Rules

## Commands
- Install: npm ci
- Typecheck: npm run typecheck
- Unit tests: npm test
- Focused test: npm test -- <path-or-pattern>
- Lint: npm run lint
- Production build: npm run build

## Architecture
- API routes live in src/app/api.
- Shared domain logic lives in src/domain.
- React components must not call database clients directly.
- Data access belongs in src/server/repositories.

## Change Boundaries
- Do not edit migrations unless the task explicitly asks for schema changes.
- Do not edit generated files.
- Do not edit .env files. Use .env.example for variable names.
- Do not change public API response shapes without calling it out.

## Verification
- For UI changes, run lint and typecheck.
- For server logic, run focused tests first, then the relevant package test.
- If a command fails because of missing local services, explain the blocker.

## Git
- Keep diffs small.
- Do not commit unless explicitly asked.
- Summaries must include files changed, tests run, and remaining risk.

Permission Modes Are Engineering Policy

Claude Code has permission modes and fine-grained rules. This is where teams either become productive or reckless.

Feature

(Note: Risks range from Low (plan) to Very High (bypass). Always prefer plan for discovery and default for daily work.)


The Second Production Scar: Infinite Test Loops

Claude Code can get stuck in a loop: Run test → See failure → Patch code → Run test again → Create a different failure.

💡
The Anti-Loop Prompt

"Fix only the failing tests in packages/billing. Start by running npm test -- packages/billing. Before editing, explain the likely root cause in 5 bullets or fewer. Stop after 3 failed test attempts and summarize what changed, what still fails, and what evidence you have."

That "stop after 3 attempts" line prevents the agent from turning a debugging task into a wandering refactor.


Hooks: Where Advice Becomes Enforcement

CLAUDE.md is not enough for rules that must always happen. Use hooks when you need deterministic behavior.

Permissions vs. Hooks

PERMISSIONS (STATIC)

Static allow/deny rules for files and commands (e.g., deny npm run deploy).

HOOKS (DYNAMIC)

Logic-based decisions (e.g., block edits to protected paths unless an override exists, or run a formatter after edits).

💡
Field Note

If a rule would wake you up during an incident, it should not live only in a prompt. Put it in permissions, hooks, CI, or branch protection.


The Review Loop: Trust But Verify

Claude Code should not be allowed to disappear into a repo and come back with a giant diff.

The Safe Review Cycle

📝
PLAN

Ask for a plan in plan mode. Challenge missing tests or risky dependencies.

✂️
SLICE

Let it implement only the first small slice of the change.

🔍
DIFF

Review the git diff yourself. Do not skip this step.

VERIFY

Make the agent run focused verification (tests/lint) on its own change.


Production Workflows That Actually Pay Off

1. Bug Investigation

Use Claude Code to trace across files, not to guess from a stack trace.

"Investigate this production error. Do not edit files yet. Find the request path, the likely failing module, and the smallest test that would reproduce it."

2. Test Coverage for Old Code

Claude is quietly excellent at backfilling tests.

"Find untested branches in src/domain/invoices. Do not change production code. Add tests that document current behavior, including edge cases."

3. Mechanical Refactors

Perfect for clear pattern migrations.

"Migrate only src/components/forms from the old Button import to the design-system Button. Do not change behavior or styling. Run typecheck."


Key Takeaways

01
01
Agent, Not Chatbot

Claude Code has root-level tools. Treat its prompts as operational intent, not just conversation.

01
01
Enforce with settings.json

Guidance goes in CLAUDE.md. Enforcement (denying .env access) belongs in permissions.

01
01
The Expert Multiplier

Claude Code rewards engineering judgment. The best users provide tight constraints and verify every diff.


💡
Series Finale

You've mastered the production guardrails. Now, take the final step: Building Custom MCP Servers to give Claude Code proprietary tool access.

AI Engineering
MH

Mohamed Hamed

20 years building production systems — the last several deep in AI integration, LLMs, and full-stack architecture. I write what I've actually built and broken. If this was useful, the next one goes to LinkedIn first.

Follow on LinkedIn →