CLAUDE.md
Confirmed in official docsPlain languageThink 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.
TechnicalA 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 docsPlain languageTelling 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.
TechnicalInstructions (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 docsPlain languageThere 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.
TechnicalPreToolUse 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 docsPlain languageDifferent 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.
TechnicalAlways-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 docsPlain languageA 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.
TechnicalA 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.