Remote OpenClaw Blog
Claude Code Rules: CLAUDE.md, Permissions, and Loop Control
8 min read ·
Claude Code rules come in two kinds: instruction rules in Markdown files (CLAUDE.md and the .claude/rules/ directory) that shape how Claude behaves, and permission rules in settings.json (permissions.allow and permissions.deny lists) that hard-limit what it can do. Instruction rules are context the model follows but can technically ignore; permission rules and hooks are enforced by the harness itself.
How Rules Work in Claude Code
Claude Code's primary rules file is CLAUDE.md, a Markdown file loaded into context at the start of every session. According to the official memory documentation, CLAUDE.md files load in order from broadest to most specific scope:
- Managed policy: organization-wide instructions (for example
/Library/Application Support/ClaudeCode/CLAUDE.mdon macOS) that cannot be excluded. - User:
~/.claude/CLAUDE.md, your personal preferences across every project. - Project:
./CLAUDE.mdor./.claude/CLAUDE.md, checked into git and shared with your team. - Local:
./CLAUDE.local.md, personal project-specific rules you add to.gitignore.
Rules files can pull in other files with @path/to/import syntax, resolved relative to the importing file and expanded at launch, with a maximum depth of four hops. Two commands manage the system: /init generates a starting CLAUDE.md by analyzing your codebase, and /memory lists every CLAUDE.md and rules file loaded in the current session. For a broader tour of the tool these rules configure, see our Claude Code guide.
The .claude/rules/ Directory
The .claude/rules/ directory lets larger projects organize instructions into multiple modular files instead of one monolithic CLAUDE.md. Its standout feature is path scoping: a rule file with a paths field in its YAML frontmatter only loads into context when Claude works with matching files, which saves context space and reduces noise. From the official docs:
---
paths:
- "src/api/**/*.ts"
---
# API Development Rules
- All API endpoints must include input validation
- Use the standard error response format
- Include OpenAPI documentation comments
Rules without a paths field load unconditionally, exactly like CLAUDE.md content. Personal rules in ~/.claude/rules/ apply to every project on your machine. This is the mechanism to reach for when your CLAUDE.md starts growing sections like "when editing the API..." that only matter some of the time.
Permission Rules in settings.json
Permission rules are the enforced kind: patterns in your settings files that decide which tool calls run automatically, which prompt you, and which are blocked outright. The syntax is Tool(pattern), per the settings reference:
{
"permissions": {
"allow": ["Bash(npm run test *)", "Read(~/.zshrc)"],
"deny": ["Bash(curl *)", "Read(./.env*)"]
}
}
Three arrays are available: allow (run without asking), ask (always confirm), and deny (block, which also hides matching file contents from Claude). Deny rules beat allow rules. Settings merge across files with a fixed precedence: managed policy first, then command-line flags, then .claude/settings.local.json, then the project's .claude/settings.json, then ~/.claude/settings.json.
On top of individual rules sit permission modes (defaultMode or Shift+Tab in a session): default auto-approves only reads, acceptEdits adds file edits, plan is read-only analysis, and bypassPermissions skips prompts entirely. The permission modes documentation also lists protected paths (.git, .claude, shell rc files, .mcp.json) that are never auto-approved outside bypass mode. If you are tempted by the skip-everything route, read our Claude Code YOLO mode guide for the guardrails first.
Rules vs Hooks vs Skills
Rules, hooks, and skills solve different problems: rules are always-on guidance, hooks are deterministic scripts at lifecycle events, and skills are on-demand expertise. The docs draw the line explicitly: memory files are "context, not enforced configuration", while hooks provide "deterministic control" that ensures "certain actions always happen rather than relying on the LLM to choose".
| Rules (CLAUDE.md / .claude/rules/) | Hooks | Skills | |
|---|---|---|---|
| What it is | Persistent instructions in Markdown | Shell commands at lifecycle events (PreToolUse, PostToolUse, Stop...) | Reusable workflows in SKILL.md files |
| Enforcement | Advisory: Claude follows, but can miss | Deterministic: always runs, can block with exit code 2 | On-demand: loads when relevant or invoked |
| Context cost | Loaded every session (path-scoped rules only when matched) | None in context; runs outside the model | Descriptions only, full content on use |
| Best for | Conventions, build commands, style | Formatting, blocking commands, validation gates | Domain knowledge, multi-step procedures |
| Lives in | CLAUDE.md, .claude/rules/ | settings.json | .claude/skills/<name>/SKILL.md |
The rule of thumb: if violating it merely annoys you, put it in CLAUDE.md; if violating it breaks something, enforce it with a hook or a deny rule; if it is a procedure Claude only sometimes needs, package it as a skill. We compare the skill format ecosystems in our OpenClaw vs Claude Code skills comparison.
Writing Rules That Actually Stick
The official size guidance for rules files is specific: target under 200 lines per CLAUDE.md, because longer files consume more context and reduce adherence. Anthropic's best practices documentation puts the editing test bluntly: for each line, ask whether removing it would cause Claude to make mistakes, and if not, cut it, warning that "bloated CLAUDE.md files cause Claude to ignore your actual instructions".
What earns a place: bash commands Claude cannot guess, style rules that differ from language defaults, the preferred test runner, branch and PR conventions, required environment variables, and genuine gotchas. What does not: anything Claude can learn by reading the code, standard conventions it already knows, file-by-file codebase tours, and filler like "write clean code". A solid minimal project file looks like this:
# Code style
- Use ES modules (import/export) syntax, not CommonJS (require)
- Destructure imports when possible (eg. import { foo } from 'bar')
# Workflow
- Be sure to typecheck when you're done making a series of code changes
- Prefer running single tests, and not the whole test suite, for performance
If you would rather start from proven layouts than a blank file, our Claude Code templates guide collects CLAUDE.md and settings patterns you can copy.
The Claude Code Loop (and Stopping Runaways)
The Claude Code loop is the cycle the agent runs on every task: gather context, take action, verify results, repeat until done, as described in Anthropic's "How Claude Code works" documentation. Each round of "model responds, tools execute, results feed back" is one turn, and long sessions are kept viable by automatic compaction, which summarizes older history when the context window approaches its limit.
Loops become a problem in two ways. The first is the quality loop you actually want: a Stop hook that runs your tests and blocks the turn from ending until they pass. That could recurse forever, so Claude Code caps it: per the docs, it "overrides the hook and ends the turn after 8 consecutive blocks". If you build verification loops, add your own failure counter inside the hook script as well, so it gives up gracefully instead of leaning on the override.
The second is the runaway session: an agent burning tokens re-trying a doomed approach. In interactive use, press Escape to interrupt and redirect. In automation built on the Agent SDK, cap the loop explicitly with max_turns (which counts tool-use turns) and max_budget_usd (which stops the session past a spend threshold). Scoped permissions from the section above are the third brake: an agent that cannot run curl or write outside the repo has a much smaller blast radius while it loops. Raising the effort level makes each turn more deliberate, which often reduces total turns on hard problems.
Limitations
The core limitation of instruction rules is that they are probabilistic. CLAUDE.md content is context the model weighs, not configuration the harness enforces, so a rule can lose out to a stronger competing signal, especially deep into a long session after compaction. Anything security-critical belongs in deny rules or hooks, never only in Markdown.
Rules also carry a standing context tax: every unconditional line loads in every session, which is why the 200-line guidance exists and why path-scoped .claude/rules/ files beat one giant file. Finally, rules interact with precedence in ways that surprise teams: a developer's settings.local.json outranks the shared project settings, so shared guardrails you actually care about should live in managed policy or the checked-in project file, with the team aware that local overrides exist.
Related Guides
- Claude Code Hooks: Setup, Events, and Real Examples
- Claude Code Best Practices in 2026: What Actually Holds Up
- Claude Code Templates: The Complete Guide for 2026
- Claude Code Guide [2026]: CLI, Desktop, Web, and Real-World Fit
Go deeper
The operator playbooks
Production-ready PDF guides for OpenClaw and Hermes Agent — $19.99 each.
Skills for this topic
Browse all skills →Frequently Asked Questions
What are Claude Code rules?
Rules are the persistent instructions Claude Code loads every session: Markdown guidance in CLAUDE.md and the .claude/rules/ directory, plus enforced permission rules ( allow , ask , deny patterns) in settings.json. The Markdown kind shapes behavior; the settings kind hard-limits which tool calls can run.
Where do I put rules in Claude Code?
Project rules go in ./CLAUDE.md (or ./.claude/CLAUDE.md ) checked into git; personal cross-project rules go in ~/.claude/CLAUDE.md ; private per-project preferences go in ./CLAUDE.local.md , which you gitignore. For larger projects, split rules into .claude/rules/ files, optionally scoped to file paths with YAML frontmatter.
Are CLAUDE.md rules always followed?
No. The official docs state Claude treats memory files as "context, not enforced configuration", so adherence is strong but not guaranteed, and it degrades as files bloat. For rules that must hold every time, use a PreToolUse hook or a permissions.deny entry, both of which are enforced by the harness rather than the model.
How do I stop Claude Code from looping?
Interactively, press Escape to interrupt the turn and redirect. Structurally: Claude Code auto-caps Stop-hook verification loops after 8 consecutive blocks, and SDK automations should set max_turns and max_budget_usd to bound tool-use turns and spend. Tight permission rules also shrink what a looping agent can touch while you notice and intervene.
What is the difference between rules and hooks in Claude Code?
Rules are instructions the model reads and follows probabilistically; hooks are shell commands the harness executes deterministically at lifecycle events like PreToolUse and Stop. A rule saying "never edit .env files" can be missed; a hook or deny pattern blocking Edit on .env* cannot. Use rules for style and conventions, hooks for guarantees.

