Agents on a budget — the token overrun and the rules it produced
A 150 M-token, 33-minute overrun, traced to a 468 KB auto-loaded instruction payload. First-call context cut 77 % the same day. Three incidents in ten days, each fixed with prose, then a hook that blocks instead.
1 · Context and constraint
A verification stage of the FrameProof pipeline (layer V4) was being run as a multi-agent job inside an AI coding harness: an orchestrating session, a truth builder and up to nine reader sub-agents, each reading a batch of screen frames and writing structured JSON. The harness bills by tokens processed and meters usage against a five-hour and a weekly allowance.
| Constraint | What it forced |
|---|---|
| Metered usage, two windows. A five-hour cap and a weekly cap, visible to the person but not to the running session | The session cannot check its own bill. Any rule phrased as "check the usage bar" is unenforceable from inside |
Instruction files are context. The harness loads the project's CLAUDE.md and every file under .claude/rules/ into the main session and into every sub-agent, on every call | Whatever is filed as a rule is paid for on every turn by every agent. The project believed the opposite, and had written that belief into its charter |
| Cache-read amplification. A payload is not billed once; it is re-read on every later turn of the session. Measured on a sister project: 133× mean, 364× peak | Size matters more than call count, and timing matters as much as size. A large file loaded on turn one is the most expensive thing a session can do |
| The work was real. The V4 layer found 9 to 10 genuine corrections per day on the two days measured | Stopping the work was not the fix. The fix had to make the same work affordable |
How the fixed tax compounds. One payload, loaded into every agent on every call, then re-read on every later turn:
2 · Problem
Three sessions in a row ended on the harness's "You've hit your session limit": 28 September, 29 September morning, 29 September afternoon. The third processed about 150 M tokens in 33 minutes: 17.6 M in the main thread and 132 M across nine sub-agents. The weekly allowance was being consumed by one verification stage of one project.
The project had rules for exactly this. It had a 312 KB economics file with a calibration table of what every work shape cost. It had a rule to file each lesson "in the rule file that matches when it is needed". The rules did not help, and the question the page is about is why a documented, measured, rule-following project burned its budget anyway, and what kind of fix holds.
What made the problem a product problem rather than a bug: the figure everyone was watching was the wrong one. The harness's agent map shows a "tokens" figure per agent. For the costliest reader it showed 389.8 k. That is the agent's final context size. The reader had actually processed 35.4 M. Every budget in the calibration table had been read off the same kind of figure, so sub-agent cost had never once been measured.
3 · My role
Sole owner of the harness and its rules: the diagnosis, the measurement scripts, the rule changes, the hook, and the decision on each of three days about what to enforce and what to leave as guidance. The same person was the customer of the fix, since the allowance being spent was mine.
The thinking carried across projects. The cross-project rule it produced is now the first section of my user-level harness configuration, applied to every project, and was used seventeen days later to cut a client repository's auto-loaded payload from about 165 KB to about 25 KB. On a second product of my own, MyWarren, the same cap took the payload from 135.4 KB to 59,099 B.
4 · Decision and trade-off
The decision: stop fixing cost with prose, and enforce it with measurement and a hook. It took three incidents to reach that decision, and the page is honest about the sequence, because the sequence is the lesson.
Incident 1, 29 September. Root cause: the file meant to control cost had become the cost. The auto-loaded instruction payload had grown to 468 KB, of which one economics file was 312 KB under an "extend it, never delete a row" rule. The context on each session's first call, before a word of work:
| Date | Main session | Sub-agent |
|---|---|---|
| 31 August | 46 k | 39 k |
| 16 September (the "split") | 85 k | — |
| 21 September | 140 k | — |
| 26 September | 201 k | — |
| 29 September | 252 k | 241 k |
The 16 September "split" moved text between files and reduced nothing, because the moved text was still auto-loaded. Two further causes compounded it: the reader prompt had been changed, without re-measuring, from "read each image once, about five fields" to seventeen fields plus a crop-and-zoom loop, taking each reader from 7–14 calls to 22–106 and the sub-agent total from about 27–37 M to 112–132 M; and nine agents ran in one window with nothing checkpointed, so when the limit hit, two readers lost everything they had read.
The fix the same day: move the six rule files out of the auto-loaded folder; split the economics file into a 7 KB digest and a grep-only archive; readers back to one read per image, JSON written every ten frames, never more than three concurrent; a session-start hook that prints the instruction payload's size and warns above 60 KB; and a script that computes real spend from the transcript instead of the agent map. Measured on the next session: first-call context 256,372 → 59,730 tokens, −77 %.
Incident 2, 6 October. The rules were followed in spirit and broken in letter. A background orchestrator spawned six concurrent readers where the charter said three, and wrote 33 one-off probe scripts in a probe-diagnose-reprobe loop. It was stopped and reverted: about 60 M tokens processed and entirely discarded. The fix: a per-agent token band table (text reader about 150 k, visual pass about 250 k, verification layer about 350 k, above 550 k is a stuck loop), the concurrency cap stated inside each task prompt rather than trusted to the charter, and the orchestrator told to check on long-running agents itself. The capped relaunch worked first time: parent 167 k tokens in 55 calls, exactly three readers at 155 k, 158 k and 165 k, no probe scripts.
Incident 3, 7 October. Every rule obeyed, and still 24 M. The next session kept every agent inside its band, never ran more than three at once, and cost about 24 M tokens, of which the uncapped orchestrator was 11.5 M. The weekly bar moved from 25 % to 40 %. This was not a runaway; the previous day's equivalent session cost 23 M. It was the recipe's normal price, and the per-agent rules had nothing to say about it. Eleven remaining days at that price would cost about two full weekly allowances.
The reframe that came out of incident 3. Per-agent caps stop a stuck loop. They do not cap a session, and the orchestrator, which no rule covered, was half the bill. More importantly: three incidents had each been fixed by adding prose to a rules file, and each time the next session followed the prose and found a different way to be expensive. A rule a session cannot check is not a rule. "Check the usage bar before a second wave" depends on something the session cannot see, so it was never checked.
The option rejected: a fourth paragraph of guidance. Instead, three changes, signed off on 9 October:
| Change | What it is | Where it lives |
|---|---|---|
| Slim the recipe | One full reader wave by the model that passed the gate; the second model reads only the frames the truth set flags, roughly a third of them. Safe because on the prior three days the corrections came overwhelmingly from flagged frames, and the unflagged ones were 600-plus rows the second reader only re-confirmed | The verification rules, as a mandatory recipe |
| A declared per-session budget | Declared before starting as processed tokens (session A ≤ 14 M, session B ≤ 6 M); measured at each wave boundary by the session itself in about a second; if the projection exceeds it, stop and ask | A budget script that shares its arithmetic with the spend script, checked to the thousand on two sessions |
| A harness hook | Fires before every agent launch: blocks past a hard line of 16 M and asks the person; warns past 10 M. Plus a notify-only check after every tool call, once per line crossed, because a session with no agents would otherwise have no enforcement at all. The ceilings live in one settings value; a declared budget can only tighten them | The harness's pre-tool and post-tool hooks |
What the hook does at every agent launch:
Why a hook and not a rule. A hook fires whether or not the session read the rules, and that unread-or-misread rule is the failure mode all three incidents share. The trade-off accepted: a hook can stop the wrong thing, which is why the hard line asks the person rather than killing the session, and why the post-tool check only notifies.
5 · What shipped
- A cross-project rule, at user level, applied to every project before any project file loads:
.claude/rules/is auto-loaded and paid on every call by every agent;CLAUDE.mdplus rules ≤ 60 KB per project; no append-only log in an auto-loaded file; at most three background agents at once; sub-agents write results incrementally; measure spend from the transcript, never from the agent map. A "read this WHEN" table inCLAUDE.mdis the pattern for on-demand reference. - Two measurement scripts: real spend per session (cache write + cache read + output, summed across the session and its sub-agents) and a first-call baseline per session, so growth in the fixed tax is visible the day it starts.
- A session-start size hook that prints the instruction payload's bytes and warns above 60 KB.
- A per-agent token band table and the rule that a task prompt states its own concurrency cap.
- A declared-budget script and a pre-launch budget hook, with the hard and warn lines in one settings value.
- A corrected calibration archive, whose header flags every sub-agent row recorded before 29 September as an agent-map figure, not a measurement.
- The second application. On 16 October the same rule was applied to a client's product repository: a 123 KB progress file split into a short snapshot plus two on-demand files, a UI-only rules file moved out of the auto-loaded folder, and a read-on-demand table added; auto-loaded payload about 165 KB → about 25 KB.
- The third application. The same 60 KB cap, written into a second product's delivery SOP as its economics rule: auto-loaded payload 135.4 KB → 59,099 B, just inside the budget rather than far under it (MyWarren).
6 · Measured result
| Measure | Before | After | Source |
|---|---|---|---|
| Auto-loaded instruction payload, the FrameProof build | 468 KB | CLAUDE.md 26 KB, no .claude/rules/ folder | RCA 29 Sep, fix log |
| Largest single rule file | 312 KB | about 7 KB digest; the table archived, grep-only | RCA 29 Sep |
| First-call context, main session | 256,372 tokens | 59,730 tokens, −77 % | baseline script, 29 Sep, verified same day |
| Calls per reader | 22–106 | back to the 7–14 shape | RCA 29 Sep |
| Capped relaunch, 6 Oct | first attempt: ~60 M, discarded | parent 167 k in 55 calls; three readers at 155 k / 158 k / 165 k | RCA 6 Oct |
| Full session, rules obeyed, 7 Oct | — | ≈ 24 M, orchestrator 11.5 M | cost proposal |
| Slim-recipe estimate for the same session | 24 M | 12–14 M (estimate, in the proposal) | cost proposal |
| Client repository, 16 Oct | ~165 KB auto-loaded | ~25 KB | decisions log |
| Second product (MyWarren) | 135.4 KB auto-loaded | 59,099 B, against 60 KB | MyWarren |
What the measurements do not prove, stated. The 29 September cut is measured; the slim-recipe saving is a projection in the signed-off proposal, and the first session measured under the hook, against its 14 M declaration, is not yet in the record. Second, the spend figure the project measures is processed tokens, which counts every cache read. Cache reads are billed well below input-token rates, so the figure is a conservative proxy for money, not money; the proposal records this as open. Third, the same multi-agent pipeline, counted across every leg, totalled about 131 M processed tokens in one lifetime even with the caps working, because each sub-agent's amplification is counted independently and none of it nets against a shared cache. Whether running a verification stage as five delegated agents is itself the expensive shape, compared with fewer larger agents or inline work, is a question the project has written down and not yet answered.
The three failure modes, named. A fixed tax that grows a little every session and is paid by every agent on every call. A prompt changed without re-measuring, so a reader's call count rose six to ten times. An orchestrator that no rule covered, so obeying every rule still cost half the weekly allowance.
7 · What was deliberately not built
- A hook that polices every project. The size hook and the budget hook live in the project where the incidents happened. Other projects carry the 60 KB rule as prose in the user-level file and were brought under budget by hand, one of them on 16 October. The condition that flips it: a second overrun in a project that has only the prose. Since written (2026-10-18): that condition has not fired, but the session-start size hook was copied on 2026-10-17, with two other hooks, from another project's harness into this site's own repository (How I build · The harness). The budget hook was not copied.
- A pipeline-level ceiling in the band table. Proposed as an open question on 6 October; answered instead by the per-session declared budget on 9 October, which caps the sum rather than adding a third table.
- A watchdog on background agents. Whether an orchestrator should be warned when a background agent crosses, say, 20 M processed tokens without reporting is written down as open. The prompt-level fix held on its first measured use, so the watchdog waits for evidence that it does not.
- A dollar-cost model. Processed tokens are the project's unit because the harness reports them exactly and a script can check them in a second. Converting to money needs vendor cache pricing, which changes, so the budget is declared in tokens and the conversion stays a note.
- Killing a session at the hard line. The hook asks the person instead. Three incidents were enough to show that the harness cannot see what the person can, and the reverse is also true.
- Stopping the verification layer. It was the expensive stage and it found real corrections on each day measured. The proposal ends with the product question rather than a guardrail: run the slim recipe on every remaining day, or rank the days by their earlier error counts and run the heavy layer on the top half. That decision belongs to the owner, not the hook.
The honest shape of the work, volunteered. The charter said the rule files were not auto-loaded, and every lesson had been filed on that premise for a month. The proof that it was wrong was in the session's own context the whole time; nobody had looked. The second incident broke a cap the charter already stated. The third obeyed every cap and was still expensive. None of this is unusual in agent operations, and that is the point of telling it: the rules that survive are the ones a machine can check.
8 · Assets
| Asset | Status |
|---|---|
| The cross-project rule, as it appears at user level | described, not reproduced, on How I build · The harness |
| The three-incident timeline (29 Sep, 6 Oct, 7–9 Oct) with the before/after table from §6 | public, this page |
| The spend script and the baseline script | not published; they read local transcript files |
| The size hook and the budget hook | not published; the size hook's design is described on How I build · The harness |
| The two root-cause analyses and the cost proposal, verbatim | not published; they name the project's internal files, day numbers and the model names used |
| The client repository's decisions-log entry | not published; referred to as "a client's product repository" |
| The mechanism section of the token rules (the amplification identity and the ranked cost sources) | not published; the mechanism is described on How I build · The harness |
Related. FrameProof, the build this happened on. This site, which keeps the same 60 KB budget. MyWarren, where the same cap was applied as 135.4 KB → 59,099 B. The harness, the method this incident hardened, and How I build · The harness, where the rules and hooks are described; this case study anchors the How I build pages.