Chapter 07

Claude-Specific Practices

Most of this book assumes the project is yours to set up from the start: the CLAUDE.md written before the first feature, the tests built alongside the first services, the conventions agreed while the team is still small. Most real projects are not like that. They were running before you arrived, with no CLAUDE.md, partial tests, and a deploy half in someone’s shell history, and the discipline has to be retrofitted around a system that is already shipping. The direction does not change between the two; the pace and the chunk size do. In a new codebase you put the conditions in place before drift starts. In an existing one you bring them in gradually, starting with the surfaces that change most and the paths that carry the most risk. The same gradualism keeps a rewrite survivable when cheaper construction makes one tempting, because the migration and the organizational patience a rewrite needs did not get cheaper just because the typing did.

The rest of this chapter is the concrete layer: the exact files and keys Claude Code reads as of this writing. Expect them to move. The categories from the last chapter are the part that lasts.


CLAUDE.md

The constitution loads at the start of every session. It can live at the project root, in .claude/CLAUDE.md, in your user file at ~/.claude/CLAUDE.md, or in a gitignored CLAUDE.local.md; the discovered files stack together. Pull other files in with an @path reference, and keep each file small.

# CLAUDE.md
Stack: Flask, Jinja, Pico.css. No build step.
See @docs/architecture.md for the layer model.

- Run tests with `pytest`.
- Never add a fallback for a required env var; fail at boot.

Path-scoped rules

Files in .claude/rules/ carry a paths: frontmatter and load only when the agent reads a matching file, so instructions that apply to one part of the tree do not sit in context the rest of the time. A rule with no paths: loads every session.

---
paths:
  - "app/templates/chapters/**"
---
# Writing the prose
First person, plain declaratives, no em-dashes.

settings.json

Technical configuration resolves across scopes, with the higher scope winning. It holds permissions, hooks, environment variables, and the default model.

Scope File Applies to
Managed A system file an org deploys Everyone; cannot be overridden
Project .claude/settings.json The team, checked into git
Local .claude/settings.local.json You, on this project, gitignored
User ~/.claude/settings.json You, across every project

Command-line flags override the lot for a single session.

Permissions

Permission rules decide what runs without asking. They are tiered: deny is checked first and blocks the call, ask prompts you, and allow approves automatically. Scope a rule to a whole tool or to a pattern within it.

{
  "permissions": {
    "deny":  ["Read(.env)", "Bash(rm -rf *)"],
    "ask":   ["Bash(git push *)"],
    "allow": ["Bash(pytest *)", "Read(./docs/**)"]
  }
}

Hooks

A hook ties a command to a point in the session’s lifecycle. The events you reach for most are these.

Event Fires
SessionStart When a session begins (load context, set state)
UserPromptSubmit When you submit a prompt, before the agent reads it
PreToolUse Before a tool runs; can block it
PostToolUse After a tool runs (lint, log, inject context)
Stop When the agent finishes a turn
PreCompact Before the context window is compacted
{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash",
        "hooks": [{ "type": "command", "command": ".claude/hooks/guard.sh" }] }
    ]
  }
}

Subagents

A subagent is a Markdown file in .claude/agents/ for the team, or ~/.claude/agents/ for you. The frontmatter names it, describes when to use it, lists the tools it may use, and can pin a model. The body is its system prompt.

---
name: security-reviewer
description: Review a diff the way a security engineer would.
tools: Read, Grep, Bash
model: sonnet
---
Read the diff. Flag injection, leaked secrets, and unsafe defaults.
Report findings; do not change code.

Skills

A skill is a folder under .claude/skills/<name>/ with a SKILL.md inside. Its frontmatter description tells the agent when the skill applies, and you can invoke it directly with /<name>. The body and any bundled files load only when the skill is used.

Slash commands

A Markdown file in .claude/commands/ becomes a /<name> command, which is handy for a prompt you run often. Skills cover the same ground with bundled files and the option for the agent to invoke them on its own.

MCP servers

External systems connect as tools through .mcp.json at the project root, shared with the team, or through your user configuration for personal servers. Each entry names a server, a transport (a local stdio command, or a remote http or sse URL), and any environment it needs.

{
  "mcpServers": {
    "playwright": { "command": "npx", "args": ["-y", "@playwright/mcp@latest"] }
  }
}

Plan mode and the permission modes

Plan mode is one of several permission modes, which run from prompting before every action to working unattended. Enter it for a single session or set it as the default. When a step goes wrong, the tool can rewind a session’s file changes to an earlier point.

Pin what you rely on

These paths and keys are current as of this writing and will move. Pin the model and the tool version you depend on, write the rules you care about where they will load, and treat the specifics here as a snapshot. The categories from the last chapter are what stays true.