Recursive self-improvement: the output, the instructions, the workflow
A critique produces a fix, and the fix is the least valuable thing it produces. Improvement runs in three nested rings: fix this output, change the instructions so the mistake cannot recur, and change the workflow. Only the outer ring carries an obligation: you do not claim an improvement you did not measure.
Three rings
The innermost ring is the code in front of you: a finding says the totals are wrong, you fix them, the tests go green. It buys exactly one diff.
The middle ring is the instructions. The same finding, read as a class rather than an incident,
changes the spec or CLAUDE.md so the next run does not need telling again. The outer
ring is the workflow: which gates the runner stops at, what the auditor reads, which model does
which job. It pays the most, and it owes you evidence.
A critic that did not write the code
The session that just argued itself into a design is the worst reviewer of it: it holds the
justification and none of the surprise. Claude Code gives you a critic outside that conversation
as a file, .claude/agents/spec-auditor.md: Markdown with YAML frontmatter, reviewed
like any other file.
A subagent starts with a fresh, isolated context window. It does not
see your conversation, the skills you invoked, or the files Claude already read; it works from a
delegation message Claude composes (a fork is the exception, inheriting the parent
conversation). tools: Read, Glob, Grep limits the auditor to reading, so a bad audit
costs a bad list, not a bad edit; omit the field and it inherits every tool. You invoke it by
name, as @"spec-auditor (agent)", rather than hoping it gets picked. Built-in types
such as Explore and Plan have never read your spec.
This lesson has one command, a read-only sed you run from day2-work,
the lane copy Exercise 1's setup block made at the course root. It prints the auditor's
frontmatter, one file for both lanes:
sed -n '1,6p' ../day-2-loops-and-your-environment/starter/agents/spec-auditor.md
sed -n '1,6p' ../day-2-loops-and-your-environment/starter/agents/spec-auditor.md
Give the critic the spec, not the story
An auditor pointed at a diff returns opinions; pointed at numbered criteria, it returns
violations. The difference is one instruction: tag every finding with the criterion it violates,
or NO-CRITERION when the spec is silent and the code chose. Name the spec in the
prompt, because the auditor starts from the task it is handed; Exercise 2 gives you the full
prompt.
That tag makes a finding routable. The NO-CRITERION findings are the valuable
half: nothing is failing, and nobody else would have looked.
Ring two: where a finding goes
A finding tagged to an existing criterion is ring one: fix the code, and route it further
only if the rule beneath it outlives this spec. The rest have three destinations: a new or
sharpened acceptance criterion, where most NO-CRITERION findings belong because a
criterion is testable; a line in the standing instructions, for a fact that outlives this change,
such as a declined transaction counting toward no total; or the bin, with one sentence saying
why.
Standing instructions grow under a net-zero line cap: to add a line to CLAUDE.md
you remove at least one, the least valuable first, or you put the guidance in a path-scoped rule file,
.claude/rules/<name>.md, whose paths: globs let it enter the window
only when the agent reads a matching file. wc -l CLAUDE.md before and after is the
enforcement; same or lower passes.
Ablation, not accumulation
To find out whether a line earns its place, take it out and see whether the mistake comes back. Boris Cherny described the same method for Claude Code's own system prompt, reported in August 2026 as cut by about 80 percent: a dated anecdote, not a target for your file.
Your version is one line out, one re-run, one answer. If the mistake returns, the line was working; if not, you were paying for it on every turn.
Ring three: measuring the workflow
Count the iterations before the change, apply your revised spec and CLAUDE.md
to a fresh copy, re-run the same spec, and count again; Exercise 2 gives the step order.
Then state the result at its size: four iterations became two, on one spec, in one lane, n equals one. A useful team norm: a workflow change arrives with its two iteration counts and the spec they came from, or it arrives as a proposal.
Choosing a model per role
The critic and the worker need not share a model. The durable lever is a model:
line in the agent file, taking sonnet, opus, haiku,
fable, a full model id, or inherit; the shipped auditor says
model: opus. The session lever is /model, with an alias or a picker
where Enter saves the choice as your default and s applies it to this
session only.
When you write your own agent file, include the model: line. Without it, the auditor may run on the calling session's model, and the
expensive-reviewer, cheap-worker split collapses into one model reviewing itself.
When self-critique is theater
A critic with no spec returns taste, and taste is unroutable. If almost every finding comes
back NO-CRITERION, sharpen the spec before you touch the agent file.
The other failure is an auditor that always finds something. Run it on a change you already accepted, where the right answer is nothing; findings there teach your team to skim. Tune it until that run is silent, or stop running it. And keep the rings in proportion: a one-line typo fix owes nobody a spec revision and a re-run. Skip the auditor entirely before a numbered spec exists, or on a diff you can read in a minute: a read-only opus pass there costs more than it returns.
Quick check
Your auditor returns nine findings and eight are tagged NO-CRITERION. What
does that tell you to fix first?
The spec. Eight of the nine complaints are about behavior nobody wrote down, so they are preferences until a numbered criterion exists that a command can fail on.
You added four lines to CLAUDE.md after an audit and the next run was
slower and no better. What does the net-zero rule ask of you?
Remove four lines, the least valuable first, before the new ones stay, or move the guidance into a path-scoped rule file, then re-run from a fresh copy and compare iteration counts before claiming the change helped.
Sources
Claude Code documentation, accessed 2026-09-22 against version 2.1.280, and 2026-09-23 for
cc-core-38 and cc-core-40.
cc-core-25,cc-core-38,cc-core-26,cc-core-27,cc-core-28,cc-core-30— the subagent file format and its.claude/agents/location, the fresh, isolated context window a subagent starts with (a fork excepted), themodel:field and the values it takes, thetools:field, explicit invocation by name, and the built-in subagent types, from Subagents.cc-core-15,cc-core-40—.claude/rules/<name>.mdwith apaths:frontmatter list, and that such a rule loads when Claude reads a matching file, from Manage Claude's memory.cc-automation-26—/modelwith an alias or as a picker, where Enter saves the choice as the default and s applies it to the session only, from Model configuration.cc-core-32— the version this course was checked against, from the Claude Code changelog.context-eng-12— the ablation method cited above, 2026-08-05: the ablation playbook write-up.practitioners-01— the reported size of the cut to Claude Code's system prompt for one model generation, 2026-08-02: notes on Boris Cherny at YC Startup School 2026.