Shareuhack | CLAUDE.md Complete Guide for Claude Code: How to Make AI Actually Follow Your Rules (2026)
CLAUDE.md Complete Guide for Claude Code: How to Make AI Actually Follow Your Rules (2026)

CLAUDE.md Complete Guide for Claude Code: How to Make AI Actually Follow Your Rules (2026)

March 27, 2026
LunaMiaEno
Written byLuna·Researched byMia·Reviewed byEno·Continuously Updated

CLAUDE.md Complete Guide for Claude Code: How to Make AI Actually Follow Your Rules (2026)

Boris Cherny, the author of Claude Code, once said in a tweet that went viral (8M views) that his own CLAUDE.md setup is "surprisingly vanilla."

That made me think. Here at Shareuhack, we run a content system powered by 8 autonomous agents, with a CLAUDE.md over 300 lines, dedicated skills directories, and per-agent operational memory. Is that complexity actually worth it for the average developer? And for those who keep adding rules to CLAUDE.md but still find Claude ignoring them — what's actually going wrong?

The answer in this article surprises most people: instructions being ignored isn't a bug, it's a design you need to understand. Once you grasp the mechanism, you'll realize most people are solving the wrong problem.

Timeliness note: This article is based on Claude Code documentation and community practices as of March 2026. Claude Code updates frequently — specific APIs, hooks syntax, and configuration structures may change with new versions. Use alongside the Anthropic official docs.

TL;DR

  • CLAUDE.md is "guidance" not "commands" — it's delivered at the user message layer, Claude actively judges relevance, it's not 100% enforced
  • Good CLAUDE.md means subtraction. arxiv 2602.11988 studied context files for coding agents: LLM auto-generated context files underperformed baseline in 5/8 scenarios; even developer-written versions had limited benefit at +19% inference cost. Core conclusion: writing it badly is worse than not writing it at all
  • settings.json protects the system, CLAUDE.md educates Claude, hooks enforce — each has a distinct role

"Instructions Ignored" Isn't a Bug: The Delivery Mechanism You Need to Know

Here's the most common misconception.

CLAUDE.md content is delivered to Claude as a "user message after the system prompt" — not as a system-level forced configuration. That means Claude actively judges whether the CLAUDE.md content is relevant to the current task, and may skip it if it judges otherwise. GitHub issue #18660 makes this explicit in community discussion: "Claude acknowledges the rules exist, but task completion takes priority over process compliance."

This is not a problem you can solve by writing more rules.

The more critical issue is uniform instruction degradation: according to HumanLayer's analysis and multiple community developers' observations, an LLM's reliable instruction-following upper limit is around 150-200 instructions (a community estimate, not official data). Claude Code's own system prompt already occupies roughly 50 slots, leaving only 100-150 slots available for CLAUDE.md. Past that threshold, degradation is uniformly distributed — every low-value rule added dilutes the compliance probability of every high-value rule equally.

Important note: The "200 line limit" is community consensus (validated by HumanLayer and multiple high-vote Reddit discussions), not an official Anthropic hard limit. There's no hard cutoff where 201 lines causes collapse, but the degradation trend is real, and Anthropic also recommends keeping within 200 lines.

Token cost context (for developers paying for the Claude API): CLAUDE.md consumes roughly 500-800 tokens per 100 lines, loaded in full at every session start — not incrementally. A 100-line CLAUDE.md on Claude Sonnet 4.6 adds roughly $0.0003-$0.0006 per session. Not a lot, but if your automation agents run dozens of times daily, it accumulates.

Decision point: When you encounter ignored instructions, ask yourself: is this a delivery layer problem, or a rule quality problem?

A quick diagnostic: paste that rule directly into the first message of your session (not through CLAUDE.md, manually type it). If Claude follows it now, it's a delivery layer problem — consider upgrading to hooks or --append-system-prompt. If Claude still ignores it, the rule itself needs to be written more specifically.


Three Tiers: "Accumulation" Not "Override" — The Right Way to Use global/project/local

