Module 1

Claude Code Configuration

Match the mechanism to the requirement: instructions influence, hooks guarantee, and every kind of knowledge has a natural home.

CLAUDE.md

Confirmed in official docs
Plain language

Think of CLAUDE.md as standing instructions Claude reads before every task in a project. Because it's always loaded, it's the right place for durable, project-wide conventions — but every line in it costs a little bit of the model's attention budget on every single session, so it shouldn't be stuffed with things that only apply occasionally.

Technical

A CLAUDE.md file is loaded automatically into context whenever Claude Code works in that project or directory. It's the always-on layer of configuration: appropriate for durable, project-wide conventions, not occasional or directory-specific rules (which belong in nested CLAUDE.md files, slash commands, or skills instead).

Why it matters

Always-loaded context is expensive in aggregate — reserving CLAUDE.md for genuinely durable, universally-relevant rules keeps sessions fast and keeps the model from having to sift through irrelevant guidance.

Instructions influence; hooks guarantee

Confirmed in official docs
Plain language

Telling the model 'always do X' in a prompt or CLAUDE.md makes X more likely, but the model can still slip — it's a probabilistic system, not a light switch. A hook is real code that Claude Code runs automatically at a specific moment, so it happens every single time, with no chance of the model 'forgetting.' If something absolutely must never (or always) happen, don't write a stronger sentence — write a hook.

Technical

Instructions (system prompt, CLAUDE.md, inline emphasis like 'IMPORTANT'/'MUST') are advisory: they shift probability but never reach 100%. A hook is deterministic code Claude Code executes at a defined lifecycle point (before/after a tool call, or at Stop), independent of model judgment. Emphatic wording is not a substitute for a hook when the requirement is a hard guarantee.

Why it matters

This is called out as the single most important idea in the whole guide: guarantees have to live outside the model, in code, because the model itself is probabilistic and can't offer a 100% guarantee no matter how it's prompted.

The hook family (PreToolUse, PostToolUse, Stop, permissions)

Confirmed in official docs
Plain language

There are a few different checkpoints where a hook can run. A PreToolUse hook is like a guard checking IDs before someone walks through a door — it runs before a tool call and can block it outright (e.g., 'never let Claude edit the migrations folder'). A PostToolUse hook runs right after a tool call, like a cleanup crew (e.g., 'auto-format every file that was just edited'). A Stop hook runs when the agent thinks it's done, as a final check. permissions.deny rules are the bluntest tool of all — they just forbid an action outright, no code required.

Technical

PreToolUse hooks run before a tool call and can block/modify it. PostToolUse hooks run after a tool call completes (e.g., invoking a formatter). Stop hooks fire when the agent attempts to end its turn. permissions.deny entries in settings are a declarative allow/deny list, the simplest and bluntest guarantee mechanism, requiring no custom hook code.

Why it matters

Different points in the lifecycle call for different hooks — matching hook type to the moment you need to intervene (before an action, after an action, at completion) is itself part of the judgment being tested.

Where each kind of knowledge belongs

Confirmed in official docs
Plain language

Different kinds of guidance have a natural home. Something everyone on the team should always see → a shared project file. Something only you use → a file in your own home directory. Something Claude should always know → CLAUDE.md. Something you only need occasionally → a slash command or a skill, invoked on demand. A couple of concrete example files for a one-off task → just reference them directly in your prompt instead of writing them into permanent config.

Technical

Always-on convention → CLAUDE.md. Directory-specific rules → a CLAUDE.md nested inside that subdirectory (loads only when working there). Occasional, invokable workflow → a /slash-command or a project skill at .claude/skills/<name>/SKILL.md. Concrete exemplar files for a one-off task → @file references in the prompt, not permanent config. Shared vs. personal MCP servers → project .mcp.json (checked into version control, team-wide) vs. ~/.claude.json (personal, machine-local).

Why it matters

Putting knowledge in the wrong home either leaks it to people who shouldn't see it (private experiment in a shared file), hides it from people who need it (shared tool in a private file), or silently taxes every session with irrelevant context (a one-off pattern baked into CLAUDE.md forever).

