My Workflow Did Not Follow Its Own Rules
Feels expensive
10/25/2026
•11 min readNote on the Content
This series describes my insights from using AI in the software development process. These are personal experiences and conclusions from which I derived measures that worked for my projects. The series does not claim to be a comprehensive guide or universally valid — it is meant as inspiration for your own projects.
In early October my agent workflow was running in several projects, and it was running well. It was just expensive: I regularly hit my subscription limit. The core of the workflow lives in its own template repository, reaches the projects through an update and therefore has version numbers. At the time it was version 1.5.2.
An external analysis of my blog post brought three studies into play. I cite two of them in Part 1: context files cost more and do not raise the success rate on average, and among the individually tested rules only prohibitions helped. The third examined how repositories on GitHub configure their coding agents: context files dominate, and only a few use skills and subagents (Galster et al. 2026). My setup was one of those few, and it was expensive without my being able to say why.
"Feels expensive" is not a diagnosis. So the analysis turned into an audit brief.
Looking Back at Part 1
In Part 1 I split my workflow into three layers: a core that stays the same in every project, an adapter per stack and the content of the project. The second dividing line concerns how knowledge reaches the agent: as a rule that every agent loads at startup, as a skill that only certain roles preload, or as a script that checks outside the context. I call the context in the first turn the base load for the main session and the startup load for a subagent. This part shows how far my setup was from that second dividing line in October and how I changed that. The result up front: in the template the base load dropped by 84% and the startup load per run by 47%. In the real project the gain was smaller, because the adapters there are large.
Measure Before You Cut
I wanted to know which file loads into the context and how often. An audit must not change anything while doing so, otherwise it ends up checking its own repairs.
So I wrote the brief as a file instead of a chat message. It has 412 lines, is
versioned and can be repeated and reviewed. The file deliberately sits outside
.claude/ and is not imported anywhere. Otherwise it would load into every
session and distort exactly the token budget it is meant to measure.
The brief has three goals: correctness, alignment with Anthropic's
recommendations and token efficiency. Hard rules come on top. The audit is
read-only, and the only write operation is the report. Every finding needs
evidence as file:line or as a command with its output. And the audit keeps
token discipline itself: an inventory first, every file read in full at most
once, at most three subagents. As a reference, the session got a table "What
loads into the context when" covering CLAUDE.md, rules with and without
paths:, skills, subagents, memory, hooks and MCP. Points I was unsure about
carried the marker [VERIFY] and had to be checked against the documentation.
I started the audit in a fresh session:
claude --model claude-opus-5-5 --effort high
> Lies audit/SETUP_AUDIT_PROMPT.md vollständig und führe den Auftrag aus.
The session took inventory first: claude --version, git ls-files on the
configuration paths, wc -lc per file. It estimated tokens roughly as
characters ÷ 4 and always labelled them that way in the report. A small Python
script read the frontmatter of all agents and skills. Not a single agent used
the skills: field to preload knowledge. Then the session evaluated the
"Required Reading" of every agent, meaning the files an agent is supposed to
read before it starts work according to its description. The documentation
questions went, bundled into two requests, to the built-in subagent
claude-code-guide, which is made for Claude Code questions and runs on a
cheap model.
The report from early October had 23 findings and the verdict "well crafted", with two major weaknesses. The first was the base load. None of the twelve rules had a path binding, so all of them loaded in the main session and in every subagent, about 17,500 tokens in total. Almost every agent read them a second time through its Required Reading. A feature run used about 312,000 tokens just for starting the agents, about 80,000 of them duplicates. This was measured in the template with empty adapters: agent startup only, workflow configuration only, characters ÷ 4. A run here is an assumed feature run with a fixed number of agent invocations, from the requirement to the code review. "Empty adapters" means: only what the workflow itself brings along is counted, without any project content.
Everything a single agent needed, every agent got, and most of them got it twice.
The second major weakness was the Flutter coupling I describe in Part 1. On top of that came gaps in enforcement. Both belong in other posts of this series: the coupling in the post about the adapter as a verifiable contract, the enforcement in the one about prohibitions as a mechanism.
Try It Yourself
- Create the audit brief as a file outside
.claude/, with a read-only rule and mandatory evidence. - Include a table "What loads when" based on the current documentation and mark the points you are unsure about.
- Compare the Required Reading of every agent with the rules that are always loaded: what sits in the context twice?
- Run it in a fresh session with high effort and have only a short verdict, the five most important findings and the path to the report returned in the chat.
Rebuilding Without Losing Knowledge
Fixing 23 findings in one go is the surest way to lose knowledge. An agent that is supposed to clean up will happily also delete what another agent needs. The second brief, again a file, therefore set an order of priority:
- Keep quality: no agent loses knowledge, no enforcement gets weaker.
- Fix the findings.
- Make migrating existing projects possible.
In a conflict the higher goal wins, so keeping quality takes precedence over fixing the findings, and the conflict is recorded.
I would recommend the hard rules that came with it to anyone. No line is deleted unless it is moved, is a duplicate, or the answer to the question "Would removing this lead to mistakes?" is no. When in doubt, it stays. Anthropic's best practices recommend the same test question for every line of a CLAUDE.md. Every finding is checked again against the current state before the change, because the audit referred to an older commit. A progress file acts as memory: every session reads it first, and that way the state of the work survives session switches and context compaction.
Before any file changed, I had two measuring tools built. measure-context.py
estimates the base load of the main session, the startup load per agent,
the duplicates and the total per pipeline run. check-knowledge-reach.py
checks whether every piece of knowledge still has a reader after the rebuild and
finds dead references such as "see section 9" pointing to sections that do not
exist. The baseline: 23,162 tokens of base load (the rules plus everything
else the main session loads at startup), 311,804 per run, 10 dead references.
Then came the documentation. The external analysis had suggested binding rules
to file paths with paths:. That was also my plan for the styling rules. The
documentation on rules says: "A
path-scoped rule loads when Claude uses the Read, Write, or Edit tool on a
matching file." Whether and when a path rule loads in a subagent was not
documented at the time of the audit, though, and almost all my agents run as
subagents. Preloading skills with skills: in
the frontmatter of a subagent, on the other hand, is documented, and whether it
takes effect can be checked in the transcript. That ruled out paths:.
Before the rebuild I had a knowledge map drawn up: a table of all rules, listing for each rule the agents that read it (with evidence), the target form, the new location and the risk. Three target forms were possible: rule, preloaded skill, or a skill that an agent invokes explicitly. I approved the table before a single file was moved. Three decisions came out of it:
- Only what everyone needs stays a rule. Only
project-context.mdmet that. - A tiny new rule,
workflow-index.md, with about 300 tokens: a table "situation → skill". The decision whether a change takes the short path for small things or the full sequence with all agents is made in the main session, before any skill runs. Without the index this step would be skipped silently. - Preloading with
skills:replacespaths:.
The implementation came in packages, and every package went through the workflow itself: the solution architect wrote concept and plan, a reviewer agent checked them, I approved, the implementation agent (the developer from Part 1) implemented step by step, the code reviewer checked the branch, and I merged. For the context load that meant:
- Eleven of the twelve rules became skills. Each agent uses
skills:to preload only the ones it needs, for example the coding guidelines for the implementation agent. - The Required Reading lists only project documents such as the use case or the concept, and no rule files anymore.
- Three agents that do not research code start with
omitClaudeMdand therefore without the CLAUDE.md. - I deleted long lists of positive style directives.
Something I found during preparation forced a package of its own: if you move
adapter files to .claude/skills/, the manifest of the update mechanism,
meaning the list of core files an update may overwrite, classifies them as core, and an update would overwrite filled-in adapters. How
I solved that belongs to the adapter contract.
I verified the result in two ways. Automatically, more than 600 tests (unit,
update, guard and migration tests) ran against the real 1.5.2 baseline, plus check-knowledge-reach.py with zero errors. And live in fresh
sessions: the preloaded skills arrived, and omitClaudeMd took effect. Two
days after the report this shipped as version 2.0.0.
Try It Yourself
- Set an order of priority for the goals, with "keep quality" at the top.
- Build the measuring tools and take a baseline first, then make changes.
- Approve a knowledge map before the rebuild: who reads what, and where does it move?
- Rehearse every change live in a fresh session instead of only running the tests.
What the Rebuild Achieved in the Template
| Template, ≈ tokens | 1.5.2 | 2.0.0 | Change |
|---|---|---|---|
| Base load, main session | 23,162 | 3,821 | −84% |
| Startup load per pipeline run | 311,804 | 165,777 | −47% |
| of which duplicates | 80,527 | 19,809 | −75% |
Measured with measure-context.py on both release states: template with empty
adapters, workflow configuration only without system prompt and tools,
characters ÷ 4. For one run the script assumes fixed invocation counts:
business analyst 1, use case review 2, solution architect 1, concept review 2,
implementation 2, test 1, code review 2.
The 2.0.0 column contains about 20,000 tokens that only arise by calculation: some procedure skills begin with "First: invoke skill X" although the agent has already preloaded X. In the transcripts no agent did this on any of three occasions, so the column is, if anything, set too high. What I did with these lines is in Part 3.
The Core Was Lean, the Adapter Was Not
Template numbers with empty adapters say little about a real project. So I
looked at the first real feature after the update, in one of my Flutter
projects (I will call it target project A). The update ran by script, the three
migration scripts for existing projects after it with a dry run first. I measured the context in the first
turn of every subagent. It is in the transcript under
~/.claude/projects/<project>/<session>/subagents/, in the usage of the
model's first response. That is a different quantity than in the template: the
whole startup context with system prompt, tools, filled-in adapters and memory,
as the API counts it.
The results from the first two days:
- Under 1.x the concept reviewer started with 207,000 tokens (one run), after 2.0 with 85,000 to 87,000 (three runs).
- After 2.0 the implementation agent started with 158,000 tokens (one run). Under 1.x its median was 201,000 (20 runs). So the load went down, but far less than for the reviewer.
The reason lies in the order of priority set out above. The migration deliberately
moved the adapter content byte for byte so that no knowledge would be lost. The
adapters of this project were large, though (as of shortly after the
migration): coding-guidelines had 1,787 lines, styling-guidelines 1,021,
testing-strategy 776 and quality-gates 471. The implementation agent
preloads coding-guidelines, testing-strategy and quality-gates of these,
3,034 lines in total. The core was now lean, the adapter was not.
There was a side finding as well. I had started the main session of this run shortly before the update, still under 1.x, with 228,000 tokens, and continued it after the update instead of starting a new one. It kept carrying the old rule content in its context. The rule I took from that: start a new session after every workflow update.
The obvious next step was to split the large adapter skills by domain and load them only when needed. I tested whether that works in an experiment first, with an abort threshold that was fixed before the first run. The experiment, what helped instead, and the numbers from two real projects at their current state are in Part 3.