Where each Claude Code instruction belongs
CLAUDE.md can't enforce never. Hooks, skills, rules and subagents can, and here is when to use each.
Published · 4 sources · Resume reading
Your CLAUDE.md says "never do X", and Claude can still do X. CLAUDE.md is guidance; hooks are enforced. Here's where each kind of instruction belongs, per the Claude Code docs.
Keep CLAUDE.md to facts
Put the facts Claude needs in every session in CLAUDE.md: build commands, conventions, project layout. The docs say to target under 200 lines, because longer files use more context and reduce how well Claude follows them [1]. Everything below moves out of it.
# my-app
- Build: npm run build
- Test: npm test
- API code lives in src/api, UI in src/uiBlock a never with a PreToolUse hook
A hook runs your script before a tool call. If the script exits with code 2, the call is blocked and whatever it wrote to stderr goes back to Claude as the reason [2]. Add this to .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
}
]
}
]
}
}Then the script, at .claude/hooks/protect-files.sh. Change the pattern to whatever must never be edited:
#!/bin/bash
file=$(jq -r '.tool_input.file_path // empty')
case "$file" in
*.env|*.env.*|*package-lock.json)
echo "Blocked: $file is protected" >&2
exit 2
;;
esac
exit 0chmod +x .claude/hooks/protect-files.shThe script needs jq (brew install jq on macOS). You should see Claude report "Blocked" when it tries to edit a protected file.
Run an always with a PostToolUse hook
For "always do Y after edits", run it after the tool instead of asking for it. This formats every file Claude edits, from the docs' own example [2]:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}You should see edited files come back formatted without asking.
Turn a procedure into a skill
A 30 line procedure doesn't belong in every session's context. Put it in a skill, which Claude loads only when it's needed [3]. The folder name becomes the command:
---
description: Release checklist. Use when the user asks to cut or publish a release.
---
1. Run npm test and stop if anything fails.
2. Bump the version in package.json.
3. Update CHANGELOG.md with the merged pull requests.
4. Tag the commit and push the tag.Save it as .claude/skills/release/SKILL.md. The --- must be the file's first line, or Claude Code won't read the frontmatter [3]. You should see /release when you type /.
Scope a rule to one folder
A rule that only matters in one part of the repo goes in .claude/rules/ with a paths list, so it only loads when Claude works on matching files [1]:
---
paths:
- "src/api/**/*.ts"
---
# API rules
- Every endpoint validates its input.
- Use the standard error response format.Save it as .claude/rules/api.md. Rules without paths load at the start of every session [1].
Hand deep work to a subagent
Long searches and log analysis fill the main context with noise. A subagent does the work in its own context window and returns only the result [4]. Save this as .claude/agents/log-reader.md:
---
name: log-reader
description: Reads long logs and test output and reports only the errors and their likely cause.
tools: Read, Grep, Glob
---
Read the logs you are pointed at. Report each distinct error once, with the file and line,
and one sentence on the likely cause. Do not paste whole logs back.Only name and description are required [4]. You should see Claude hand log questions to log-reader and get a short summary back.
Your CLAUDE.md is now short, the nevers are enforced by a hook, and everything else loads only when it's needed.
Keep this guide
Filed under Claude Code
Questions about this guide
How long should CLAUDE.md be?
The Claude Code docs say to target under 200 lines per file. Longer files use more context and Claude follows them less reliably.
Sources
- Claude Code docs: memory and CLAUDE.mdcode.claude.com
- Claude Code docs: hooks guidecode.claude.com
- Claude Code docs: skillscode.claude.com
- Claude Code docs: subagentscode.claude.com