Slash commands vs. skills vs. subagents

Confirmed in official docs
Plain language

A slash command is a saved snippet of instructions you can pull up on demand, like a reusable checklist. A skill is a more substantial, self-contained workflow file that the whole team shares and improves over time via version control. A subagent is a completely separate assistant with its own clean memory — reach for one when a task is big enough to deserve its own isolated workspace, not just to hold a checklist.

Technical

A slash command injects a saved instruction block on invocation — lightweight, prompt-shaped. A skill is a version-controlled, team-shared workflow file (SKILL.md) with more structure, meant to evolve over time. A subagent (Agent/Task tool) is a separate assistant instance with an independent context window — appropriate for isolation and delegation, not merely for storing reusable text.

Why it matters

Reaching for a subagent when a slash command would do adds unnecessary overhead (spinning up a whole isolated context for a simple checklist); reaching for a slash command when a skill is warranted means the workflow won't be versioned or easily co-maintained by a team.

Verification note — The guide frames slash commands as simple 'saved snippets' — in practice a slash command can carry a full, structured workflow definition, not just a short checklist, so the size distinction from skills is softer than the guide implies.

Worked examples for this module

See all 58 →

Situation

A shared venue-lookup MCP server should be available to the whole team; a personal experimental playlist server should be visible only to you.

Recommended approach

Put the shared venue server in the project-level .mcp.json, and the personal playlist server in your own ~/.claude.json.

Why it works

Project-level .mcp.json lives in the repository and is shared with everyone who checks it out, so the team-wide server belongs there. ~/.claude.json lives in your home directory and is private to you, so the experimental server belongs there. Each server ends up matching who should actually see it.

Weaker approaches people try — and why they fall short

  • Put both servers in your local ~/.claude.json.Teammates never receive the shared venue server.
  • Put the venue server in ~/.claude.json and the playlist server in .mcp.json.This is backwards: the private experiment becomes team-visible, and the shared tool becomes invisible to everyone else.
  • Put both servers in the project-level .mcp.json.Your private experiment gets exposed to the whole team.
Takeaway — Shared config → project file (.mcp.json). Personal config → home file (~/.claude.json). Match scope to audience.

Plain-language notes on the technical terms above

.mcp.json
The shared, project-level file listing MCP servers everyone on the team gets.
~/.claude.json
Your own personal, private configuration file — not shared with the team.
MCP (Model Context Protocol)
A standard way to connect outside systems and data to an AI agent.
#2

Deterministic Enforcement vs. Instructions

Situation

CLAUDE.md says 'use 4-space indent and run Prettier,' but about 30% of generated files are still mis-formatted. Adding IMPORTANT/MUST language only cuts that to about 15%.

Recommended approach

Add a PostToolUse hook (matching Edit/Write) that automatically runs Prettier on every file Claude modifies.

Why it works

Formatting is a mechanical, deterministic task. A PostToolUse hook runs real code every time a file is edited or written, so formatting is applied 100% of the time regardless of what the model remembered. Deterministic problems deserve deterministic tools, not stronger wording.

Weaker approaches people try — and why they fall short

  • A Stop hook with a prompt-based check asking Claude to fix violations.Still relies on the model's judgment to detect and fix issues — probabilistic, so violations slip through.
  • Split rules into path-scoped rule files.Still instructions the model may or may not follow; organizes guidance without enforcing it.
  • Extract the rules into a dedicated file with more examples.More examples and emphasis is the same probabilistic approach that already plateaued around 15% failure.
Takeaway — If a rule must hold 100% of the time, enforce it with a hook, not with instructions. Instructions influence; hooks guarantee.

Plain-language notes on the technical terms above

Hook
A piece of real code that runs automatically at a specific moment, guaranteed — unlike an instruction, it can't be skipped or forgotten.
PostToolUse hook
A checkpoint that runs right after Claude uses a tool, e.g. to automatically clean up or format whatever just changed.
CLAUDE.md
A file that Claude automatically reads before every task in a project — like a standing set of house rules.

Situation

A new payment module should mirror patterns already used in three existing files. It's a one-off task, and the patterns are already clear in the code itself.

