The model is the fulcrum.
The harness is the lever.
Claude Code ships the agent loop for you; the ring around that loop you build yourself. With the same Claude, how well you build that ring decides whether it edits a few lines or carries a 700K-line legacy system.
Same model,
the environment sets its ceiling
Onboard Claude like a new developer and stalled work starts moving again; yet the model's own capability is the ceiling. Put both together: the harness is the adjustable lever, the model the fixed fulcrum. You can't change the fulcrum — the room to act is the lever.
A discipline running through the whole piece: a harness decays. When the model improves, yesterday's scaffolding can become dead weight. So for every layer below, weigh when to retire it — covered in the closing.
This piece is only about configuring Claude Code
Claude Code gives you the main loop Anthropic already built; you don't write the agent loop. This article covers one thing: how to configure that ready-made framework. Three categories shouldn't be conflated: ① what the model gives you (can't change it, Layer 0), ② what you configure (this article), ③ what you build from scratch (out of scope here).
Model selection, context management, the build order for knowledge and tools, orchestration with subagents and Workflows, pulling verification into its own role. All of it is what you configure, not build.
Plus ①model capability: a given you can't change, only route around — the bedrock (Layer 0).
prompt-caching design rules, implementing an MCP server, an agent-facing CLI, the single-loop vs. multi-agent trade-off, turning your product into a verifiable interface. These only come up building an agent from scratch with the API/SDK.
Where such material appears it's noted briefly and tagged "out of scope," not expanded.
Five floors, built bottom-up
Layer 0: the bedrock you can't route around
This layer isn't built; it's given. But understand it first — it decides how lean the harness can be.
The window is 1M tokens (system prompt + full conversation + all tool output + files read), but a large window isn't license to fill it.
Practical tip: put a context progress bar in your status line. No more hammering /context and breaking flow — how much window is left is visible at a glance:
/compact or spin up a subagent — no more /context breaking your flow.As of 24 July 2026 the strongest coding model available is Opus 5, but the more durable point is not the current ranking: it is the principles below, which stay applicable after the named model is superseded.
high; tune it against the work and the eval. In Claude Code, every model that supports effort defaults to high, except Opus 4.7 at xhigh. Opus 5 supports low, medium, high, xhigh, and max. Anthropic's guidance is to start at high, use low and medium liberally as the primary controls for token cost and response time where quality holds, and step up to xhigh for demanding coding and agentic work. Reserve max for work that justifies unconstrained token spend; it still shows diminishing returns and can overthink. Re-run the full effort sweep on the project's own evals for every new model rather than carrying settings forward. (4.7's Claude Code default was xhigh; 4.8 moved it back to high — which is exactly point D below.)/model and /effort once in a fresh session, since both remember the previous selection and that choice should be deliberate. When a session will be grunt work, MAX_THINKING_TOKENS=0 turns thinking off for that one session (except on Fable 5), the step below /effort low. Both commands also sit on the cache key; the cost of switching mid-conversation is in 0.4.| What changed | Specifics | What to do |
|---|---|---|
| Default effort changed | Claude Code defaulted to xhigh on 4.7; 4.8 moved it back to high | Set it back to xhigh for coding |
| Long-context retrieval regressed (the 4.7 gen) | Multi-needle MRCR: 256k 91.9%→59.2%, 1M 78.3%→32.2%; heavy web research fell too, BrowseComp ≈ −4.4pp | RAG / long-doc / web-research: A/B before upgrading, don't trust the version number |
This generation's hallucination dropped sharply, which directly changes how much verification costs. The same fact-check process audited 11 reports (independent subagent compares each claim to the source in a clean context, fixes, hands to a fresh subagent until zero issues). The day we switched to Opus 4.8 was a clear watershed:
But don't misread it as "no verification after 4.8." What thins is the rework, not verification itself. Generation isn't evaluation; an independent agent signing off rather than the executor self-grading is a separation of duties that can't be removed (see Layer 4).
You are billed per token, but what you pay for is inference: the GPU time it takes to run the model over those tokens. Three things decide how much of that time a token takes — which model you run, whether it is input or output, and whether it was cached. Section 0.2 covers the model; everything below is multiplied by its price.
| One token | Relative to input | Why |
|---|---|---|
| Input · prefill | baseline | The model reads everything you sent: system prompt, CLAUDE.md, your message, plus every file and command output already in the conversation |
| Output · decode | roughly 5x | Written one token at a time, so a 200-token response is 200 sequential runs of the model; per token, decode keeps the GPU busy far longer |
| Cache read | 0.1x | The server loads the already-computed state instead of recomputing it |
| Cache write | up to 2x | The state has to be retained afterwards — but the write happens once, and every later turn reads at 0.1x |
Take the prompt "fix the failing test in utils.test.ts." Claude Code sends five requests for it, each carrying the complete conversation so far:
The match has to hold byte for byte from the very start of the request, and the order is stable: tool definitions, the system prompt, then the conversation with CLAUDE.md at its front. A tool result appended at the end is the ideal case, since nothing sits behind it. What throws the cache away is a change further forward, or a change to the cache key — the small set of values that decides whether the beginning still counts as identical:
/model: every model has its own cache, so the next turn prefills the entire conversation at full price. This includes opusplan, which switches models on every entry to and exit from plan mode./effort: also part of the key. That is why both commands ask you to confirm a mid-conversation switch./compact: the conversation is replaced with a shorter one, so nothing in it matches anymore; the system prompt in front of it survives.ENABLE_PROMPT_CACHING_1H=1 makes the latter an hour. Come back later than that and the next turn prefills everything again — which resuming an old session almost always does, since the cache is usually gone and the system prompt is rebuilt at launch anyway.Anthropic treats a cache hit rate below its threshold as a production incident (SEV): a miss recomputes every turn at full price, doubling cost and halving the plan's rate limit, so hit rate directly sets the quota a Pro/Max plan gives you.
None of this means never switching model or effort. It means the switch has cheap moments (the start of a session, right after /clear) and expensive ones (the middle of a long conversation). Hence the two rules:
Caching also has 5 design rules for agents you build from scratch (no mid-stream tool changes, defer_loading, no model switching, update via messages not the system prompt, disguise compaction as a parent continuation) — out of scope here, not covered.
Context: the one resource you actually manage
The loop is given; you manage what goes in and when to clear it. Almost every difference in outcome traces here. After each step, you stand at a branch point — 5 choices, 4 of them about managing context quality:
Compaction is lossy: near the limit the whole conversation becomes a summary, and the model continues from it in a fresh window. The danger is when automatic compaction fires — exactly at the model's weakest moment:
Scenario: 5 files read, approach A failed, switch to B.
Failure and fix both linger
"That doesn't work, try B" — the failed approach plus your correction stay in context, adding noise and clouding judgment.
Back to the fork, switch cleanly
Roll back to "5 files read, A not tried," then say "don't use A — foo doesn't expose that interface, go to B." Keep the reads, drop the failed try.
Companion "Summarize from here": Claude condenses what it learned into a handoff note — a letter from the future Claude to its past self ("I tried A, it didn't work, because…") — so a later session doesn't repeat it.
Rewind is also the cheaper move. It only cuts those turns off the end, so everything before them is still cached and it costs nothing; /compact rewrites the whole conversation and therefore always costs something. If the last few turns went somewhere you don't want to keep, rewind to just before them instead of reaching for /compact.
/compact and /clear both clear context; the difference is who decides what to keep:
| Dimension | /compact | /clear |
|---|---|---|
| Effort | Low — Claude summarizes | High — you distill |
| Precision | Claude decides what to keep | You decide what to carry |
| Context rot | Partly mitigated | Fully eliminated |
| Best for | Clearing clutter mid-task | Starting a fresh task |
| Scenario | Use | Why |
|---|---|---|
| Same task, context still relevant | Continue | It's all still working for you |
| Claude went down the wrong path | Rewind | Keep reads, drop failed try |
| Session clogged with stale debug | /compact + steer | Low effort, you set direction |
| Starting a fresh task | /clear | Zero rot, full control |
| Next step: lots of conclusion-only output | Subagent | Noise stays in the child |
| Stepping away from the keyboard | /compact | Cheap while the old conversation is still cached |
New task = new session. For related tasks: highly relevant → continue (skip re-reads); otherwise /clear. Subagent mental test — "do I need the tool output itself, or just the conclusion?" Conclusion only → dispatch. More in Layer 3. The downside belongs here too: without your conversation it sometimes has to re-read what the main session already held while paying for its own turns, so a small job is pure overhead, and the main session only gets back what the subagent chose to report. For a noisy job you hand off repeatedly, give it a definition of its own with model: haiku; otherwise it runs on whatever the main session is running on.
Nothing gets sent just once. Anything that lands in the conversation, a file Claude read or the output of a command it ran, is sent again on every turn after it for the rest of the session (a turn being one complete round trip from your or a tool's input to the model's response). Those re-sends are cached and therefore cheap, but cheap is not free, and they occupy room the model has to think around on every turn. A session's cost comes down to three things:
The startup share is directly inspectable: run /context in a fresh session to see what is loaded, keep CLAUDE.md to specific instructions and move workflow-specific material into skills that load only when used, and turn off any MCP server this session does not need with /mcp. Almost everything added later is tool results, and how much Claude reads depends on how much it has to work out on its own:
| Three ways to ask for the same fix | What it costs |
|---|---|
| "The tests are failing" | A grep or two to find which test, several files opened to see which is relevant, all of it staying in context long after it stops being useful |
"Fix the failing test in utils.test.ts" | Skips the search; costs one Read call |
"Fix the failing test in @utils.test.ts" | Drops the Read call too: @ attaches the file to your message before anything is sent, so it is in the very first request |
The file takes up the same room either way, so mention it once per conversation; @-mentioning it again on a later turn generally attaches a second copy.
The other side is command output. Whatever your tests, a build or a git log prints is appended just like a file Claude read, and stays for the same number of turns. The counterintuitive part sits on either side of one threshold:
Written out to a file
Claude Code writes the output to a file and leaves only a short preview and the path in the conversation. BASH_MAX_OUTPUT_LENGTH changes the threshold.
The lasting weight
A test runner that prints 400 passing tests one line at a time comes in under the limit, and those 400 lines are now part of every remaining turn.
Claude will often handle this with flags and tail; for tighter control, the docs have a small hook that rewrites noisy commands before they run so only the lines that matter come back. The cheaper habit is to put the two or three commands you run all day into CLAUDE.md, quiet flags included, written the way you would type them — running a single test file with npx vitest run --reporter=dot, for instance. It saves a turn and a few hundred lines of output in every session after it.
Retention costs too. One long session costs more than the same work spread over a few short ones, so don't carry one task's context into the next: /clear when you start something new, /compact when the earlier part of the same task is done. The supporting moves: /rename before you /clear if you'll want the session back; when you /compact, say what to keep, or add a Compact instructions section to CLAUDE.md if it is always the same; and on a 1M model, /autocompact 200k puts the auto-compact safety net back where it used to be, which needs Claude Code v2.1.221 or later.
Some turns happen while you are not typing. A /loop fires as a full turn inside the session where you set it up, carrying that whole conversation every time, and if more than an hour has passed since the last turn, that is a cache miss on top. Start a fresh session in another terminal and run the loop from there.
Knowledge & tools: a 7-layer build order
The core framework. An often-missed premise: the harness matters as much as, or more than, the model. First the underlying mechanism — Claude finds code via agentic search, not RAG:
| Dimension | RAG tools | Claude Code · agentic search |
|---|---|---|
| Index upkeep | Needs an embedding pipeline | None |
| Freshness | Lags (hours/days/weeks) | Real time on the live codebase |
| Failure mode | Returns deleted/renamed funcs, no signal | No such problem |
| Scaling | Can't keep up with thousands of commits | Each instance runs independently |
The cost: it needs enough starting context to know "where to begin," and navigation quality tracks setup quality. Conclusion — teams that invest in codebase setup get better results.
| Layer | Most common misuse |
|---|---|
| L1 CLAUDE.md | Stuffed with reusable expertise (belongs in a skill) |
| L2 Hooks | Done via prompt instead of auto-running |
| L3 Skills | All crammed into CLAUDE.md |
| L4 Plugins | Good config left in one person's hands |
| L5 LSP | Assumed automatic (needs a plugin + language server) |
| L6 MCP | Built before the basics |
| L7 Subagents | Exploring and editing in one session |
permissions.deny to version control for the whole team.Many people think a skill is just a SKILL.md. It's actually a folder — SKILL.md is only the entry point, with scripts, references, templates, even its own hooks alongside it. That's exactly what makes it stronger than a prompt.
SKILL.md gives the method, scripts/ the hands, references/ load on demand to save context.Mechanically, each skill's name and description sit in the system prompt, which is what makes them the trigger surface: Claude scans those entries, decides which to use, and invokes it by issuing an ordinary Bash call to cat the relevant SKILL.md into context. Referenced files such as references/api.md are then read with a further cat only when actually needed. The whole load chain is Claude pulling content on demand with general tools, not the harness pre-injecting it.
Anthropic groups the common uses into nine kinds, from looking up docs all the way to ops:
Nine best practices from Anthropic's hundreds of internal skills:
Getting a skill right
- No filler: focus on what pushes Claude off its defaults (e.g. "avoid Inter and purple gradients")
- Build a Gotchas section: the most valuable content — log failure points, keep updating
- Progressive disclosure via the file system: split detail into
references/api.md - Avoid over-constraining Skills, except in highly important areas; Description is the trigger, not a summary
Keeping it durable
- Store scripts for Claude to compose, not rebuilt boilerplate
- Hooks on demand:
/carefulinterceptsrm -rf,DROP TABLE - Persist in
CLAUDE_PLUGIN_DATA(skill dirs are wiped on upgrade) - User config in
config.json; if unset, ask via AskUserQuestion
Sharing: small teams check into .claude/skills; for scale, a plugin marketplace (with vetting). A PreToolUse hook logging invocations shows what's popular. One lesson: good skills start as a few lines and improve as you hit edge cases.
MCP brings external data and systems into the session. This piece covers plugging it in, not designing a server (out of scope here). Two cost levers — both client capabilities:
MCP and Skills are complementary: MCP gives tools and data, Skills give operating knowledge, and the strongest agents use both. (The five MCP-server design patterns are out of scope here.)
Back in late 2024, Claude 3.5 Sonnet scored 49% on SWE-bench Verified with just two general tools, Bash and Text Editor — the SOTA then. Claude Code's foundation is still those two; Skills and Memory are combinations of them.
2.2 gave a build order, "in what sequence to stand up which capabilities." Here is the orthogonal lens: once you already have a concrete instruction, which carrier should hold it? Anthropic groups the carriers into seven, and what separates them isn't function but four axes: when it loads, whether it survives compaction, context cost, and how much authority it carries. Three weren't covered on their own above; the most important is a distinct constraint carrier, Rules (markdown under .claude/rules/, with a paths: field that scopes it so it loads only when Claude touches a matching file). Its split with CLAUDE.md: a rule with no path scope is mechanically the same as putting the text in root CLAUDE.md, always loaded and always burning tokens, so its value lives entirely in paths. A single directory's convention belongs in a nested CLAUDE.md; a cross-cutting constraint scattered across directories (say, "every handler validates input first") fits a path-scoped rule better.
--- paths: - "src/api/**" - "**/*.handler.ts" --- All API handlers must validate input with Zod before processing.
src/api/** → stays out of context in a docs-only session, loading only when Claude touches a matching file. That scoping is the whole of what makes Rules different from a root CLAUDE.md.| Carrier | When it loads | Survives compaction? | Context cost | Best for |
|---|---|---|---|---|
| CLAUDE.md · root | Session start, always resident | Yes, re-read (memoized) | High, every line costs | Build commands, codebase-specific gotchas, team norms |
| CLAUDE.md · subdir | When a file under it is read | Gone until that dir is touched again | Low | A directory's local conventions |
| Rules | When a file matching paths is touched | Re-injected | Medium (resident if unscoped) | Cross-cutting local constraints |
| Skills | Name resident, body loads on invoke | Re-injected up to a shared budget, oldest dropped first | Low | Procedural workflows |
| Subagents | Name resident, body only when called | Only the final summary returns | Near-zero in main context | Isolated side tasks, result only |
| Hooks | Fire on lifecycle events | Bypass compaction entirely | Low, config lives outside context | Actions that must happen deterministically |
| Output styles | Session start, into system prompt | Never compacted | High, overwrites default system prompt | Role-level changes (use with care) |
| Append-system-prompt | CLI flag, that invocation only | Never compacted | Medium, cached after first request | Tone, length, format preferences |
The green column, "survives compaction?", is the axis not covered systematically before: put an instruction in a carrier that compaction drops, and in the back half of a long session it may simply be gone. A subdirectory CLAUDE.md vanishing once that directory stops being touched is the easiest one to get bitten by.
What actually decides which CLAUDE.md files load at session start is where the session starts: every CLAUDE.md / CLAUDE.local.md on the ancestor chain from ~/.claude/ down to the launch directory loads at start, and only directories below it are on-demand. Launching in a subdirectory preloads the whole chain's conventions, which is both the intended way to get local context and how context quietly gets heavier.
Anything written into CLAUDE.md, Rules, or Skills is an instruction, and an instruction is a request, not a guarantee. In a long session, an ambiguous moment, or a file carrying a prompt injection, the model can simply miss it. So for things that must never happen, dropping a database, editing prod, touching off-limits paths, a line that says "don't do this" isn't enough; only hooks and permissions enforce deterministically.
Hooks fire across the whole agentic loop, with events seeded all the way from SessionStart to SessionEnd, and every tool call re-runs the PreToolUse → tool executes → PostToolUse cycle each turn. Hook configuration lives outside the main context and bypasses compaction entirely. PreToolUse is the one deterministic blocking gate: a hook that exits with code 2 denies the call. The dashed cluster on the right holds off-spine, asynchronous events that fire independently of the main flow.
The last two carriers are best left alone in most cases. Output styles overwrite the default system prompt, stripping "you are a software-engineering assistant" along with its safety and verification habits, unless you set keep-coding-instructions: true; to adjust style, check the built-in Proactive / Explanatory / Learning first. Append-system-prompt applies to one invocation and only adds to the role, but the more you pile on, the less faithfully it's followed.
Close with a "symptom → relocate" lookup. The earlier table reads carrier-first; this one runs the other way: catching yourself writing a certain kind of thing into CLAUDE.md is usually the signal it belongs somewhere else.
| If you're writing this in CLAUDE.md… | It belongs in | Why |
|---|---|---|
| "Every time X, always do Y" (run prettier after every edit, post to Slack on completion) | a hook in settings.json | The model choosing to run a formatter is not the same as the formatter running automatically. If it must happen reliably, hand it to the harness instead of trusting the model to remember. |
| A 30-line procedure (deploy runbook, release or review checklist) | a skill in .claude/skills/ | CLAUDE.md is for facts that are always true (build commands, codebase-specific gotchas, team conventions). A procedure's body loads only when invoked; leaving it resident just burns tokens. |
| A personal preference (e.g. "always use semantic commit messages") | a user-level file (~/.claude/ or CLAUDE.local.md) | Every file-based method has a user-level counterpart loaded across all repos. Keep personal taste at the user level; reserve project files for preferences that are team-wide but specific to this codebase. |
Two more symptoms are covered earlier in this section: a "never do X" rule needs hooks plus permissions, with managed settings for org-wide enforcement (see the authority paragraph above); an unscoped constraint that only applies to src/api/** is mechanically identical to putting it in CLAUDE.md unless you add paths: (see the Rules paragraph).
Published alongside Claude Opus 5 on 24 July 2026, Thariq Shihipar's official Anthropic post, "The new rules of context engineering for Claude 5 generation models," extends the less-is-more throughline from 2.6 with evidence from Claude Code itself. For Opus 5 and Fable 5, Anthropic removed over 80% of the system prompt "with no measurable loss on our coding evaluations." It attributes the root cause directly: "Overall, we found that we were overconstraining Claude Code, both through our system prompt and in our CLAUDE.md files and skills." The transcript evidence adds a mechanism beyond context capacity. A single request could inherit "leave documentation as appropriate" from one layer and "DO NOT add comments" from another. Even when Claude recovered the intended answer, it had to spend attention reconciling overlapping constraints before acting. That reconciliation cost is distinct from the token cost of carrying the instructions at all.
| Then | Now | What changed |
|---|---|---|
| Give Claude rules | Let Claude use judgement | Match surrounding code; keep Skills flexible by default, with tight constraints only in highly important areas. |
| Give Claude examples | Design interfaces | Expressive parameters and typed states teach usage without narrowing exploration. |
| Put it all upfront | Use progressive disclosure | Main principle already covered; new here is deferred loading for Claude Code's built-in tools. |
| Repeat yourself | Simple tool descriptions | Main principle already covered; new here is removing duplication in favour of tool descriptions. |
| Memory in CLAUDE.md | Auto-memory | Relevant work and user preferences are now saved automatically. |
| Simple specs | Rich references | Artifacts, tests, existing code and rubrics provide executable evidence of intent. |
The highlighted rows are new to this article. The two unhighlighted ones restate principles covered in 2.1, 2.4, 2.6 and 2.7; only their new parts are added below.
The progressive-disclosure principle is already established; the addition here is its application to Claude Code's built-in tool surface. Anthropic says some of its tools use deferred loading: the agent must retrieve their full definitions through ToolSearch before use, and the Task tools are the named example of what this makes affordable. Section 2.5 described the MCP client-side switch that withholds external tool definitions; here, the same mechanism governs Claude Code's own tools. Anthropic also removed repeated instructions from the system prompt, judging tool descriptions sufficient to carry usage guidance without duplication.
Auto-memory supersedes the old # hotkey workflow by saving relevant work and user preferences automatically. Anthropic presents four forms of rich reference: an HTML artifact created with Artifacts, a detailed test suite, a function in another codebase to port, and a rubric evaluated through dynamic workflows and verifier agents, which lets Claude check taste in a given field against a standard (their example: what good API design looks like). It favors executable or code-adjacent references over prose: "For example, a HTML mockup of a design will generally produce better results than a description of the design or a screenshot." The seven-carrier taxonomy from the earlier "Steering Claude Code" post remains unchanged.
Anthropic packaged the audit as claude doctor, exposed in Claude Code through /doctor, as the automated entry point for rightsizing Skills and CLAUDE.md files. That turns the six reversals into routine maintenance, and the closing section takes the same idea further: build it, then cut it.
Orchestration: who should hold the plan
The question becomes: does Claude carry the whole plan turn by turn, or is it held elsewhere? Principle: don't split small tasks; don't make the model hold an entire large plan in context alone.
What it is
- Three traits: fresh start (no history), parallel, permission isolation (research read-only / impl editable)
- Nestable: a subagent can spawn subagents, up to five levels deep, the structural basis for dynamic orchestration fanning one task across hundreds of agents
- General-purpose: full tools, complex multi-step
- Plan Agent: read-only, research + strategy
- Explore Agent: read-only, fast search
When to dispatch
- Research-heavy (dozens of files)
- Multiple independent tasks (parallel)
- A fresh perspective (no inherited bias)
- Pre-commit verification (independent check)
- Pipeline workflow (clear stages/handoffs)
The maturity path in one line: conversation first, automation later. Start in natural language, watch what recurs, then harden it:
.claude/agents/, description = a triggerHow it should be done
- Research then implement (start from a summary, not 20 raw files)
- Parallel batch edits (one pattern, independent files)
- Independent code review (a fresh view is more objective)
- Pipeline (design/implement/test, handoff via files)
Don't do this
- Sequentially dependent: one session in order is cleaner
- Same-file edits: parallel edits collide
- Tiny tasks: delegation has overhead, just do it
- Too many expert agents: lowers auto-delegation reliability
- Needing inter-agent coordination: they can't talk — use Agent Teams
What separates the three isn't scale, it's one question: who holds the PLAN token. With Subagent/Skill, Claude holds it turn by turn and intermediates land in context; with a Workflow, the script holds it and Claude sees only the final answer.
| Subagents | Skills | Workflows | |
|---|---|---|---|
| Who decides next | Claude, per turn | Claude, per prompt | The script |
| Intermediates live | Claude's context | Claude's context | Script variables |
| Reproducible | Worker definition | Instructions | The orchestration |
| Scale | A few per turn | Same as subagent | Tens to hundreds/run |
| On interruption | Restart the turn | Restart the turn | Resumable in-session |
A Workflow isn't a replacement for a Skill; they're orthogonal: a Skill changes "what the model knows," a Workflow changes "how things are deterministically orchestrated." An agent fanned out in a workflow can load a skill first.
/workflows, press s to save it as a command.Convergence is the exit condition, not a fixed round count. Triggers: workflow in a prompt / /effort ultracode / a saved command; a built-in /deep-research. On by default for Max/Team/API, manual via /config for Pro, off for Enterprise. Token use far exceeds a normal session — try a small task first; before a big run, check /model and route lighter stages to a smaller model.
A Workflow ported Bun from Zig to Rust: ~750K lines, 11 days, 99.8% test pass rate, via four chained workflows (① map Rust lifetimes ② translate per file, hundreds of agents in parallel, two reviewers each ③ drive build/tests to green ④ optimize overnight, a PR per change for human review). But the preconditions are extreme; not "any migration in 11 days":
- strangler-fig incremental replacement, not a rewrite — Zig and Rust linked into one binary, switched class by class
- every switch passed tests + shadow-diff + a ≤2% performance gate — verification-driven, not "done means trusted"
- very high existing test coverage (99.8% presupposes a strong suite), single-author, not yet in production (99.8% isn't 100%)
Correct reading: on a high-value module with strong tests and gates, a deterministic script + build/test fix loop compresses quarter-scale work to days. Pilot on such a module; don't copy the timeline.
The default harness packs planning and execution into one context; on long-running, massively parallel, or adversarial work it breaks — three ways, which is exactly why the plan should move into a script:
Laziness
A 50-item review claims "done" at item 35.
Self-preference
It shields work it just produced when judging it.
Goal drift
Fidelity leaks over turns; compaction drops "don't X."
Workflows fix all three structurally: laziness — the script holds the full checklist, not done until the loop ends; self-preference — verification by another independent agent; goal drift — the goal lives in the script, immune to compaction.
Classify-and-act
A classifier decides the category, routes to different agents. A triage desk for the pipeline.
Fan-out-and-synthesize
Split into steps, one agent each; synthesis is a barrier — the only one that waits.
Adversarial verification
Each worker gets a dedicated agent to verify adversarially against a rubric. Cures self-preference.
Generate-and-filter
Diverge into many ideas, then filter and dedupe to the best few.
Tournament
N agents, different strategies on one task; pairwise compare to a winner.
Loop until done
When the workload is unknown, no fixed round count — loop to a stop condition.
Comparative judgment beats absolute scoring, especially for ranking.
Counterintuitively, it's often more useful for non-technical work. Of the nine use cases named officially, over half aren't about writing code:
An agent reading untrusted public content must not take high-privilege actions; those go to a separate set of agents. Reading and acting are kept apart — a structural defense against prompt injection.
When not to use it: Workflows can produce exceptional results, but not every task needs one and they burn far more tokens. First ask "does this really need more compute" — most traditional coding tasks don't need a five-person review panel. Tips: a detailed prompt matters most; small tasks can use a quick workflow; pair with /loop and /goal; write use 10k tokens to cap; press s to save into ~/.claude/workflows or a skill. Treat it as a starting point, not an endpoint.
Verification: the doer shouldn't grade its own work
Writing code is cheap now, so the bottleneck moves to verification. The core: generation isn't evaluation; the two must be separated. Ask the doer to grade itself and it almost always praises — like a developer reviewing their own code. An engineering reality: tuning an independent Evaluator to be strict is far easier than teaching the Generator to self-criticize.
Use an independent review subagent, or the Workflow adversarial-verification pattern, so reviewer ≠ executor and they share no context. Pure Claude Code usage, no extra code.
Turn the artifact into an agent-readable interface (data-verify-* contracts, window.__verify, .verify.ts). The thesis is "an economic inversion": agents drive verification's marginal cost toward zero, so contract testing finally scales on the front end. You'd only do this when reshaping your own product.
Onboarding a 700K-line legacy codebase
All four layers on the opening's Skyline project. Core method: onboard Claude like a new hire — explain enough background to finish a bounded project, and produce better context for the next round. A five-step loop, each round starting higher:
pwiz-ai, not the code repo — else it's isolated by branch and Claude becomes a "different person" per branch. Maintained as a real engineering artifact, versioned.Four takeaways: scope isolation is the prerequisite (no one-shot on a huge legacy base — slice and expand) · the debugging skill must be a hard constraint (blindly changing one line in 700K can chain-fail) · context must be independent of code branches · MCP wiring frees people from triaging failures. One honest caveat: not an install-and-go silver bullet — someone maintains the context layer and advances incrementally. But it was proven in "the scenario least suited to AI."
Cut as you build: the harness's half-life
A harness isn't build-once-and-done; it has a half-life. Every component encodes an assumption about model capability, and assumptions expire. How much you can cut depends on how strong the model is.
A real case: Sonnet 4.5 ended tasks early near the limit ("context anxiety"), so a context-reset workaround was added; once Opus 4.5 shipped and the behavior vanished, that code became pure dead weight. Likewise a hook intercepting writes to force Perforce p4 edit turned redundant once it was native. The right mindset isn't "how to make Claude stronger" but "what can I stop doing."
But some parts can't be cut. The Planner / Evaluator separation of duties stays: without a Planner, the Generator under-scopes; without an Evaluator, edge-case bugs slip through. Cleanly distinguish the cuttable (scaffolding) from the uncuttable (context discipline, separated verification). Audit the harness every 3 to 6 months, starting with /doctor to rightsize Skills and CLAUDE.md. Anthropic's removal of over 80% of Claude Code's system prompt, with no measurable loss on its coding evals, sets the scale of reduction worth testing.