learnaiwithrafa
ClaudeWorkflows

Stop Stuffing CLAUDE.md: The 7 Controls Claude Code Gives You

Anthropic's own engineering post admits a prompted "never do this" can fail under pressure. Here's my map of the seven ways to steer Claude Code — when each one enters the context, how hard it's enforced, and the rule I use to decide where an instruction belongs.

3 min read1 source
  • #claude-code
  • #hooks
  • #skills
  • #subagents
  • #context-engineering

The most useful line in Anthropic's post on steering Claude Code is not a feature — it's a confession. A "never do this" written in your CLAUDE.md is not a guardrail: in a long session or an ambiguous situation, the model can drift right past a prompted rule. If an instruction absolutely must hold, it has to be code that runs, not prose the model reads. That one idea reorganizes how you use all seven controls.

The mental model I took from the post: every control differs on two axes — when it enters the context window and how strictly it's enforced. Pick the control by those axes, not by habit.

The 7 controls, on those two axes

  • CLAUDE.md — enters at session start, every line, every session, relevant or not. Anthropic's guidance: keep it under 200 lines. Best for what's always true — stack, build commands, conventions. Worst place for procedures and hard constraints.
  • Rules (.claude/rules/*.md) — constraints that can be path-scoped with paths: frontmatter (say, src/api/**), so they enter the context only when Claude touches matching files. Best for "in this corner of the codebase, always X" without taxing every session.
  • Skills (.claude/skills/<name>/SKILL.md) — only the name and a short description load up front; the full playbook enters when invoked. Best for repeatable procedures: release checklists, review passes. If your CLAUDE.md contains step-by-step logic, that's a skill living in the wrong file.
  • Subagents (.claude/agents/*.md) — run in an isolated context window and return only the final answer; they can nest up to five levels deep. Best for messy side investigations (log digging, dependency audits) whose intermediate noise you never want in your main thread.
  • Hooks (settings.json) — real commands that fire deterministically on lifecycle events. A PreToolUse hook that exits with code 2 blocks the tool call, full stop. This is the only item on the list that is enforcement rather than persuasion.
  • Output styles (.claude/output-styles/*.md) — injected into the system prompt itself, so they carry the highest adherence of any prompt-level control. The trap: a custom style replaces Claude Code's default coding instructions unless you set keep-coding-instructions: true.
  • --append-system-prompt — session-only additions on top of the default role. Handy for one-offs, but Anthropic flags diminishing returns: the more you stack here, the weaker each instruction gets.

The EM angle

On a team, this is an onboarding and risk question, not a personal-productivity trick. A repo where hard constraints live in hooks, procedures live in skills, and CLAUDE.md stays a lean map is a repo where the new hire's agent behaves like the senior's agent on day one. And in interviews with international companies, explaining why a rule belongs in a hook instead of a prompt is exactly the kind of judgment that reads as senior.

Today: open your CLAUDE.md and audit it line by line. Anything phrased as "never" or "always" that would actually hurt if ignored → move it to a PreToolUse hook. Any step-by-step procedure → extract it into a skill. What remains should fit comfortably under 200 lines.

Sources