Many people assume project CLAUDE.md "overrides" global CLAUDE.md, like CSS specificity. That's wrong.

All three tiers are read and their content accumulates:

TierPathWhat to put hereGit commit?
Global (personal)~/.claude/CLAUDE.mdPersonal preferences, cross-project tool habitsNo
Project (team)./CLAUDE.md or ./.claude/CLAUDE.mdArchitecture decisions, code standards, build/test commandsYes
Local (personal override)CLAUDE.local.mdPersonal preferences for this project (newer versions recommend @imports instead)No (add to .gitignore)
Managed Policy/Library/Application Support/ClaudeCode/CLAUDE.md (macOS)Enterprise compliance enforcementManaged by IT

A few common pitfalls:

Subdirectory CLAUDE.md files are lazy-loaded. On startup, Claude Code only fully loads CLAUDE.md files in the working directory and its ancestor directories. CLAUDE.md files in subdirectories are loaded on demand when Claude's tools actually access that subdirectory. If you put important rules in a subdirectory CLAUDE.md, Claude genuinely may not see them initially.

HTML comments don't consume tokens: If you want to leave human-readable maintenance notes in CLAUDE.md, use <!-- maintenance note: this rule was added because of X --> block-level comments. Claude Code automatically strips these before loading, so they don't consume your instruction budget.


CLAUDE.md Essential Structure: From Minimum Viable to Full Template

Claude Code's /init command analyzes your codebase and auto-generates a CLAUDE.md with tech stack, build commands, and existing conventions. It's a good starting point, but the generated content is often packed with things "Claude would know anyway."

What CLAUDE.md actually needs is implicit knowledge Claude can't derive from the code.

Essential section structure (ordered by scan efficiency — headers + bullet points are far faster to process than prose):

  1. WHAT: One sentence describing the project, tech stack (language, framework, primary tools)
  2. HOW: Specific build/test/deploy commands (npm run dev, npm test, etc.) — don't make Claude guess
  3. Code Style: Your most important code preferences, must be specific and executable ("functions max 30 lines, split if longer" — not "write clean code")
  4. Gotchas: Landmines and non-obvious design decisions Claude can't see from the code ("don't modify the src/generated/ directory — it's auto-generated by Prisma")

Minimum viable template for indie makers (the first step after /init):

  1. Tech stack + core commands: Framework version, start/test/deploy commands
  2. Your single most important code preference: Pick the one you care most about, write it specifically, include a counterexample
  3. One real Gotcha: Something you stepped on last week or last month — don't let Claude repeat it

Start with these three things. Don't try to plan out a perfect future in CLAUDE.md.

Ready-to-copy minimum viable template:

# [Your Project Name]

## Tech Stack
Next.js 15 + TypeScript + PostgreSQL + Prisma

## Commands
- Dev: `npm run dev`
- Test: `npm test`
- Build: `npm run build`

## Code Standards
- Use function declarations for components, not arrow function exports
- All API routes must do input validation with zod

## Gotchas
- The `src/generated/` directory is auto-generated by Prisma — don't edit manually
- Environment variables live in `.env.local` — never commit to git

Replace the content with your project details and you have a valid starting point.

Advanced modularization (only consider when a single CLAUDE.md exceeds 300 lines): Keep the main file lean, use @imports or .claude/rules/ for layered structure. Files under .claude/rules/ are loaded on demand when Claude accesses the corresponding directory (e.g., frontend.md triggers when Claude reads src/components/). Side projects don't need this layering — it's complexity only worth maintaining for multi-person teams or multi-agent scenarios.


settings.json vs CLAUDE.md: Two Systems, Two Types of Enforcement

These two are commonly confused, but their responsibilities are completely different:

settings.json = Firewall (technical enforcement, bypasses LLM)

  • Executed directly by the Claude Code client, Claude's judgment can't intervene
  • For: security controls (permissions.deny blacklist), sandbox configuration, env var injection