Recommended approach

Use @ references to pull the three existing modules directly into the prompt.

Why it works

@file references bring the exact code into context, so Claude sees the real patterns rather than a paraphrase of them. Because this is a one-off, there's no reason to pay the ongoing cost of documenting it project-wide — concrete, immediate examples are enough.

Weaker approaches people try — and why they fall short

  • Ask Claude to explore the codebase to find the patterns first.Costs time and tokens and risks finding the wrong files, when the right files are already known.
  • Add each pattern to CLAUDE.md as a project convention.CLAUDE.md loads into every session forever — overkill for a one-off, and it bloats context permanently.
  • Describe the patterns in natural language in the prompt.Lossy — re-describing code in prose when Claude could just read the real thing directly.
Takeaway — When you already know the exemplar files, @-reference them directly. Reserve CLAUDE.md for durable, project-wide conventions.

Plain-language notes on the technical terms above

CLAUDE.md
A file that Claude automatically reads before every task in a project — like a standing set of house rules.
#7

Right Mechanism for Each Requirement Type

Situation

CLAUDE.md contains three rules: never edit the migrations folder, prefer a custom logger over console.log, and always Prettier-format TypeScript after edits. Claude edited a migration file anyway.

Recommended approach

Use permissions.deny for the migrations folder, keep the logging preference as a CLAUDE.md instruction, and use a PostToolUse hook for Prettier — a different mechanism for each requirement type.

Why it works

Each requirement has a different nature. A hard prohibition needs a permissions.deny rule that physically blocks the action. A soft preference is genuinely advisory and belongs in CLAUDE.md. A mechanical guarantee belongs in a PostToolUse hook. Matching mechanism to requirement type is the core skill being tested here.

Weaker approaches people try — and why they fall short

  • Rewrite all three rules in CLAUDE.md with stronger language and examples.Stronger wording is still probabilistic — it can't guarantee migration files are never touched.
  • Use hooks for all three rules.Using a hook for the soft logging preference is over-engineering; a preference doesn't need a code gate.
  • Move all three into path-scoped rule files.Still model-followed guidance, so the absolute prohibition still wouldn't be guaranteed.
Takeaway — Absolute block → permissions.deny. Soft preference → CLAUDE.md. Mechanical guarantee → hook. Don't use one tool for all three.

Plain-language notes on the technical terms above

permissions.deny
A settings list that just outright forbids certain actions, no custom code needed.
CLAUDE.md
A file that Claude automatically reads before every task in a project — like a standing set of house rules.
PostToolUse hook
A checkpoint that runs right after Claude uses a tool, e.g. to automatically clean up or format whatever just changed.
#11

Slash Command for a Reusable Workflow Snippet

Situation

A team wants Claude to follow an 8-item code-review checklist for pull requests, but also uses Claude heavily for features, debugging, and docs. Right now devs paste the checklist in by hand every time.

Recommended approach

Create a /review slash command that contains the checklist.

Why it works

The checklist is only needed sometimes (during reviews), and the same Claude session is used for many other kinds of work. A slash command injects the checklist on demand, exactly when needed, without burdening every other session — replacing the copy-paste ritual cleanly.

Weaker approaches people try — and why they fall short

  • Create a dedicated review subagent with the checklist embedded.A subagent is heavier than needed; the task is 'apply this checklist,' not 'run an isolated specialist with its own context.'
  • Make plan mode the default for reviews.Plan mode isn't a checklist mechanism and doesn't carry the 8 items.
  • Add the checklist to CLAUDE.md under a Code Review heading.CLAUDE.md loads into every session — the checklist would pollute feature, debugging, and docs work where it's irrelevant.
Takeaway — On-demand, occasional guidance → slash command. Always-on conventions → CLAUDE.md. Isolated specialist work → subagent.

Plain-language notes on the technical terms above

Slash command
A saved chunk of instructions you can pull up on demand by typing /something, instead of retyping or pasting it every time.
CLAUDE.md
A file that Claude automatically reads before every task in a project — like a standing set of house rules.
Subagent
A separate assistant with its own clean memory, used when a task is big or messy enough to deserve its own isolated workspace.
#12

