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.

competing for the same space in one run: rules and conventions source files that were read what has been done so far (turns, tool calls) build output and error messages the work product being written right now

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.

Every decision to add to the document is a decision to remove something else.

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.

File Size ~Tokens Loaded when ───────────────────────────────────────────────────────────── CLAUDE.md (rules) 10.0KB ~6,000 always eleventy.config.mjs 4.5KB ~1,500 changing the build posts.css 5.5KB ~1,500 touching styles layouts/post.njk 1.5KB ~500 changing the layout partials/head.njk 2.0KB ~700 changing meta tags vercel.json 1.5KB ~500 moving a path _data/staticPages.js 0.9KB ~300 adding a page ───────────────────────────────────────────────────────────── one post (ko, enriched) ~16KB ~9,000 editing that post .content-queue.md 19.6KB ~11,000 checking batch state

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.

must be known up front — get it wrong and the first commit is wrong posts are always created as a ko/en pair both files must carry the same date post bodies are HTML, not markdown post styling lives in the shared posts.css fine to look up — it's right there in the file what each front matter field means what the layout generates automatically the full list of redirect rules

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:

Copy an existing post and fill in the front matter.

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.

| # | date | cat | slug | topic | done | | 1 | 2026-09-11 | A | url-migration-redirects | ... | [x] | | 2 | 2026-09-14 | B | unattended-agent-guardrails | ... | [x] | | 3 | 2026-09-16 | C | lifting-gear-belt-straps-guide | ... | [ ] |

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.

fine to compress: "wrote three posts, build passed" files read while exploring and never used attempts that failed and were fixed not fine to compress: the exact slug and date of posts not yet written the constraint that ko and en dates must match the list of topics already covered (the dedup basis)

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:

read everything 27 posts × ~12KB avg = ~320KB ~180,000 tokens → doesn't fit, and if it did it evicts everything else index only slug · date · title · file size 27 lines × ~60 chars = ~1.6KB ~900 tokens → enough to pick the four smallest

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.

1. files read while exploring but never used — re-read if needed 2. full output of successful commands — "it passed" suffices 3. details of work already committed — the repo holds the result 4. rules paragraphs unrelated to this task — candidates to make conditional ────────────────────────────────────────────────────────────── never dropped exact values for unfinished items (slugs, dates) failed attempts and why they failed — you'll repeat them decisions made this run, with reasons — later work contradicts them

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.

as a rule: always loaded + still missable as a guard: zero most of the time + a few lines when wrong

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.

Symptom Actual cause Fix ────────────────────────────────────────────────────────────── Re-asks something already state lives only move state into settled earlier in the conversation a file Follows the rules early, the rule blurred move enforceable breaks them late during compaction ones into guards Re-reads the same file what was read got keep an index, over and over evicted open on demand A later conclusion contra- the reasoning was write decisions and dicts an earlier one compressed away reasons to a file Carries out half of an the instruction ran split it into instruction long; the tail sank ordered steps

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.