CLAUDE.md File Hierarchy
| Level | Location | Scope |
|---|
| User | ~/.claude/CLAUDE.md | All projects for this user |
| Project | ./CLAUDE.md or .claude/CLAUDE.md | This project only |
| Directory | src/CLAUDE.md, tests/CLAUDE.md | This directory and below |
Key rule: Put coding standards, project structure, and key conventions in project-level CLAUDE.md. Keep it focused — Claude reads it every session.
Hooks Lifecycle
| Hook | Timing | Can Block? | Use Case |
|---|
| PreToolUse | Before tool executes | Yes (exit 2) | Validate inputs, enforce policies |
| PostToolUse | After tool completes | No | Logging, notifications, cleanup |
| Notification | On status changes | No | External alerts, progress tracking |
Hooks receive TOOL_NAME and TOOL_INPUT as environment variables. PostToolUse also receives TOOL_OUTPUT.
Permission Model
| Setting | Effect |
|---|
| allowedTools | Whitelist — tools here run without approval |
| deniedTools | Blacklist — tools here are blocked completely |
| Default (neither) | Claude asks for user approval each time |
Security rule: User-level denied tools cannot be overridden by project-level settings. This prevents malicious repos from escalating permissions.
Custom Slash Commands
Create .claude/commands/my-command.md with a prompt template. The filename becomes the command name. Use $ARGUMENTS placeholder for user input.
CI/CD Integration
| Flag | Purpose |
|---|
| --print | Non-interactive single-shot mode |
| --dangerously-skip-permissions | Auto-approve all tool use (CI only) |
| --model | Override default model |
| --output-format json | Machine-readable output |
| Anti-Pattern | Why It Fails |
|---|
| Skip permissions in production | Security risk — tools can modify files, run code |
| No timeout on CI runs | Claude may loop indefinitely, blocking pipeline |
| Missing CLAUDE.md in CI | Claude lacks project context, produces poor results |