In March I published the rule I use for keeping AI agent instructions manageable: methodology goes in skills, portable packages of instructions the agent loads when a task matches them, while identity and safety invariants stay in CLAUDE.md, the file the agent loads every session. I recorded my always-loaded file at 136 lines and considered the problem handled. Five months later that same file measured 54,825 bytes against a 55,000-byte hard budget. Full, in other words, at 99.7 percent, with no headroom and no plan.
The separation was right. What I had not published, because I had not yet lived it, is the failure mode built into the always-loaded file’s job description: it grows monotonically. Every incident adds a rule, and no rule ever leaves, because every rule earned its place through something going wrong. My 136 lines had become 465, and most of the growth was not rules. It was teaching. Each rule arrived with its incident story, its worked example, and the rationale that would make a future session take it seriously. All of it loaded every session and was paid for in every context window, whether the session touched that territory or not.
Two responses present themselves, and both fail. Raising the budget defeats its purpose: the budget exists to protect the per-session context window, and a bigger budget is a decision to have the same problem later at a larger size. Trimming rules weakens the system the rules protect: deleting hard-won rules because the file is full amounts to scheduling the repeat of your old incidents. I refused both, which forced a third option. This week I rewrote the file from 54,825 bytes to 21,026 with zero rules weakened, and the mechanism is worth describing because none of it is specific to my setup. If you run a CLAUDE.md, an AGENTS.md, or any always-loaded instruction file for an AI agent, your file is growing the way mine did.
Three things and nothing else
The observation that unlocked the rewrite: most instruction bytes are not instructions. They are teaching material, and teaching material has (or deserves) a canonical home somewhere that loads on demand. The always-loaded file, which I now think of as a kernel in the operating-system sense (the minimal resident core, everything else loaded when needed), keeps exactly three things.
First, always-on invariants: compressed operative rules, one to four lines each, with a pointer to wherever the narrative lives. The kernel keeps the rule text that binds, not the story of why it binds.
Second, a routing table: task shape mapped to skill stack. A writing task loads the writing stack; a mention of a named project loads the project-management stack. This is the one part that must be always-loaded, because it is what makes on-demand loading reliable. A skill that would have prevented a failure is worthless if nothing triggers loading it when the matching task appears.
Third, enforcement declarations: one line each, naming which mechanical check enforces which rule. Where a fail-closed hook (a check that blocks when it cannot run, rather than warning and proceeding) verifiably enforces a rule, the prose only needs to declare that it exists and must never be bypassed.
Everything else moves to the home that canonically owns it: worked examples and procedure detail into skills, mechanical rules into hooks, lookup tables into reference files.
Classify every rule before moving any
I inventoried the file rule by rule; the audit came to 62 rules, and each landed in one of four enforcement classes. Twenty-five belong in the kernel as compressed invariants. Twenty-eight moved into skills, each leaving a trigger behind in the routing table. Six shrank to one-line declarations because a fail-closed hook already enforced them mechanically. Three became reference files loaded on demand.
The class worth dwelling on is the first, because it keeps some rules in the kernel even when a skill or hook home exists. Certain rules fail precisely when enforcement does not engage. A gate against deferring work has to fire in the sessions already drifting toward deferral, and those are exactly the sessions least inclined to load an anti-deferral skill. A never-send rule backed by a hook whose matcher enumerates today’s messaging tools still needs its prose form, because tomorrow’s tool is not in the matcher. Rules like these keep a kernel remnant no matter how good their homes are. Moving them out entirely would weaken them, and the audit has to say so explicitly.
Prove nothing got weaker
“Zero rules weakened” needs an artifact behind it; mine is a migration matrix: every rule, its landing place, its enforcement class, and a verification that the destination actually carries the substance. The discipline that mattered most: verify by opening the named file, not from memory. My from-memory claims were wrong in several places. Rules I was confident lived in a skill existed only as private lesson notes, and one had no home anywhere beyond a session log. Each of those, migrated on trust, would have been a rule silently dropped.
Order is the safety property. Build the homes first and delete nothing: the system runs briefly with duplicated rules, which is safe, where running with orphaned rules is not. Verify the enforcement next: a hook that backstops a rule proves it with a passing health check on every agent runtime before any rule relies on it. Rewrite the kernel last. Then archive the old file, so the matrix can always be audited against the original text.
Give the budget teeth
A budget nothing enforces is a wish. Three properties made mine real. The hard limit refuses: an over-budget kernel does not install. Refusal, not a warning. A warn band signals early: mine now warns at 85 percent, because a gate with only a hard limit reports 99.7 percent full with zero signal, and I know because mine did. And every write path validates: my installer checked the budget, but the hook that propagates source edits to the installed files did not, so an over-budget file could go live through the unvalidated path while the validated one correctly refused the identical content. Two enforcement layers that disagree are one enforcement layer, the weaker one.
The rewrite landed at 21,026 bytes, 38 percent of the budget, so the headroom is structural rather than an accident of the last trim. The kernel runs 122 lines, fewer than the 136 I recorded in March, and it binds five more months of accumulated rules. The difference is compression: operative rule text stays, narrative leaves. One source file generates the kernel for both agent runtimes I use, Claude Code and OpenAI Codex, so the discipline pays for itself twice.
The same architecture at every layer
I have published this shape before, one layer down. The tiered context architecture applies identical reasoning to a project’s working memory: CONTEXT.md carries a 150-line budget, stable facts move to a reference file, history archives monthly, and content leaves the hot file only after it verifiably exists in its destination. That piece called the protocol garbage collection for context, and the name transfers upward. Per-project working memory and cross-project standing rules are both caches with budgets, and a bounded cache with no eviction policy eventually refuses the very rule your next incident needs to add.
The layer above CONTEXT.md took me longer to treat because an instruction file’s contents feel too important to touch. They are important. That is the argument for the architecture, not against it: relocation with verification is how the rules stay strong while the file gets small.
A skill trying to be born
The durable habit underneath all of this is recognizing extraction moments as they happen. The skills catalog itself began that way: the March release converted 67 private runbook files, over 13,000 lines, into portable skills once it was obvious the same methodology kept getting re-explained to every new session. The kernel bloat was the same signal at a different layer, and it took me five months to read it.
So the general lesson, for anyone maintaining an always-loaded instruction file: when you catch yourself pasting the same instructions into prompts again and again, that is a skill trying to be born. When your instruction file is teaching instead of binding, those are skills trying to be born too. Accumulation is the default motion of these files. Extraction is the discipline that keeps them kernels.
I wrote the full pattern up in the open-source skills project, including the enforcement classes, the migration order, and the budget-gate design: the instruction-kernel pattern. My file spent five months growing toward its ceiling before I treated the growth as architecture rather than housekeeping. Yours is growing right now.
