An agent breaks a rule, so you edit the doc. Add a paragraph, note the exception, bold the important part. Repeat a few times and the rules file is 400 lines long.
And the rules get followed less.
The reason is mundane. There's a limit to how much an agent actually holds at once, and inside that limit the rules doc, the files it read, the work done so far, and every tool output all share the same space. Writing a longer document doesn't reinforce a rule — it takes the allocation away from something else.
1. Context Is a Budget, Not a Container
Think of context as "a place to put information" and adding more always looks like a win. Think of it as a budget and the calculus changes.
Grow the rules doc and one of the other four shrinks. Usually it's "what has been done so far" — which is precisely what a long unattended run needs most.
You just can't see what got removed. Which is why rules documents only ever grow.
What reading this repository actually costs
To make the invisible part visible, we priced the files. Token counts vary by tokenizer, so these are order-of-magnitude estimates, not measurements.
Only the first row says always. Everything else is conditional. Yet every line added to the rules file bills every task — the CSS-only ones, the redirect-only ones, all of them.
The last two rows stand out: a single post costs more than the entire rules file. That makes "how many posts fit at once" the real unit of work — and it's why this batch touches exactly one ko/en pair at a time.
2. Always-Loaded vs. Read-on-Demand
So this repo's rules file draws a hard line between two kinds of content.
The test for which side something belongs on: "if work starts without knowing this, is it unrecoverable?"
Write a ko post with no en counterpart and the working method itself is wrong — learning it later means revisiting all eight posts. Whereas the meaning of one front matter field is visible the moment you open an existing post. There's no reason to carry it around in advance.
3. One Example Is Cheaper Than Ten Lines of Explanation
This repo's instructions for writing a new post begin with:
One line — and more accurate than documenting the whole field table. A real file carries field order, quoting, date format, and the classes used in the body all together. Transcribe that into prose and something always goes missing.
An example also only occupies space when it's needed. Put the field table in the rules doc and it rides along during tasks that touch no posts at all. "Copy an existing post" keeps the instruction always loaded and the content loaded on demand.
4. Keep State in the Repo, Not in the Conversation
The most expensive item is "what has been done so far," and it grows without bound as a task runs.
So content work in this repo keeps its progress in a single file.
Three lines fully express the current state of an eight-post job. Knowing what's finished and what's left requires no replay of earlier work.
There are two payoffs. Resumability is one; the other is the context saved. State kept outside doesn't need space to be remembered.
5. Where Summarization Costs You
In a long run, earlier context gets compacted. What matters then is which things survive compression well and which don't.
The bottom three share one property: they need exact values. "Dates have to match" surviving as a gist is useless once "September 16" has gone fuzzy.
So those values get re-read from a file rather than recalled. Open the queue and the exact values are still there. The working principle: store what must be exact, and leave only the gist to memory.
Build an index instead of a summary
There's a step past that. If compression loses information, the better move is never having anything to compress.
Choosing which posts to enrich means looking at all 27. Opening them costs this:
Two hundred times cheaper — and only the four selected posts get opened. The distinction between index and summary matters here: a summary requires reading the originals first, while an index is built from filenames and a few leading lines.
The general form: any "survey everything, then pick a few" step can become an index. Decide which fields the picking actually needs, and read the rest afterward. Here that was three fields — size, date, slug.
What to drop first when you have to drop something
Sometimes it overflows anyway. Deciding the eviction order in advance beats improvising it under pressure.
Item two is bigger than it looks. Full build output runs to hundreds of lines, while what's actually needed is pass/fail plus a few error lines on failure. Output from a successful command is nearly always safe to drop.
The second "never dropped" line, on the other hand, gets discarded constantly. Lose the failed attempts and you walk into the same failure again. Failures deserve to outlive successes.
6. Move Verification Out of Context Entirely
One more angle: verification barely costs context at all.
Enforcing "check that ko and en dates match" as a rule requires the rule to stay loaded — and it can still be missed. Let the build check it and the rule doesn't need to be loaded at all; when it's violated, an error message arrives with exactly as much detail as the moment requires.
Seen this way, adding a guard is not only a safety measure but a context optimization. Every enforceable rule you move into code is a rule you no longer document.
7. How to Actually Shrink the Document
What worked when the rules file got long:
- Move enforceable rules into code and delete them from the doc. Anything the build checks collapses into one line — "the build catches this."
- Replace explanations with a pointer to an example. Ten lines of "field X means…" becomes "copy an existing post."
- Only elaborate rules that have actually been broken. Rules nobody ever violated don't get expanded — and they're usually the longest ones in the file.
- Never say the same thing in two places. If a doc and a code comment explain the same rule, keep one.
The third one paid off most. A rules document is a record of what once felt scary, so the word count rarely matches the real failure rate.
Symptoms of a Tight Budget
Running short on context doesn't surface as an error. It surfaces as work degrading in specific, recognizable ways — and each symptom has its own cause, so each has its own fix.
Rows one and four look similar and aren't. Asking again is the healthy signal — it means the gap is known. Confidently producing a contradictory conclusion is far worse, because nothing marks the spot where the reasoning went fuzzy.
The last row is about the instruction, not the rules file. Several short instructions were followed more reliably than one long one, for the same reason rules files fail: length doesn't function as emphasis.
Frequently Asked Questions
Context windows keep growing — doesn't this problem go away?
Capacity grows; the ordering problem stays. The losses we actually hit were far more often "it was in there and went fuzzy" than "it didn't fit." And as capacity rises, so does what gets loaded — the rules file didn't reach 400 lines because the window was small. Choosing is a separate problem from fitting.
How long should a rules file be?
Filter on "is this always true?" rather than line count. A single paragraph that's only true during one kind of task is misplaced regardless of the file's length. This repo's rules file is 10KB, but half of that is tables and examples — the rules themselves are much shorter.
Is it better to read part of a file or all of it?
Partial when you know what you're looking for, whole when you don't. When it's unclear, narrow by search first, then read around the hits. Same shape as the index idea above: separate the narrowing step from the reading step.
Why not just ask for a summary along the way?
It helps, but a summary is still lossy. What to keep is decided at summarization time, and what turns out to matter later is usually whatever looked trivial then. So summaries serve as a supplement, while values that must be exact get written to a file regardless.
Does moving things into a skill save context?
Yes — that's one of the real benefits of skills. A procedure needed by one task costs every task from the rules file, and only that task from a skill. Think of it as a way to move a row in the table above from "always" to conditional.
What changes for unattended runs?
Nobody is there, so "just ask again" stops being a recovery path. Keeping state in files goes from preference to precondition. Add explicit stopping conditions on top and the run can end before it enters the range where a tight budget starts degrading the work.
8. Summary
- Context is a budget, not a container. Adding to the doc subtracts from something else.
- Only preload what's unrecoverable if unknown. The rest is one file open away.
- Point at an example instead of explaining. Instruction always, content on demand.
- Keep progress in the repository. Holding it in memory costs space continuously.
- Store the values that must be exact and re-read them. Summaries keep gist, not values.
- Turn enforceable rules into guards. Their steady-state cost drops to zero.
When a rule isn't being followed, writing more about it usually solves the problem backwards. The question isn't "how do I explain this better" but "can this leave the document at all?" Moved into code, replaced by an example, or exported to a file — the rules that get followed best are the ones no longer written down.