Rules
You’ve started a fresh session on the same repo for the fifth time this week. The first three messages of every session are always the same: “we use pnpm, not npm. Tests are in __tests__/, not next to source. Don’t auto-run the dev server, it conflicts with the one I already have open. Use the dev-stack branch as base, not main.”
You’re not telling the agent anything new. You’re telling this session what you already told last session, because sessions don’t remember each other. It can read any file and grep anything; what it can’t do is know the unwritten conventions of the team that owns the repo. So every session starts at zero on the same five facts.
Rules are how you stop re-teaching. They are the persistent, human-authored context each CLI reads at session start and injects into the model’s context: a file (or set of files) you write and check into the repo, holding the facts you would otherwise repeat - “we use pnpm not npm,” “never edit migrations after they’ve been merged.” Write them down once and they load before your first message. The agent walks in already knowing.
The file format has partly converged. Several tools read AGENTS.md natively, while Claude Code’s primary file is CLAUDE.md and can pull the other in with an @AGENTS.md import. So the clean pattern is one AGENTS.md at your repo root, imported into CLAUDE.md where needed - a single source of truth for the tools that support it. The Comparison table has the per-tool filenames.
Rules are declarative: you write them, the agent reads them. That is the whole line between rules and agent-managed memory, a separate primitive this chapter doesn’t cover - see Name collisions.
Real-world examples of what teams put in CLAUDE.md / AGENTS.md:
- Stack and tooling - package manager, test runner, linter, build commands. The first thing the agent gets wrong without this.
- Project layout - where things live (“API code is in
services/api, web is inapps/web”). Saves it grepping the tree for a file you could have named. - Conventions the linter can’t catch - “use the
Loggerclass, notconsole.log,” “all DB calls go throughdb/repo/,” “feature flags read fromflags.ts, never inline.” - Workflow rules - “never push to
main,” “runpnpm validatebefore declaring done,” “write tests in the same PR as the feature.” - Domain context - what your product is, who uses it, what the core nouns mean. Especially for non-obvious domains (insurance, logistics, ad-tech).
- Pointers to deeper docs - “for the auth flow, read
docs/auth.md,” so the file stays small but the breadcrumbs are there.
The test: if you’ve corrected the agent on the same thing twice across sessions, it belongs in your rules.
Why this and not…
Section titled “Why this and not…”| You want to… | Reach for | Not |
|---|---|---|
| State a fact the agent should know on every turn of every session | Rules | Skill |
| Encode a multi-step procedure the agent activates only when relevant | Skill | Rules |
| Hard-enforce a rule (block, gate, redirect) deterministically | Hook | Rules |
| Apply guidance only when working in a specific path/subdir | Path-scoped rules (see below) | Bloating root CLAUDE.md |
| Share knowledge across multiple repos | User-global rules file | Per-repo rules |
Rules are always loaded, every turn. That makes them powerful - and expensive on context. Anything that doesn’t need to be present every single turn belongs in a skill instead. Anything that needs to enforce (not just inform) belongs in a hook.
The tabs won’t tell you which files win when several apply at once. That needs the per-tool paths first, so it waits until after the tabs.
How it works in each tool
Section titled “How it works in each tool”Files Claude Code may load into a session:
./CLAUDE.md- project root- Nested
CLAUDE.mdfiles in subdirectories - load when Claude works in that subdir ~/.claude/CLAUDE.md- your user-wide file (applies to every project)- Managed-policy
CLAUDE.md- org-controlled, takes precedence .claude/rules/*.md- optional path-scoped rules (new in 2026)
Layering: all levels are additive. Claude reads every applicable file and uses judgment when they conflict; later or more-specific instructions often receive more attention, but contradictory files are not a reliable override mechanism.
Path-scoped rules keep CLAUDE.md small. A rule file in .claude/rules/ with paths: frontmatter only loads when Claude touches matching files:
---paths: ["src/api/**"]---Use Zod for all request validation.Path-scoped rules load when Claude reads matching files. Verify that a rule is present with /memory or /context before relying on it for anything critical.
Imports: @path/to/file anywhere in CLAUDE.md inlines that file’s content. @AGENTS.md imports that file into Claude Code; whether other tools read it is tool-specific.
Sizing: keep CLAUDE.md under ~200 lines. Move reference material to skills, and path-specific guidance to .claude/rules/.
Files Codex reads:
./AGENTS.md- project root- Closest
AGENTS.mdwalking up from the working directory ~/.codex/AGENTS.md- user-wide
Standard: Codex implements the open agents.md spec. Any tool that follows the spec reads the same file.
Layering - nested files: Codex concatenates AGENTS.md files from the root downward into one combined prompt, joined by blank lines. Files closer to the working directory appear later and therefore override earlier guidance positionally - additive with positional override, not replacement.
@path imports: Not supported. AGENTS.md is read as-is; there is no file-inclusion directive.
Files OpenCode reads:
./AGENTS.md- project root~/.config/opencode/AGENTS.md- user-wide
Standard: OpenCode is the other implementation of the agents.md spec. A project’s AGENTS.md is portable between OpenCode and Codex with no changes.
Behavioral rules: OpenCode does not have a separate “Rules” file - AGENTS.md is the rules layer. For additional rule sources, point at extra files via the instructions field in opencode.json (accepts file paths or glob patterns).
Nested files: OpenCode walks up from the current working directory and the first matching file wins per category - a subdirectory’s AGENTS.md replaces (does not merge with) a parent’s.
@path imports: Not parsed. OpenCode does not auto-resolve @path references inside AGENTS.md. Workarounds: list the files in opencode.json’s instructions field, or instruct the agent in prose to read specific files on demand.
Files Cursor reads:
./AGENTS.md- repo root; nestedAGENTS.mdfiles in subdirectories auto-apply when working in that subtree.cursor/rules/*.mdc- Cursor-native rule files (Markdown + YAML frontmatter).cursorrules- legacy single-file format at repo root; still honored for back-compat, no longer recommended- User Rules - global, edited from Cursor Settings → Rules; no local file
- Team Rules - dashboard-managed on Team and Enterprise plans; pushed to all members
Standard: Cursor reads AGENTS.md natively - portable with Codex and OpenCode from a single file.
.mdc frontmatter controls when a rule attaches:
---description: Use Zod for request validationglobs: ["src/api/**"]alwaysApply: false---All API handlers validate input with Zod schemas.Four rule types map to those fields: Always (alwaysApply: true), Apply Intelligently (agent picks via description), Apply to Specific Files (globs:), and Apply Manually (invoked with @RuleName).
Layering: Project, User, and Team rules are additive. .cursor/rules/ and AGENTS.md coexist - Anysphere recommends AGENTS.md for cross-tool portability and .cursor/rules/ for Cursor-specific guidance.
@path imports: No bare @path syntax inside rule files. @RuleName invokes a specific manual rule; @File and @Folder attach context inline in chat. Not the same primitive as Claude Code’s static import.
Files Copilot reads (VS Code, JetBrains):
.github/copilot-instructions.md- single-file, repo-wide.github/instructions/*.instructions.md- path-scoped withapplyTo:glob./AGENTS.md,./CLAUDE.md,./GEMINI.md- read natively at repo root; nearest file in the directory tree takes precedence- Personal custom instructions - set at
github.com/settings/copilot; apply to your sessions across all repos - Org instructions - Business/Enterprise; set by org admins
Standard: Copilot natively reads AGENTS.md (and CLAUDE.md, GEMINI.md) at the repo root - clean interop with Codex, OpenCode, Cursor, and Claude Code from a single file.
Path-scoped instructions use frontmatter:
---applyTo: "app/models/**/*.rb"---Use Active Record validations; never raw SQL in models.applyTo: accepts comma-separated globs. Optional excludeAgent: opts the file out of specific surfaces (e.g., ["code-review", "cloud-agent"]).
Layering precedence (highest → lowest): personal > repository > organization. All applicable sets are concatenated, not overridden.
VS Code knob: github.copilot.chat.codeGeneration.useInstructionFiles must be true for copilot-instructions.md to auto-apply (default on in current builds). JetBrains lags VS Code on path-scoped .instructions.md support.
@path imports: No file-inclusion directive. #file:path references a file as live context inside a chat turn, but doesn’t statically import rules at session start.
Files Pi reads at startup: AGENTS.md (or CLAUDE.md) from three locations, concatenated:
~/.pi/agent/- user-global- Every parent directory walking up from the current working directory
- The current directory itself
Layering: every matching file on the walk is concatenated in order - global first, then each ancestor down to the cwd. Closer files land later in the assembled context, but Pi does not implement a formal override rule, so overlapping guidance is not resolved for you. Disable the whole mechanism per run with --no-context-files / -nc.
A second, stronger layer: SYSTEM.md (project .pi/SYSTEM.md or user ~/.pi/agent/SYSTEM.md) replaces Pi’s default system prompt outright. APPEND_SYSTEM.md appends to it instead of replacing it.
The practical split: AGENTS.md is helpful project context the agent can weigh against a request. APPEND_SYSTEM.md is a stronger, must-follow rules layer baked into the system prompt itself - reach for it when a convention needs to survive the model treating it as “just” a suggestion.
Pi doesn’t do path-scoped rules via glob frontmatter - nesting AGENTS.md files deeper in the tree is the only targeting mechanism, and deeper files are appended rather than replacing the ones above them. If two levels genuinely conflict, resolve it in the text yourself.
Which files load, and in what order
Section titled “Which files load, and in what order”Tools agree on where rules files live but not on how they combine - and the differences bite in monorepos. Same repo, same files, a different answer per tool: pick where the agent is working and see exactly which files each one loads. In OpenCode, nested rule selection and configured instructions are separate mechanisms: the former uses precedence, while the latter can be combined with AGENTS.md.
Comparison
Section titled “Comparison”| Aspect | Claude Code | Codex | OpenCode | Cursor | Copilot | Pi |
|---|---|---|---|---|---|---|
| Default project file | CLAUDE.md | AGENTS.md | AGENTS.md | .cursor/rules/*.mdc or AGENTS.md | .github/copilot-instructions.md or AGENTS.md | AGENTS.md / CLAUDE.md (+ APPEND_SYSTEM.md / SYSTEM.md) |
| Cross-tool standard | Via @AGENTS.md import | Native (agents.md) | Native (agents.md) | Native (AGENTS.md) | Native (AGENTS.md / CLAUDE.md / GEMINI.md) | Native (agents.md) |
| User-global file | ~/.claude/CLAUDE.md | ~/.codex/AGENTS.md | ~/.config/opencode/AGENTS.md | User Rules (UI; no local file) | Personal instructions (github.com) | ~/.pi/agent/ |
| Path-scoped rules | .claude/rules/ with paths:¹ | - | instructions: in opencode.json | globs: in .mdc frontmatter | .instructions.md with applyTo: | - (nested walk only, no glob targeting) |
| Nested files per subdir | Concatenated (additive) | Concatenated; deeper files override by appearing later | First match wins (no merging) | Nested AGENTS.md auto-applied in subtree | Nearest AGENTS.md takes precedence | Nested walk, concatenated; closer files appended later, no formal override |
@path imports | Yes (bare @path) | No | No | @RuleName only (manual invocation) | No | No |
| Managed/org override | Yes | Yes | Yes | Yes (Team Rules) | Yes (Business / Enterprise) | - (project resources are trust-gated, not org-policy-gated) |
¹ paths: is the documented, current key - not globs: (that’s Cursor’s). As of 2026-07 it has open reliability bugs: user-level (~/.claude/rules/) scoping can be silently ignored, and a rule may load on read but not on write. See the Claude Code tab above for detail.
Name collisions
Section titled “Name collisions”“Rules” is the least portable word in this chapter. It names a different slice of the layer in every tool:
| Tool | What the word points at there |
|---|---|
| Claude Code | The path-scoped Markdown files in .claude/rules/ only - a subset. The main file is CLAUDE.md. |
| Codex | No separate “Rules” concept; AGENTS.md is the entire layer. |
| OpenCode | No separate “Rules” file; AGENTS.md carries the role, supplemented by the instructions field in opencode.json. |
| Cursor | The umbrella name for the whole layer: .cursor/rules/*.mdc, User Rules, Team Rules, plus AGENTS.md. |
| Copilot | Called “instructions” throughout: copilot-instructions.md, .instructions.md, personal and org instructions. |
| Pi | No “Rules” concept; AGENTS.md / CLAUDE.md is the context layer, with APPEND_SYSTEM.md / SYSTEM.md as a stronger layer above it. |
In this chapter, “rules” is the cross-tool umbrella term. Two more collisions worth knowing:
AGENTS.mdvsCLAUDE.md- same purpose, different filenames. Don’t write conflicting copies of both in one repo; have one import the other.- “Memory” is not the same as rules. Rules are human-authored, declarative, version-controlled. Memory (in the strict sense) is agent-managed - the agent itself decides what facts to remember about a user or project across sessions, often without you seeing the write. They solve different problems and live in different places. This chapter covers rules only.
Start with one AGENTS.md at the repo root and let corrections fill it: the second time you tell the agent the same thing, that line goes in the file. When it stops fitting - the Claude Code tab suggests holding it under ~200 lines - the overflow has somewhere to go. Procedures move to skills, path-specific guidance to path-scoped rule files, and anything that has to be enforced rather than remembered to hooks.