Skip to content

Pruning 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.

  • 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.md hierarchy, unless its definition sets omitClaudeMd: 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.md content 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 sonnet or haiku alias, 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:

  • @path imports 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.md switches AGENTS.md off. Adding one for personal notes in an AGENTS.md-only repository stops Claude from reading AGENTS.md under 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 /status when an instruction file is over the recommended length, and the /doctor checkup (v2.1.206+) proposes trims of content derivable from the codebase, such as directory layouts and dependency lists, in a checked-in CLAUDE.md.

Check what loaded with /context (the Memory files list) and /memory.

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 haveClaude CodeCodexCursor
Rule needed in every sessionCLAUDE.md (or AGENTS.md), under 200 linesroot AGENTS.mdalways-applied rule
Rule for one file type.claude/rules/<topic>.md with pathsnearest AGENTS.md to those files (no glob scoping)rule scoped to a glob
Rule for one package or directorysubdirectory CLAUDE.mdsubdirectory AGENTS.md (AGENTS.override.md to shadow it)scoped rule
Multi-step procedureskill in .claude/skills/<name>/SKILL.mdskill in .agents/skills/<name>/SKILL.mdskill
“Never do X” that must holdPreToolUse or Stop hookhook, or a CI checkhook
Extra guidance for a cheaper modelsubagent definition with its own modelsubagent definitionsubagent definition (check that it can pin a model)
Subagent that gets everything from its delegation promptomitClaudeMd: true in its definition (v2.1.271+), so it stops paying for CLAUDE.md——
Personal preferenceCLAUDE.local.md or ~/.claude/CLAUDE.md~/.codex/AGENTS.mduser rule
Note for human maintainersHTML comment (zero tokens)READMEREADME

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.

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.

  1. 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.md and .claude/rules/. Pause auto memory for the week, or it rewrites what you removed: set "autoMemoryEnabled": false in .claude/settings.local.json, or export CLAUDE_CODE_DISABLE_AUTO_MEMORY=1. Confirm with /context that Memory files holds only what you expect.

  2. 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-audit first (v2.1.283 or later, both release channels on 2026-10-12; it needs bundled skills enabled; pass a path such as .claude/rules to 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.

  3. 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 paths loads 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.

    paths is the only frontmatter field Claude Code reads from a rule. If the YAML does not parse, the rule loads unconditionally; claude --debug shows the parse error.

  4. 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 build rule 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; then
    jq -n '{hookSpecificOutput: {hookEventName: "PreToolUse", permissionDecision: "deny",
    permissionDecisionReason: "Dev server is listening on :3000. Stop it before pnpm build."}}'
    fi
    exit 0

    The 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 in config.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.

  5. Consolidate to one source of truth. Two files that say nearly the same thing drift apart at the rate you edit them. AGENTS.md is 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+ reads AGENTS.md directly. If you need Claude-specific lines, or some sessions run an older version, make @AGENTS.md the first line of CLAUDE.md and 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.

  6. 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.

Pruning is only safe if you can show nothing regressed without rereading every line and every diff. Five checks carry that proof:

  1. 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.
  2. 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.
  3. Loading is confirmed, not assumed. In Claude Code, /context lists the memory files that loaded, and a hook on the InstructionsLoaded event can log which CLAUDE.md and rules files loaded, when and why. An AGENTS.md that Claude Code reads directly (no CLAUDE.md) does not fire InstructionsLoaded; confirm it with /memory, which lists it from v2.1.280. In Codex, run the byte-budget script below.
  4. 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.
  5. Someone owns the file. Put instruction files under CODEOWNERS so the tech lead signs off on every addition, and require a log entry for each one.

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:

codex-agents-budget.sh
#!/usr/bin/env bash
root=$(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")
done
total=0
for 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
done
done
if [ "$total" -gt 32768 ]; then
echo "Over 32 KiB: Codex truncates the file that crosses the line and skips the rest."
fi

It ignores project_doc_fallback_filenames and a raised project_doc_max_bytes; adjust the names and the limit if you set either.

Terminal window
# CI step: fail when any agent instruction file exceeds 200 lines
over=$(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 1
fi

The 200-line figure is Anthropic’s recommendation for a single CLAUDE.md; pick your own number for Codex-only repositories, but pick one.

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.

Where to go next after pruning context files

Section titled “Where to go next after pruning context files”