CodeHerderSearch⌘KRequest access →

Optimise the file every agent reads before doing anything

Every coding agent reads a house-rules file before it does anything. Claude Code calls it CLAUDE.md. It holds the things you’d tell a new engineer on day one: how to run the tests, which patterns this repo prefers, the mistake everyone makes once.

Ours grew from 6KB to 231KB in under a month: 33x in ten days, across roughly 37 agent-authored commits. Nobody decided that. Our own agents wrote it, and every one of them was right to: each addition was a real lesson from a real incident, landing as an accurate diff that a reviewer had no reason to reject.

Keeping that file small is obvious best practice. We knew it when the file was 6KB and we knew it at 231KB. That is exactly what makes this worth writing up.

We build CodeHerder by running CodeHerder: this product is developed almost entirely hands-off by agents on our own platform, and part of the point is to find where that breaks. This is one of those places. A human maintainer would have looked at a 200KB house-rules file and flinched. A herd of agents, each landing one correct paragraph about one real incident, never did — because common sense is not a constraint an agent reliably applies to a diff that is, in isolation, entirely defensible.

Nothing in the loop could see that the file had a cost. So it grew until we measured it.

Then we split it: a 23KB index of one-line rules, with the reasoning moved into a skill that agents load only when they need it. Because CodeHerder records every API call against a task, a stage and a model, we could measure exactly what that did. And because we run the same platform across several repos, we had something better than a before-and-after: a control group.

What the numbers did

Cost per Claude turn, in the repo we changed versus every other repo on the same herd, same days, same models:

CodeHerder (changed) Other repos (untouched)
08-08 → 08-11 $0.0877 $0.0632
08-13 → 08-15 $0.0633 $0.0668

The changed repo fell 28%. The untouched repos drifted slightly up over the same window. That gap is the whole finding: an API-side price change or a model swap would have moved both columns together. Only one column moved, and it’s the one where we edited a single file.

The mechanism is visible one layer down, in cached input tokens per turn:

CodeHerder Other repos
before 237,080 138,770
after 139,243 134,000

Before the split, every turn in that repo carried roughly 98,000 extra tokens of house rules. After it, the repo sits exactly where its siblings do. We hadn’t been paying for a bigger codebase or a harder problem. We’d been paying to re-read our own documentation, on every turn, forever.

The part we didn’t expect

Cheaper turns were the obvious prize. The better result was fewer of them.

Turns per completed task, same repo:

turns per task
08-11 (peak file size) 499
08-15 (after the split) 320

A third fewer turns to finish the same class of work. We can’t prove the causal chain as tightly as we can prove the cost one, but the reading that fits the data is simple: 231KB of rules is not more guidance than 23KB, it’s less usable guidance. The signal an agent actually needs (this repo wraps errors this way, that gate is load-bearing) was in there the whole time, buried under the history of why.

Two things make us confident the saving is real rather than an artifact:

  • The expensive model got more use, not less. Opus went from 35% of turns before the split to 46% after. Cost per turn fell anyway, so if anything the measurement understates the effect.
  • Output tokens per turn stayed flat at roughly 480. The agents didn’t start doing less work or writing shorter answers. They just stopped hauling the encyclopedia around.

At our volume (around 50,000 turns a day in that one repo) $0.024 per turn is about $1,200 a day. From deleting nothing: every rule still exists, it just moved somewhere agents can reach it when it’s relevant instead of paying for it when it isn’t.

How that lands depends on how you buy capacity, and both versions hurt. On API billing it is money, straightforwardly: $1,200 a day of tokens spent re-reading your own documentation.

On a subscription it is worse in a way that’s easy to miss, because no invoice changes. You are burning rate limits far faster than the work requires. Every one of those 98,000 wasted tokens counts against your 5-hour and 7-day windows, so you hit the ceiling sooner, your agents stall, and the throughput you already paid for simply isn’t there. We run mostly on subscriptions, and capacity exhaustion has been a genuine operational constraint for us. A share of it was self-inflicted by this one file.

The shape of the fix

The split is boring, which is the point:

The file became an index

One line per rule: what the rule is, the name of the test that enforces it, and how to opt out if you legitimately need to. No history, no measured evidence, no war stories. If a rule takes a paragraph to state, the paragraph goes elsewhere and the line points at it.

The reasoning became a skill

Rationale, the defect each rule replaced, the counts of sites fixed, the incident that produced it: all of it kept, none of it deleted, loaded on demand by an agent that has a reason to care.

Four tests now hold the line, and this is the part that actually matters. Splitting the file was a one-afternoon job; keeping it split is the hard problem, because the same agents that grew it the first time are still working, still learning, still right to write things down.

So the constraint is mechanical:

  • TestClaudeMdSizeBudget fails the build when the index passes its byte budget. Raising that budget requires a human signing off in the merge request, and the guard’s failure message says so. An agent that hits the ceiling cannot quietly lift it.
  • TestClaudeMdIsAnIndexNotAChangelog rejects the specific shape the growth took: bullets narrating instalment numbers, task IDs, before/after counts and admission tables inline. That was the actual failure mode, so it gets its own guard.
  • TestConventionsSkillExists makes sure the overflow has somewhere to go. A size limit with no destination just turns into pressure to delete real knowledge.
  • TestClaudeMdDocumentsItsOwnBudget requires the file to explain its own rule, so the next agent to touch it reads the constraint before hitting it rather than after.

We could have written “keep this file short” in the file. We had, in effect. It doesn’t work: a convention an agent can satisfy by believing it is following it is not a constraint. A failing test is the only reviewer that reliably notices, and it’s the only feedback that arrives before the merge instead of on next month’s bill.

The same argument applies one level up: our dispatch brief has a 9,000-byte budget for exactly the same reason. Anything injected into every session needs a number attached to it and a test holding that number.

What to take from this

If you run coding agents, you have a file like ours, and it is almost certainly bigger than you think. Three things worth doing this week:

Measure it, don’t estimate it

Cached input tokens per turn is the number. If your agent platform doesn’t attribute API calls to tasks and stages, that’s the gap to close first. We could only find this because every turn was already attributed, and we could only prove it because we had untouched repos to compare against.

Split by “when is this needed?”, not by topic

The index carries what applies to every task. Everything conditional (the why, the history, the deep reference) moves behind a load-on-demand boundary. Agents are good at fetching what they need; they’re not good at ignoring what they don’t.

Put a budget on it, especially if agents can write to it

Context bloat has no natural predator. Each addition is individually justified, the cost is invisible at review time, and the bill arrives spread thinly across every turn of every task. Give the file a number and a test that fails when it’s exceeded, then let agents keep writing everything down, just somewhere the budget can absorb it.

The lesson isn’t “keep your context files small” — everyone already knows that. It’s that in hands-off agentic development, knowing it isn’t enough. Agents will grow any file they’re allowed to grow, one reasonable commit at a time, and the cost shows up somewhere you aren’t looking: on an invoice, or in rate limits you thought you had headroom in.

So put a number on every file that gets injected into every session, and put a test behind the number. That is the whole lesson, and on our herd it was worth more than any prompt we have tuned.


This is the same instrumentation behind the $7.54 median story and the model-name cost lever — every API call attributed to a task, a stage and a model, which is what makes questions like this answerable at all.

← Back to Insights
CodeHerder

Round up your herd.

Bring every human and every agent onto one table. Watch the work move. Costs update as it happens.

Try "pricing", "connect a device", or "who reviews the code"

↑↓ move · ↵ open · esc close