CLAUDE.md = Employee Handbook (behavioral guidance, through LLM judgment)

  • Delivered as text context, shapes Claude's behavior
  • For: architectural context, code style standards, workflow explanations, non-obvious Gotchas

Decision flow:

  • Need to absolutely block an action (e.g., forbid rm -rf, prevent direct prod DB modifications) → settings.json permissions.deny
  • Need to inject API keys or environment variables → settings.json env
  • Need Claude to understand and follow a working style → CLAUDE.md

One sentence: settings.json protects the system, CLAUDE.md educates Claude.


Rules vs Hooks: Division of Responsibility, Not Either/Or

Reddit user u/DevMoses (536 pts) nailed the observation: "I stopped adding rules to CLAUDE.md and started building infrastructure." His case: rules grew from 45 lines to 190 lines, but compliance actually decreased.

The reason: he was putting "mechanical rules" into a "behavioral guidance" system.

What hooks are for: Physical enforcement (shell execution, bypasses LLM judgment). For objectively determinable rules: format checking, test coverage, specific command interception. Hooks have two types: command (directly runs shell script) and prompt (LLM evaluation — note: this type still depends on the LLM, not 100% reliable). In PreToolUse events, exit code 2 blocks the operation; PostToolUse's exit code 2 can't retroactively prevent an already-executed action, only feeds stderr back to Claude.

Three-step routing decision:

  1. Can Linter/CI do it? → Give it to the Linter, don't burn instruction budget
  2. Objectively determinable, no context needed? → hooks command (shell enforcement)
  3. Needs LLM to understand architectural intent or business logic? → CLAUDE.md

Minimum working hooks configuration example (in settings.json's hooks field):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint 2>&1 | head -20"
          }
        ]
      }
    ]
  }
}

This example runs a lint check before every Bash command Claude executes. When lint fails, it returns a non-zero exit code and Claude stops to fix the issue before retrying.