Project Skills Live in .claude/skills/ (Version-Controlled)

Situation

A team migrates React components to Vue often, has a step-by-step workflow for it, wants everyone to be able to invoke /migrate-component, and wants that workflow to stay in sync as it evolves.

Recommended approach

Put a SKILL.md at .claude/skills/migrate-component/SKILL.md, committed to version control.

Why it works

A team-shared, evolving workflow belongs in a project skill that's committed to version control. Everyone gets it automatically, it's invokable, and Git keeps it in sync as the team iterates — one source of truth.

Weaker approaches people try — and why they fall short

  • A big instruction block in the root CLAUDE.md.CLAUDE.md always-loads and isn't the right home for an invokable, self-contained workflow.
  • A copy of the skill file under each person's home directory.The home directory is per-machine and private — it wouldn't be shared or stay in sync across the team.
  • An override entry inline in settings.json.There's no proper mechanism for this — skills live in SKILL.md files, not inline in settings.
Takeaway — Shared, evolving, invokable workflow → a committed project skill in .claude/skills/. Version control keeps everyone in sync.

Plain-language notes on the technical terms above

Skill
A more substantial, shared workflow file the whole team can use and improve together, saved to the project so everyone gets it.
#14

Subdirectory CLAUDE.md for Directory-Specific Guidance

Situation

An infrastructure-as-code repo has separate Terraform, Kubernetes, and pipelines directories. The root CLAUDE.md is 500+ lines, and Terraform rules load even when editing Kubernetes files, wasting context.

Recommended approach

Split the guidance into subdirectory CLAUDE.md files — one inside the Terraform folder, one inside the Kubernetes folder, and so on.

Why it works

Claude Code loads a directory's CLAUDE.md based on where you're actually working. Splitting guidance this way means only the relevant directory's rules load into context — Terraform guidance stays out of the way when you're editing Kubernetes. This is the built-in, token-efficient pattern.

Weaker approaches people try — and why they fall short

  • Files in a rules directory with path-scoping metadata.Plausible, but the established, built-in mechanism for locality is nested CLAUDE.md files, not a custom rules-frontmatter pattern.
  • Reorganize the root CLAUDE.md into labeled sections with headers.Headers improve readability but everything still loads — no token savings.
  • Keep the root CLAUDE.md and use an import mechanism for tool-specific files.An import still pulls the imported content into the same always-loaded root context.
Takeaway — Put directory-specific rules in that directory's own CLAUDE.md so only relevant guidance loads where you're actually working.

Plain-language notes on the technical terms above

CLAUDE.md
A file that Claude automatically reads before every task in a project — like a standing set of house rules.

Situation

A compliance rule requires that refunds over $500 always auto-escalate to a human rather than being left to model discretion. Despite clear prompt instructions, about 3% of high-value refunds are still being processed directly.

Recommended approach

Add a hook that intercepts the refund tool call: if the amount exceeds $500, block it and invoke human escalation instead.

Why it works

A hard compliance rule needs a deterministic gate. A hook intercepting the tool call and blocking any refund over the threshold enforces the rule 100% of the time, independent of the model's judgment — compliance guarantees belong in code, not in prompt wording.

Weaker approaches people try — and why they fall short

  • Add few-shot examples showing escalation at amounts just below, at, and above the threshold.Examples reduce the failure rate but never eliminate it entirely — still probabilistic.
  • Use even stronger, more emphatic system-prompt language.The same probabilistic approach that already failed to reach 100%, just phrased more forcefully.
  • Modify the refund tool itself to return an error above the threshold, asking the agent to escalate.Closer, but the agent could still choose not to call the tool at all or mishandle the resulting error — a hook intercepts the action itself for a firmer guarantee.
Takeaway — Non-negotiable compliance rules need a hook (a deterministic block), never just prompt emphasis.

Plain-language notes on the technical terms above

Hook
A piece of real code that runs automatically at a specific moment, guaranteed — unlike an instruction, it can't be skipped or forgotten.
PreToolUse hook
A checkpoint that runs right before Claude uses a tool, able to block that action entirely.