Prune CLAUDE.md and AGENTS.md: the ablation protocol
PLPruning context files means treating CLAUDE.md, AGENTS.md and Cursor rules as a budget to cut, not a log to extend. The ablation protocol archives the file, records which mistakes repeat, restores only the lines that prevent them, moves the rest into scoped rules, skills and hooks, and reruns on each model change.
Three months ago you added a line telling the agent never to run pnpm build while the dev server is up. This morning it ran pnpm build while the dev server was up. The instinct is to rewrite the rule in capitals and prefix it with “IMPORTANT”. That makes the file longer, and a longer file is part of why the rule was missed. This page is for the developer who owns a repository’s agent configuration and the tech lead who has to keep one file useful for eight people and three tools. If you have not written a context file yet, start with concise repository context and come back when it has grown.
What you get from pruning context files
Section titled “What you get from pruning context files”- A map of what Claude Code, Codex and Cursor load at launch, what they load on demand, and which “optimizations” save nothing
- A routing table that answers “where does this line go” for every rule you keep
- Six copy-paste prompts that archive, audit, move, consolidate and re-test your instruction files
- A byte-budget script for Codex and a line-count gate for CI, so the file cannot quietly grow back
- A verification loop that proves the pruned file still works
Why a longer context file makes the agent worse
Section titled “Why a longer context file makes the agent worse”Anthropic’s own memory documentation states the cost plainly: target under 200 lines per CLAUDE.md, because “longer files consume more context and reduce adherence”. Three more mechanics explain why length hurts:
- Instructions are advice, not configuration. Claude Code delivers
CLAUDE.md“as a user message after the system prompt”, with “no guarantee of strict compliance, especially for vague or conflicting instructions”. If two lines contradict each other, “Claude may pick one arbitrarily”. - Every copy is paid again. In Claude Code, every subagent except the built-in Explore and Plan agents loads the full
CLAUDE.mdhierarchy, unless its definition setsomitClaudeMd: true(v2.1.271+). Fan out ten subagents without that field and you pay for the file eleven times. - Codex cuts the overflow. Codex caps project
AGENTS.mdcontent at 32 KiB by default (project_doc_max_bytes, checked in the 0.157.1 source). The file that crosses the limit is truncated, and every file after it is skipped.
Accretion is adding a line after every mistake, so the file only grows. Ablation is the machine-learning term for removing a component to measure what it contributed. Here it means deleting lines on purpose and restoring only what demonstrably breaks.
Set the dial to the model that reads the file
Section titled “Set the dial to the model that reads the file”The scaffolding a repository needs shrinks as the model reading it gets stronger. Every rule is a bet that the model cannot work something out on its own, and newer models win more of those bets. As of 2026-10-12 the defaults are Claude Opus 5.5 in Claude Code (from v2.1.280, on both release channels) and GPT-6.1 Sol as Codex’s bundled default (since CLI 0.159.1); the models hub holds the current list.
- Frontier default models. Prune hard. Keep only what the model gets wrong without it.
- Cheaper or older models (a
sonnetorhaikualias, a local model). Keep more explicit instruction: the package manager, prerequisites, the one command that is wrong to run. - Mixed teams. If your Opus session, a colleague’s cheaper model and a CI job all read the same file, write for the least capable reader. A strong model copes with an over-specified file better than a weak one copes with an under-specified file.
So re-run the audit when you change models, not on a calendar, as one step of the new-model playbook. Claude Code now has a check for exactly this: /doctor prompt-audit looks for “instructions written for older models”, references to files or commands that no longer exist, and files that contradict each other (v2.1.283, both release channels on 2026-10-12). When you move down a tier for cost, expect to restore some lines. That is the dial moving, not a regression.
What Claude Code, Codex and Cursor load, and when
Section titled “What Claude Code, Codex and Cursor load, and when”The main file loads every session. Which other mechanisms defer loading decides where each surviving line lives.
At launch, in full: managed policy files, ~/.claude/CLAUDE.md, every CLAUDE.md and CLAUDE.local.md in your working directory and the directories above it, and every .claude/rules/*.md file without paths frontmatter. Auto memory adds the first 200 lines or 25 KB of MEMORY.md, whichever comes first.
On demand: .claude/rules/*.md files with a paths glob load when Claude reads a matching file. CLAUDE.md files in subdirectories below your working directory load when Claude reads a file in that directory.
AGENTS.md: from v2.1.277 (on both release channels since stable reached v2.1.287, checked 2026-10-12), Claude Code reads AGENTS.md when there is no CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md in the working directory or above it. To load both, set Project instructions in /config to claude-md-and-agents-md.
Traps worth knowing:
@pathimports do not reduce context. Imported files “are expanded and loaded into context at launch”. Five tidy imports of a 400-line file still cost 400 lines every session.- Auto memory is accretion without you. It is on by default and writes notes to
~/.claude/projects/<project>/memory/. Its index loads every session, so it is part of the surface you prune. - A
CLAUDE.local.mdswitchesAGENTS.mdoff. Adding one for personal notes in anAGENTS.md-only repository stops Claude from readingAGENTS.mdunder the default setting. - HTML comments are free. Block-level
<!-- ... -->comments are stripped before injection, so rationale for human maintainers costs no tokens. - Claude Code already flags an overgrown file. It warns at startup and in
/statuswhen an instruction file is over the recommended length, and the/doctorcheckup (v2.1.206+) proposes trims of content derivable from the codebase, such as directory layouts and dependency lists, in a checked-inCLAUDE.md.
Check what loaded with /context (the Memory files list) and /memory.
At session start: the global ~/.codex/AGENTS.md, then one file per directory from the project root (the nearest .git by default) down to the directory you started in. In each directory Codex takes AGENTS.override.md if it exists, otherwise AGENTS.md. Files are concatenated root first, so the files nearest your working directory come last.
On demand: nothing. A deeper AGENTS.md applies only to sessions started in that directory or below it.
Untrusted projects: since 0.150.0, a project you have not trusted supplies no project AGENTS.md at all.
The trap that costs debugging hours is the byte budget:
project_doc_max_bytesdefaults to 32 KiB and covers the project files only. The global~/.codex/AGENTS.mddoes not count against it.- The file that crosses the limit is cut at the remaining byte count, and every file after it is skipped.
- Codex logs a warning (“project doc exceeds remaining budget; truncating”) and starts the session anyway, so the cut is easy to miss.
- Because files load root first, the loss lands on your most specific instructions, the ones nearest your working directory.
You can raise the limit in ~/.codex/config.toml (project_doc_max_bytes = 65536), but splitting and moving procedures into skills is the better fix. Codex memories are off by default in 0.157.1; if you turn them on, prune them too.
Cursor’s Rules “provide system-level instructions to Agent”. A rule either applies always or is scoped, and always-applied rules are the ones that cost context on every request. Rules can also come from outside the repository (your own settings, or rules your organization manages), so list every rule the Rules settings page shows, not just the files in your checkout.
Cursor also supports skills, hooks and plugins. Project rules are .mdc files in .cursor/rules with description, globs and alwaysApply frontmatter, Cursor reads AGENTS.md in the project root and subdirectories, and it reads CLAUDE.md the same way, always applied to every conversation (Cursor docs, checked 2026-10-12). The protocol below works regardless: list every rule with how it applies, then prune the always-applied set first.
Where each line in a context file belongs
Section titled “Where each line in a context file belongs”Once you know what defers, “should this line stay?” becomes “where does this line go?”. The main file is only one of several destinations.
| What you have | Claude Code | Codex | Cursor |
|---|---|---|---|
| Rule needed in every session | CLAUDE.md (or AGENTS.md), under 200 lines | root AGENTS.md | always-applied rule |
| Rule for one file type | .claude/rules/<topic>.md with paths | nearest AGENTS.md to those files (no glob scoping) | rule scoped to a glob |
| Rule for one package or directory | subdirectory CLAUDE.md | subdirectory AGENTS.md (AGENTS.override.md to shadow it) | scoped rule |
| Multi-step procedure | skill in .claude/skills/<name>/SKILL.md | skill in .agents/skills/<name>/SKILL.md | skill |
| “Never do X” that must hold | PreToolUse or Stop hook | hook, or a CI check | hook |
| Extra guidance for a cheaper model | subagent definition with its own model | subagent definition | subagent definition (check that it can pin a model) |
| Subagent that gets everything from its delegation prompt | omitClaudeMd: true in its definition (v2.1.271+), so it stops paying for CLAUDE.md | — | — |
| Personal preference | CLAUDE.local.md or ~/.claude/CLAUDE.md | ~/.codex/AGENTS.md | user rule |
| Note for human maintainers | HTML comment (zero tokens) | README | README |
Two rules of thumb fall out of the table:
- If a rule starts with “when”, it does not belong in the main file. “When working on API handlers, validate with the shared schema helper” is a path-scoped rule in disguise.
- If you would be annoyed when the agent ignores it, prose is the wrong tool. “Never run the build while the dev server is up” is a hook, not a sentence. See hooks as deterministic guardrails.
Run the ablation protocol
Section titled “Run the ablation protocol”The six steps below run in order: archive, audit, move, harden, consolidate, prove. Each has a prompt that works in any of the three tools; the tabs carry only the per-tool differences.
-
Archive the file and start an ablation log. Do not edit first. Find out what the file is buying you. Work normally for a week with a minimal file and record every stumble. A line comes back only when the agent fails the same way twice; one failure is noise.
Archive
CLAUDE.md,CLAUDE.local.mdand.claude/rules/. Pause auto memory for the week, or it rewrites what you removed: set"autoMemoryEnabled": falsein.claude/settings.local.json, or exportCLAUDE_CODE_DISABLE_AUTO_MEMORY=1. Confirm with/contextthat Memory files holds only what you expect.Archive every
AGENTS.mdandAGENTS.override.mdin the tree. Rename files rather than emptying them; an empty file is not the same as a missing one when you later compare runs.Archive the project rules directory, then list every rule the Rules settings page shows, including rules from your own settings or your organization. Those keep applying while you think you have ablated.
-
Audit the archive line by line. The agent must give a verdict and a reason for every line. Twenty weak reasons in a row make deletion easy.
KEEP lines are candidates, not restorations: a KEEP line goes back only once the log shows the failure it prevents twice; until then, keep the KEEP list in the log.
In Claude Code, run
/doctor prompt-auditfirst (v2.1.283 or later, both release channels on 2026-10-12; it needs bundled skills enabled; pass a path such as.claude/rulesto audit one file or directory). It reports outdated and conflicting instructions with proposed edits and changes nothing until you ask. In Codex, run the byte-budget script before the prompt so you know which instructions were already being lost. -
Move conditional rules out of the main file. Every MOVE-PATH verdict becomes a scoped rule or a subdirectory file. In a monorepo, the root file keeps only what is true for every package; near-universal is not universal.
A rule without
pathsloads at launch like the main file, so the frontmatter is what makes it conditional:---paths:- "services/api/**/*.ts"---# API handlers- Validate every request body with the shared schema helper in `services/api/lib/validate.ts`.- Error responses use the `{ error, code }` shape, never a bare string.pathsis the only frontmatter field Claude Code reads from a rule. If the YAML does not parse, the rule loads unconditionally;claude --debugshows the parse error.Codex has no glob-scoped rules: its only conditional axis is directory depth. Place each rule in the
AGENTS.mdnearest the files it governs, and useAGENTS.override.mdonly where a package genuinely contradicts its parent (a service on a different runtime). Splitting is also how you stay under 32 KiB.Turn each cluster into a rule scoped to its glob rather than an always-applied rule, then confirm in the rules list that it shows as scoped.
-
Turn procedures into skills and hard rules into hooks. A procedure in the main file is read on every turn. A skill is read when its description matches the task, so detail becomes cheap there. A “never” in prose is a strong suggestion; a hook is enforcement.
The hook for the
pnpm buildrule from the opening, in Claude Code’s.claude/settings.json:{"hooks": {"PreToolUse": [{"matcher": "Bash","hooks": [{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/no-build-with-dev-server.sh" }]}]}}#!/bin/bash# .claude/hooks/no-build-with-dev-server.sh (chmod +x; needs jq and lsof)COMMAND=$(jq -r '.tool_input.command')if echo "$COMMAND" | grep -Eq 'pnpm( -[^ ]+)*( run)? build' && lsof -iTCP:3000 -sTCP:LISTEN >/dev/null 2>&1; thenjq -n '{hookSpecificOutput: {hookEventName: "PreToolUse", permissionDecision: "deny",permissionDecisionReason: "Dev server is listening on :3000. Stop it before pnpm build."}}'fiexit 0The matcher is illustrative: extend the pattern to every spelling your team uses. Codex hooks are stable and on in 0.157.1, and need persisted trust before they run: register a similar command hook in
.codex/hooks.json(or a[hooks]table inconfig.toml). Hooks as deterministic guardrails has the Codex registration and the Cursor fallback. For formatting and lint rules, a CI check is often the better wall because it also catches human commits. -
Consolidate to one source of truth. Two files that say nearly the same thing drift apart at the rate you edit them.
AGENTS.mdis the open cross-tool format; put everything tool-agnostic there and keep tool-specific files close to empty.If the repository has no
CLAUDE.md, Claude Code v2.1.277+ readsAGENTS.mddirectly. If you need Claude-specific lines, or some sessions run an older version, make@AGENTS.mdthe first line ofCLAUDE.mdand add the Claude-only lines below it. Prefer the import to a symlink when anyone clones on Windows: a symlink there needs Administrator privileges or Developer Mode.AGENTS.mdis already native. Deduplicate the global~/.codex/AGENTS.mdagainst the project files: it sits outside the byte budget, but anything stated twice is still paid for twice in the context window.Check for overlap between always-applied rules and any shared instruction file. Where the same guidance appears in both, keep one copy.
-
Prove each kept rule, then schedule the next round on a model change. If you cannot name a behaviour a rule changes, it is noise, and noise is not free.
How to prove the pruned file still works
Section titled “How to prove the pruned file still works”Pruning is only safe if you can show nothing regressed without rereading every line and every diff. Five checks carry that proof:
- Your existing gates stay green. Tests, type checks and lint in CI are the behavioural check. A pruned file that produces failing PRs shows up there first, not in a review of the file.
- The ablation log is the evidence. Every restored line cites at least two dated failures. A PR that says “removed 140 lines; three failures in two weeks, two lines restored, log attached” is reviewable. A bare 140-line deletion is not.
- Loading is confirmed, not assumed. In Claude Code,
/contextlists the memory files that loaded, and a hook on theInstructionsLoadedevent can log whichCLAUDE.mdand rules files loaded, when and why. AnAGENTS.mdthat Claude Code reads directly (noCLAUDE.md) does not fireInstructionsLoaded; confirm it with/memory, which lists it from v2.1.280. In Codex, run the byte-budget script below. - Size is gated in CI. The line-count gate below fails a PR that pushes any instruction file past 200 lines, so accretion needs a conscious exception.
- Someone owns the file. Put instruction files under
CODEOWNERSso the tech lead signs off on every addition, and require a log entry for each one.
Check the Codex byte budget
Section titled “Check the Codex byte budget”Save this as codex-agents-budget.sh and run bash codex-agents-budget.sh from the directory you start Codex in (run it with bash, not source, so its exit does not close your terminal). It follows the same order Codex uses (project root first, one file per directory, AGENTS.override.md before AGENTS.md) and prints the running total:
#!/usr/bin/env bashroot=$(git rev-parse --show-toplevel) || { echo 'not a git repo'; exit 1; }d=$PWD; dirs=()while :; do dirs=("$d" "${dirs[@]}"); [ "$d" = "$root" ] && break [ "$d" = / ] && break; d=$(dirname "$d")donetotal=0for d in "${dirs[@]}"; do for f in AGENTS.override.md AGENTS.md; do if [ -f "$d/$f" ]; then size=$(wc -c < "$d/$f"); total=$((total + size)) printf '%7d bytes running %7d %s\n' "$size" "$total" "$d/$f"; break fi donedoneif [ "$total" -gt 32768 ]; then echo "Over 32 KiB: Codex truncates the file that crosses the line and skips the rest."fiIt ignores project_doc_fallback_filenames and a raised project_doc_max_bytes; adjust the names and the limit if you set either.
Gate instruction-file length in CI
Section titled “Gate instruction-file length in CI”# CI step: fail when any agent instruction file exceeds 200 linesover=$(git ls-files '*CLAUDE.md' '*AGENTS.md' '*AGENTS.override.md' '.claude/rules/*.md' \ | while read -r f; do n=$(wc -l < "$f") if [ "$n" -gt 200 ]; then echo "$f: $n lines"; fi done)if [ -n "$over" ]; then echo "$over"; echo "Prune or split before merging."; exit 1fiThe 200-line figure is Anthropic’s recommendation for a single CLAUDE.md; pick your own number for Codex-only repositories, but pick one.
When pruning context files goes wrong
Section titled “When pruning context files goes wrong”The rule is still ignored after you shortened the file. Check three things in order. First, did the file load? In Claude Code, a file missing from /context looks exactly like a rule being ignored; in Codex, check the byte budget and whether the project is trusted. Second, does another rule contradict it? The agent may pick either, and no amount of emphasis fixes that. Third, is the rule falsifiable? “Write maintainable code” cannot be followed or broken, so delete it.
You deleted something load-bearing and CI caught it. That is the protocol working, and why step 1 archives rather than deletes. Restore the single line, cite the failure in the log, and leave the rest of its section out.
Codex follows the vague global rules and ignores the precise local ones. That is the 32 KiB cut, not a model regression. Because project files load root first, the nearest and most specific file is the one truncated or skipped. Run the byte-budget script, then move procedures into skills and split the root file.
Auto memory rebuilds what you deleted. Auto memory records your corrections, so weeks after an ablation it can hold the rules you removed, unreviewed. Open /memory whenever you review the main file, or turn auto memory off for the project and curate by hand.
AGENTS.md stopped loading in Claude Code. Someone added a CLAUDE.md or CLAUDE.local.md on the path, which takes precedence under the default setting. Set Project instructions to claude-md-and-agents-md in /config, or put @AGENTS.md at the top of CLAUDE.md; the import also works on builds older than v2.1.277.
The team disagrees about what was cut. Review the log, not the diff. Each restored line needs two dated failures, and the A/B prompt from step 6 settles each disputed cut.