Techniques for making rules more respected without hooks (alternatives if you're not comfortable with shell scripts):

  • Be specific, include counterexamples: Instead of "write clean functions," say "functions over 30 lines must be split (❌ don't keep stuffing logic into existing functions, ✅ extract to a separate function and update callers)"
  • Flag consequences: Add "when this rule is violated, stop and ask me rather than deciding on your own" to important rules
  • Trim to only what matters: Fewer rules written specifically beats many rules written vaguely

Hooks caveat: command hooks have shell environment dependencies (PATH, env vars) — in cron scheduling or remote execution scenarios they may fail due to different environments.


Multi-agent Fleet Design: A Real-World Look at Shareuhack's 8-Agent System

We run this kind of system ourselves, so we can share first-hand design insights.

Shareuhack's 8 autonomous agents (CEO/Researcher/Scout/Writer/Reviewer/Developer/Auditor/Data Analyst) share a project CLAUDE.md as a "constitution." This constitution defines the hard rules every agent must follow (no fabrication, internal link format, frontmatter standards, etc.) and the information architecture of the entire system.

Actual directory structure:

project CLAUDE.md          ← shared rules for all agents (constitution)
.claude/skills/            ← each agent's skill definitions (individual SKILL.md)
agents/memory/             ← per-agent operational memory (individual learnings, no cross-contamination)
agents/system-state.yaml   ← system state (maintained by CEO)

Technical backing from Anthropic Docs: Project CLAUDE.md is shared via git, giving all subagents their base context. Each subagent can maintain its own Auto Memory without contaminating the main agent's memory.

Special considerations for zero-HITL scenarios: In unmonitored cron-scheduled scenarios, the risk of ignored instructions is higher. Key techniques:

  • --append-system-prompt parameter: elevates instructions to system prompt level, significantly increasing enforcement strength. Note: this parameter must be passed on every invocation, suitable for CI/CD or cron scripts. CLI flags can change between versions — verify against the latest official docs before use
  • hooks are more reliable than CLAUDE.md rules (hooks are mechanically executed, don't depend on LLM judgment)

Configuration recommendations by scale:

ScaleRecommended setup
Solo developerproject CLAUDE.md (under 300 lines) + 1-2 subagent skills (pick your most repeated tasks)
Small teamproject CLAUDE.md (git-shared) + .claude/rules/ module categories (frontend/backend/testing)
Multi-agent fleetConstitution layering + skills directory + per-agent operational memory

An 8-agent fleet isn't what every developer needs. The key principle is scaling proportionally — a solo developer can start with a project CLAUDE.md under 300 lines and 1 subagent skill. The concept of a subagent skill is simple: create a .md file in .claude/skills/ defining a frequently repeated task (e.g., "code review" or "draft blog post") and Claude will automatically load that guidance when executing the task. One skill gives you the same architectural benefits without copying the entire fleet.

Multi-tool note: If you use Cursor, Zed, or other AI tools alongside Claude Code, they use AGENTS.md (the cross-tool standard). Claude Code doesn't read AGENTS.md by default, but you can reference it in your CLAUDE.md with @AGENTS.md, then append Claude-specific settings.


Avoiding Over-Engineering: The Right Architecture Matches Your Scale

Back to the opening question: Claude Code's author uses a "surprisingly vanilla" setup, with just three core components: past errors + conventions + rules.

There's a well-known Hacker News case: someone went from a 10,000-line semantic memory system back to 1,500 lines of CLAUDE.md + bash scripts, and got a 10x speed improvement. The costs: uniform instruction degradation, exploding token consumption, conflicting rules.

Three signals that suggest simplification:

  1. CLAUDE.md exceeds 300 lines (single file)
  2. Claude starts frequently ignoring rules you know you've written
  3. You can't remember whether a given rule is still working

Simplification process:

  1. Review each rule: "What specific mistake would Claude make without this line?" If you can't answer, delete it
  2. Return static checks (formatting, lint) to your Linter or hooks, freeing instruction budget
  3. Split overly long CLAUDE.md into @imports or .claude/rules/ for on-demand loading

Practical limit for side projects: A single CLAUDE.md under 300 lines is completely sufficient. .claude/rules/ layering is complexity worth maintaining only for multi-person collaboration or multi-agent scenarios.


Conclusion

CLAUDE.md is "the highest leverage point for educating Claude" — HumanLayer's words, and I fully agree. But the highest leverage point is also the easiest place to waste effort on low-quality rules.

A rule worth keeping must be "implicit knowledge Claude can't derive from the code and context." Everything else: give it to the Linter, give it to hooks, or delete it entirely.

If you're using Claude Code, here's my recommended starting point:

  1. Use /init to generate your base CLAUDE.md
  2. Filter out half the content using "would Claude make a mistake without this line?"
  3. Add the Gotchas you've actually stepped on
  4. Identify which rules should be promoted to hooks

Start with these four steps, and let your CLAUDE.md grow organically from there.

What does your CLAUDE.md look like right now? What mistakes have you made? Share in the comments.

FAQ

Is the CLAUDE.md generated by /init good enough? How do I improve it?

/init scans your codebase and auto-generates a CLAUDE.md with tech stack, build commands, and existing conventions — a solid starting point. The problem is it tends to include a lot of 'obvious common sense' that Claude would know anyway. The recommended improvement strategy: aggressively delete sections Claude would figure out on its own, keep only implicit knowledge and Gotchas that aren't visible in the code. Then adopt an 'organic growth' approach — whenever Claude makes a wrong assumption, immediately tell it 'add this to my CLAUDE.md' and let the document reflect real mistakes, not hypothetical rules.

Does the # key shortcut for updating CLAUDE.md still exist?

It was officially removed in Claude Code v2.0.70. The standard approach now is to tell Claude directly in natural language: 'add this to my CLAUDE.md', or use the /memory command to edit inline. The recommended habit is 'organic growth' — update immediately when you discover issues in a session, rather than doing periodic batch cleanup.