The Ultimate Agent Coding Workflow on Claude + Pi
The same state-of-the-art multi-agent coding harness as our Claude Code build, moved onto a Claude Code orchestrator driving Pi-based workers, and run on a large enterprise codebase with 10,000+ functions across 22 modules. The hybrid recovers the one thing flat Claude Code cannot do, nested teams, and turns tool-output compression into a first-class runtime feature: a 44% reversible token reduction rewritten in-place by Pi's tool_result hook, 2.1x fewer context tokens per edit, and an independent-judge gate that took task success from 0/3 to 3/3. A companion to our Claude Code and GitHub Copilot Agent Pipelines writeups.
We documented a seven-agent development workflow inside GitHub Copilot on a large enterprise line-of-business application, published as the GitHub Copilot Agent Pipelines project, then rebuilt the same workflow on Claude Code with a year of harder-won harness knowledge behind it. That Claude Code build is the sibling writeup to this one. It is the cleanest native host for the stack, but it is flat: its subagents cannot spawn subagents, so a work item that wants its own sub-fan-out has nowhere to put it. This project takes the identical architecture and moves it onto a Claude Code orchestrator driving Pi-based workers, and in doing so recovers nested teams, the one capability the flat build cannot express. The runtime changed and two things got sharper; the throughline did not. A large codebase is a knowledge-organization problem, not a context-window problem.

Figure 1 - The Claude plus Pi Harness at a Glance: A Claude Code orchestrator dispatches Pi team-leads, and each team-lead spawns its own Pi workers, the nested topology flat Claude Code cannot express. The seven-stage pipeline runs inside a red security frame enforced by a Pi TypeScript extension that hooks both tool_call and tool_result. An amber traceability spine feeds a custom Pi emitter out to LangSmith over OpenTelemetry. Underneath sits the same four-layer knowledge substrate: code graph, domain wiki, issue history, and skills, with identity carried in a soul.md base plus per-role overlay.
The Problem
The target is a large enterprise line-of-business application, the same one from our Copilot and Claude Code projects. Its shape is public there, so we can reuse the numbers: 10,000+ functions across 1,000+ files in 22 modules, backed by PostgreSQL, with over a decade of accumulated business logic. Module interdependencies, application-layer data isolation, validation rules, and undocumented gotchas all live in that history. Very little of it is discoverable from the file an engineer happens to be editing.
Generic AI coding assistants fail here for a reason that has nothing to do with model quality. They generate syntactically valid code that breaks foundational platform concepts, crosses data-isolation boundaries, or misses a module-specific rule that is not in the current file. The structural relationships between functions (who calls what, where complexity concentrates) are invisible to any tool that treats code as text.
The naive fix is a bigger context window with more of the codebase pasted into the prompt. That is the wrong diagnosis. You do not need the model to hold ten thousand functions in its head. You need it to know which twenty functions matter for the task in front of it, why they exist, and what happened the last time someone touched them. That is an organization problem, and everything below is an answer to it. The reason to document the same answer on a second runtime is that the runtime decides how each part of the answer is wired, and Pi wires two of them in a way Claude Code cannot.
What We Built
On Claude plus Pi, the workflow is the same roster of narrowly scoped agents, but the dispatch is nested. A non-coding Claude Code orchestrator hands work to Pi team-leads, and each team-lead runs its own Pi workers, sitting on top of the same six-layer stack. Every layer already existed as a pattern. The contribution here is assembling them into one coherent harness and showing that the architecture survives a runtime swap that changes the topology. The pattern language is the composable set Anthropic describes in “Building effective agents” [1]: a non-coding orchestrator that dispatches scoped workers, and an evaluator that checks their output. We covered the agent-definition side of this in Building Effective Claude Code Agents.

Figure 2 - The Six-Layer Stack: Orchestration topology decides who dispatches whom, the knowledge substrate is what agents read, traceability records what happened, the compounding layer governs what the system may learn, the safety stack catches what slips through, and economics decides which model runs each role. Each layer is independent, so any one can be upgraded in place. Only two layers change on the move from Claude Code to Pi: the topology gains a tier, and the safety and economics layers gain a deeper hook.
The roster is the proven Copilot pipeline, split further for parallel review: an explorer, a planner, an implementer, a code-reviewer and a security-reviewer running in parallel, a documenter, a skill-capture agent, a skill-validator that acts as a gate, and a skill-builder. The cognitive separation between the agent that writes code and the agent that reviews it is load-bearing, because a single agent grading its own work ships the security holes it just wrote. On Pi, each role is a worker driven by a TypeScript extension, its identity carried in a soul.md base file plus a per-role overlay, its skills ported from the Claude Code build with a path move. Pi ships with no native MCP, on purpose: the core stays minimal and every opinionated behavior is an extension, so the code graph, wiki, and issue history reach the workers through an MCP client added as a Pi extension.
KEY INSIGHT: Splitting the developer and the reviewer into two agents with no shared memory is not process overhead. It is the cheapest security control in the stack, because an independent reviewer catches the exact class of bug a self-grading agent is blind to. The runtime does not change that; it only changes where the boundary is enforced, and Pi enforces it deeper.
Most of those layers are more than a pattern we cite: each is carried by a component we built, measured, and published as its own project, and this workflow is the assembly of those measured parts. Eight such instruments span the knowledge substrate and the layers beneath it. They are runtime-neutral by design, so the same eight carry the Pi build; what Pi changes is how the economics instrument plugs in, covered later. The table below names the instrument behind each layer, links its project page, and gives the headline number we measured on it.
| Layer | What we built | Measured result |
|---|---|---|
| L2 Knowledge substrate | MapKit | 2.1x fewer context tokens per edit, 53% less, across 8 edits |
| L3 Traceability | TraceKit | 70:1 input token curve; 17 of 17 process faults caught vs an output-only check; $0 API cost on the default path |
| L3/L5 Ingest guard | Ingest-Guard | 85.0% injection detection at 0.0% false positives keyless, 90.0% with the optional classifier, 0 of 40 payloads leaked |
| L4 Compounding | FlywheelKit | 1 to 4 gotchas compounded across 3 harvests, a plausible-but-wrong rewrite blocked at the gate, zero un-gated writes |
| L4/L5 The gates | Deterministic Gate Harness | 0 phases advanced without evidence across 6 gated runs; the same workflow ungated shipped 4 broken artifacts |
| L5 Independent judge | RubricGate | 0/3 to 3/3 task success, 1.00 judge precision and recall on the labeled sample |
| L5 Staged autonomy | Trust-Ladder Deployer | 4 eval-gated rungs; auto-demote kept 7 bad writes out of production; the promotion gate blocked 0.720 accuracy against a 0.950 bar |
| L6 Economics | ContextLedger | 44.0% tool-output token reduction, fully reversible, on a 127-payload session; 72% on code payloads via AST strip |
Key Results
The Copilot pipeline proved the seven-stage shape. The Claude Code rebuild added the four layers the first version lacked. The Pi build keeps every one of those and adds back the topology tier that Claude Code has to flatten, while making the economics layer a native interception rather than a bolt-on.
| Dimension | Claude Code build | Claude plus Pi build |
|---|---|---|
| Topology | Flat: subagents cannot nest, one hub over seven leaves | Nested: orchestrator to Pi team-lead to sub-workers, sub-fan-out recovered |
| Hooks | PreToolUse deny at tool-use time (out-of-process) | Pi TypeScript tool_call deny and tool_result rewrite, in-process |
| Tool-output compression | ContextLedger via MCP server or PostToolUse hook, 44% reversible | Same 44%, rewritten in-place by the tool_result hook, a first-class runtime feature |
| MCP wiring | Native .mcp.json | Via a Pi extension, stdio stability is the named risk |
| Tracing | Native LangSmith (stop hook or first-party plugin) | Custom Pi emitter bridged to LangSmith over OpenTelemetry |
| Identity | CLAUDE.md plus agent files | soul.md base plus per-role overlay |
| Cost model | Flat-rate on Max, Opus orchestrator free at the margin | Metered API, every token bills, so Opus is confined to two roles |
| Schema drift | A tailwind: Claude Code’s edit tool is the optimization target | A risk it carries: newer Claude can call Pi’s tool schema worse |
The Development Workflow
The staged pipeline is unchanged from what the Copilot workflow proved: research plus doc, then plan plus doc, then code, then review plus doc, then skill capture, then knowledge capture, then an issue comment plus doc. What changed is the mechanics of the handoff underneath. The Claude Code orchestrator never writes code. It reads a work list, dispatches each stage to a fresh scoped Pi worker, and moves the durable output of one stage into the input of the next. This mirrors Anthropic’s guidance for long-running agents: a non-coding initializer or orchestrator, repeated stateless coding sessions, and progress written to files and commits rather than held in a single swelling context [2].

Figure 3 - The Seven-Stage Pipeline: Each stage produces a durable artifact (a research note, a plan, a diff, a review, a skill, a wiki entry, an issue comment) that becomes the next stage’s input. The artifacts are files, so a stage can be re-run or resumed without replaying the whole session. The review stage forks into a code-reviewer and a security-reviewer that rejoin before documentation. On Pi, each stage runs as a worker, so the fork is a real parallel spawn rather than a scheduled pair. The amber arrows run backward: a failing test or a rejected review routes to the planner for another research-and-refine pass, and only verified work moves forward.
The important property is that state lives on disk, not in a conversation. A research worker writes a findings file, the planner reads it cold and writes a plan, the implementer reads the plan cold and writes code. Each worker starts from a clean context and a written brief, which is why the pipeline can run for hours without a long session slowly forgetting its own early decisions. What Pi adds is that a stage which needs its own sub-fan-out no longer has to flatten it. A single work item can become a team-lead with its own workers, so the handoff is not always one file to one worker, it can be one file to a team that splits the work and merges its own results before reporting up.
On paper that reads like a conveyor, and it is not one. The pipeline iterates, and the loop runs through the planner. The implementer’s definition of done includes running the tests, and a failing test does not move forward, it routes back to the planning stage with the failing output attached. The planner owns the diagnosis. It can send the explorer back out for more research, and it can decide to instrument the code, adding debug statements for terminal inspection or setting breakpoints and stepping through the failure, to gather the evidence the first plan lacked. The refined plan goes back to the implementer, which applies the changes, re-runs the tests, and verifies the fix actually worked. Only a verified change reaches review, and review findings travel the same road: a rejected diff goes back through the planner rather than to an ad hoc patch. The nesting does not change where the loop lands. A team-lead whose worker hits a failing test reports the failure up rather than improvising a fix inside its own fan-out, the Claude Code orchestrator re-dispatches a planner worker with the current plan and the failing evidence, and every pass leaves an amended plan and a fresh findings note on disk, so the iteration stays as traceable as the pipeline itself.
The Knowledge Substrate
Underneath the pipeline are four kinds of memory that do not substitute for one another. Getting this taxonomy right is the sharpest part of the whole design, because conflating any two layers produces silent retrieval failures.
- Structural memory is the code graph. We run CodeGraphContext (CGC), an open-source code-graph tool we adopted and fixed rather than built. Our contributions were Neo4j node-conversion fixes, logger bug fixes, Windows PATH compatibility, and a portable
.cgcbundle system. It parses the source into a Neo4j graph exposed over MCP, so an agent can ask “who calls this function” and get an exact answer, not a similarity guess. It re-indexes on save, never rots, and is exempt from the refinement gate because it is deterministic. On Pi it mounts through the MCP-via-extension path, andcgc mcp startexposes the same tool surface a Pi worker would query natively. - Semantic memory is a file-based domain wiki: the why behind a workaround, the business rule behind a data model, what tenant isolation means in this specific codebase. This is knowledge you cannot infer by reading the code.
- Episodic memory is the issue history: one dated entry per ticket, capturing what happened and why, so a returning agent starts warm instead of re-discovering a dead end.
- Procedural memory is skills: progressive-disclosure files that describe how to run a repeatable task. The library splits into two families, both load-bearing. Engineering skills encode the codebase’s coding conventions and its API reference surfaces, the exact call shapes of internal services and third-party SDKs. Domain skills encode how the business actually works in this system: how orders flow, how invoicing runs, how credits apply. They are living files, not one-time documentation. When an agent working in one of those areas discovers something a skill missed, the skill-capture stage feeds that discovery back into the skill, so the library sharpens with every ticket it touches. Pi reads the same
SKILL.mdformat the Claude Code build used, so the procedural layer ports with a path move rather than a rewrite.

Figure 4 - Four-Layer Memory: The code graph holds the shape, the wiki holds the why, the issue history holds what happened on a specific ticket, and skills hold how to perform a task, from coding conventions and API call surfaces to domain procedures like orders, invoicing, and credits. Each layer has a characteristic wrong-use pattern (a procedure buried in the wiki, domain lore stuffed into a skill) that degrades retrieval when boundaries blur. Identity sits beside the four layers in a soul.md base plus a per-role overlay, so a worker knows who it is without polluting any memory layer.
The agents do not pick a retrieval method at build time. We hand them every tool and let the loop choose, cheapest mode first: navigational (read the wiki and issue-history index first, because a documented answer beats a fresh investigation), then structural (the code graph for exact call chains and blast radius), then textual (grep for literal strings the graph does not model), then semantic escalation only when the cheaper passes fail. The navigation map that makes that first rung cheap is one we packaged as MapKit, built on the upstream DOX/AGENTS.md pattern rather than invented, where we measured 2.1x fewer context tokens per edit against reading raw files.

Figure 5 - The Retrieval Ladder: Retrieval climbs from cheapest to most expensive. Navigational lookups answer most questions from an already-written index. Structural queries hit the code graph for exact relationships. Textual grep covers literal strings. Semantic vector search is the last rung, reached only when the first three fail, not the default.
This is where we take our most contrarian position: a vector database is premature by default on this codebase. Embedding pipelines cannot keep pace with an active team’s change rate, and the code graph plus grep plus a wiki index already covers structure and lookup. When a vector layer does earn its place, it belongs over the wiki prose, never over the code, and only on a named pain signal, such as the wiki outgrowing what an index and grep can serve. Building it speculatively buys a staleness and security problem in exchange for a capability you were not yet using. The runtime does not move this line: the substrate is identical on Pi, which is the whole point of documenting it once and reusing it.
KEY INSIGHT: On a live codebase, retrieval quality comes from letting the agent climb a cheap-first ladder, not from bolting a vector store onto everything. Earn the vector layer with a real pain signal, and put it over prose, never over code the graph already models.
Traceability and the Self-Improving Loop
This is the biggest single upgrade over the Copilot workflow, which had no trace layer at all. Traceability is what turns the back half of the pipeline (review, skill capture, knowledge capture) from a manual chore into a self-improving loop.
We capture every session as a trace. Here the runtime costs us the convenience the Claude Code build enjoyed. Claude Code has a native LangSmith path, either a roughly fifty-line Stop hook or a first-party plugin. Pi has neither, so tracing is a custom emitter we write as a Pi extension, feeding spans out to LangSmith over OpenTelemetry rather than through a native sink. The work is real, but the payoff is identical: the append-only event log becomes the agent’s identity, and runs are replayable, forkable, and portable. We built the harvest side of this as TraceKit, which reads a coding session’s transcript into a cost curve and a reliability scorecard, catching 17 of 17 process faults that an output-only check misses.

Figure 6 - The Self-Improving Loop: Every session emits a trace, on Pi through a custom emitter bridged to LangSmith over OpenTelemetry. A two-phase loop reads those traces, first identifying recurring issues, then generating candidate fixes. The fixes are proposed edits to skills and to the domain wiki, which is exactly the skill-capture and knowledge-capture stages automated. The gate is what keeps the loop from feeding on its own noise.
The loop itself is simple. Trace the runs, then run a two-phase pass over them: identify recurring failure modes, then generate fixes as proposed edits to skills and to the wiki. That is the skill-capture and knowledge-capture stages, automated, and we described the general shape of a system that improves its own agents in our writeup When AI Builds AI. The one non-negotiable is that the proposed edits pass through a gate before they land, the subject of the next section. A self-improving loop with no gate does not improve, it compounds its own mistakes.
One boundary deserves a hard guard. Any stage that reads an issue tracker or an error log is a prompt-injection surface, because hostile text can ride in through a ticket body. The issue-comment stage needs a safety classifier in front of routing, so a poisoned ticket cannot steer the agent. The classifier we built for that boundary is Ingest-Guard, which caught 85.0% of injections at 0.0% false positives keyless in our tests, with 0 of 40 payloads leaking through.
Orchestration
This is where Pi earns its place, because the topology is nested and that is the capability Claude Code cannot provide. A Claude Code orchestrator dispatches Pi team-leads, and each team-lead can spawn its own Pi workers, so a work item that wants its own sub-fan-out gets a whole team instead of a single leaf. There is a hub, an intermediate team-lead tier, and the workers beneath it. For a job that decomposes into parallel sub-tasks, that middle tier is the difference between one agent serializing the work and a lead splitting it across workers and merging their results before reporting up.

Figure 7 - The Nested Topology: A Claude Code orchestrator dispatches Pi team-leads. Each team-lead spawns its own Pi workers and merges their results before reporting up, the sub-fan-out that flat Claude Code cannot express because its subagents cannot nest. The extra tier is not free: it adds a coordination layer and its own token budget, so nesting is an opt-in reserved for work items that genuinely decompose, not a default for every stage.
Two orchestration cautions carry across from the research, and the second matters more on Pi. The first is a warning: flat equal-role agents do not scale. Cursor has reported that 20 peers sharing a coordination file collapse to the throughput of 1 to 3 under lock contention, and that the cure is role separation into a planner, a sole-owner executor, non-coordinating workers, and an independent judge [3]. We treat that figure as Cursor’s self-reported finding, not a universal law, but the shape matches everything we have seen, and it is the reason the nested tier is a team-lead over non-coordinating workers rather than a pool of peers. The second is that nesting is a trap in every runtime that allows it: unbounded, it recurses without a circuit breaker. On Pi the discipline is explicit, a depth budget per team-lead, because the runtime will let you nest further than you should. Parallel fan-out still uses git worktrees, one worktree per work item, so parallel file mutation never collides and a plain git merge resolves two half-solutions mechanically. We present that as an architectural pattern, not a benchmarked result.
The model map is held constant to isolate the harness effect. Opus 4.6 runs the two low-volume, high-leverage roles, the orchestrator and the planner. Sonnet 4.6 runs the high-volume verifiable roles: implementer, reviewers, documentation, and the skill roles. On Pi that split is not just a quality choice, it is a cost control, because every token is metered, which the economics section returns to. We walked through the multi-agent handoff mechanics in more depth in Multi-Agent Pipelines.
Compounding Without Slop
The system is allowed to learn, but only through a gate, because agents lack the pain bottleneck that stops a human from writing bad documentation. A person who writes a misleading wiki page eventually gets burned by it, an agent does not. Left ungated, the loop feeds on itself: the wiki page an agent gets wrong today is the source the next agent reads as established fact tomorrow, and the error is re-copied and amplified on every pass after that. That is the ouroboros problem, named for the serpent drawn eating its own tail, and compounding slop is what it produces.
The gated refinement loop runs after review. It proposes three things: skill edits, wiki-page edits, and an always-written issue-history entry. The issue-history entry is ungated because it is episodic fact and low blast radius. The skill and wiki edits are gated, either by a human or by a capped validator agent. We built that loop as FlywheelKit, which compounded 1 to 4 gotchas across 3 harvests while blocking a plausible-but-wrong rewrite at the gate, and the definition-of-done check behind it as the Deterministic Gate Harness, where 0 phases advanced without evidence across 6 gated runs and the same workflow ungated shipped 4 broken artifacts.

Figure 8 - The Three-M Gate: A proposed edit auto-applies only when all three risks are absent. Megaphone asks whether a wrong update broadcasts widely, Money whether it touches anything financial, and Meaning whether it corrupts a shared context file other skills depend on. Any one present routes the edit to human review. The criterion is blast radius, not confidence.
The gate criterion is blast radius, captured as the three-M test. Megaphone asks whether a wrong update broadcasts widely. Money asks whether the change touches money. Meaning asks whether it corrupts a shared context file other skills depend on. The loop auto-refines only when all three are absent, and routes everything else to a human. For model specialization, the sellable pattern is the teacher-model pattern: a stronger teacher watches a cheaper student fail, writes a skill that captures the fix, and the student executes from that skill thereafter. Full custom reinforcement-learning distillation is real, but it fails the practicality test for a typical mid-market client with no GPU infrastructure, so it stays a reference rather than part of the workflow we ship.
KEY INSIGHT: Give a self-improving system a blast-radius gate, not a confidence threshold. Confidence is what a wrong agent has too much of; blast radius is what actually determines whether a bad edit costs you a typo or a corrupted shared context file.
Quality, Safety, and Economics
Safety is a stack, not a reviewer. Each layer catches what the others miss, and this is the second place Pi changes the wiring, because its hooks run in-process and can block before an action executes.
The first layer is adversarial verification: the checker re-derives the answer and ignores the worker’s self-report, so a confidently wrong result gets caught at any rank, including the orchestrator’s own. We wrote about this red, blue, and referee structure in our adversarial testing series, and the fresh-context judge we built for it is RubricGate, which took task success from 0/3 to 3/3 at 1.00 judge precision and recall on our labeled sample. The second layer is two-level security, and here Pi is genuinely deeper than Claude Code. A Pi extension subscribes to the tool_call event and returns { block: true } to deny destructive commands, out-of-scope writes, and sensitive reads before the action runs, in-process rather than as an out-of-process advisory hook, and a separate security-reviewer worker checks tenant isolation, parameterized SQL, OWASP categories, and auth boundaries at review time. The third layer is hard action gates: a typed SDK is the agent’s only door to mutate state, and a deterministic execution step catches the false-completion failure where an agent reports done with nothing committed. Governing how much autonomy each role earns, the Trust-Ladder Deployer runs four eval-gated rungs whose auto-demote kept 7 bad writes out of production. The last discipline is to prune scaffolding as models improve, because a verifier written around a model limitation that has since been fixed can start doing harm.

Figure 9 - The Safety Stack: Adversarial verification catches confidently wrong output by re-deriving the answer. The Pi tool_call hook blocks dangerous actions in-process before they run, while the security-reviewer worker catches isolation and injection risks at review time. The typed-SDK action gate is the only door to state mutation and catches false-completion.
On economics, the rule is to route by dollars per task, not dollars per token. The flagship model runs planning and hard code, a mid tier runs by default, and the cheap tier runs mechanical labeling and knowledge chores. Two mechanics keep the bill down and both have vendor-direct backing. Anthropic’s prompt caching reads cached input at 10% of the normal input rate, a 90% discount on repeated context [4]. Lean tool design matters because tool definitions themselves eat the context window: Anthropic measured tool-definition token loads in the tens of thousands, with a five-server setup of 58 tools costing roughly 55K tokens before a single call is made, and its Tool Search Tool with deferred loading cut that by about 85% in Anthropic’s own measurement [5]. That capability is in beta, not general availability, so we treat it as a near-term optimization rather than a shipped default.

Figure 10 - Routing by Dollars per Task: The two low-volume, high-leverage roles (orchestrator and planner) run on the flagship tier. The high-volume verifiable roles (implementer, reviewers, documentation, skills) run on the cheaper tier. The routing target is cost per completed task, not cost per token, because a cheap model that loops ten times is not cheap. On a metered API this routing is a hard budget lever, not a preference.
Pi’s billing model is where the two runtimes diverge most sharply. The Claude Code build runs flat-rate on Max, so its Opus orchestrator and planner are effectively free at the margin and the real constraint is account rate limits. Pi runs on a metered API, where every orchestrator, planner, and worker token is a line item. That is exactly why Opus is confined to the two low-volume, high-leverage roles: on a flat-rate plan you can afford to be generous with the expensive model, and on a metered one you cannot. The tradeoff is real: Claude Code is the highest input-token consumer among the coding harnesses, because it re-feeds accumulated context every turn. Sebastian Raschka, who writes the Ahead of AI newsletter, ran one open-weight model across three harnesses on an identical task set and found that Claude Code used by far the most input tokens and Codex the fewest, with a single Claude Code run burning roughly 578k input tokens against 4.5k of output across 25 turns [6]. His framing is that a harness using 50% fewer tokens at equal task success is a huge win, because it also halves wall-clock time. That is one author’s five-task private benchmark, so we read it as directional rather than definitive, but on a metered runtime the direction is the part that bills. Under a flat-rate plan that appetite is absorbed by the subscription; under Pi’s metered API it is a line item, which is why the compression layer below stops being a nice-to-have and becomes load-bearing.
The re-feed problem has a direct mitigation, and on Pi it is a first-class runtime feature rather than a bolt-on. The dominant token cost in a coding session is the output of tool calls, the file reads, git status dumps, test logs, and JSON blobs the agent pulls in, not the prompt you write. The pattern is a reversible, type-aware compression layer between the agent and the model: compress each tool result by content type (AST-strip for code, field-prune for JSON, smart-filter for shell), cache the original, and leave a retrieve(id) escape hatch so nothing is lost. Tejas Chopra, an engineer at Netflix, laid out this pattern in his Headroom talk at the Linux Foundation’s Open Source Summit North America, and noted that AST compression matters more when the agent reads raw files than when it works through an LSP [7]. On Claude Code we plug our implementation in as an MCP server or a PostToolUse hook, which sees the tool output only after the fact. On Pi the tool_result hook can rewrite the output in place before the worker ever sees it, so compression is a native interception, not a downstream copy. We built the measured implementation as ContextLedger, which unifies three patterns we had arrived at independently and recorded a 44.0% tool-output token reduction, fully reversible, on a real 127-payload session at roughly a 1% retrieve rate. To be precise about provenance: we built ContextLedger and the 44% is our own measurement, while the compression pattern itself is Chopra’s Headroom work. On a metered runtime that reduction is money, not just headroom, and it stacks with the prefix caching above rather than replacing it.
KEY INSIGHT: The biggest token line in a coding agent is the output of its tool calls, not the prompt you write. On a runtime whose hook can rewrite that output in place, compression stops being a downstream proxy and becomes the model’s actual input, so you cut the bill at its source and lose nothing, because the original is one retrieve(id) call away.

Figure 11 - In-Place Tool-Output Compression on Pi: A large raw tool result is intercepted by the Pi tool_result hook, which passes it through a content router and type-aware compressor (AST-strip for code, field-prune for JSON, smart-filter for shell) and rewrites it in place. The worker receives only the compact payload, carrying a retrieve(id) handle, while the original is cached. The rewrite happens before the worker sees the output, so the 44% reduction is the model’s real input, not a copy made after the fact.
What Transfers
The thesis of this whole build is that the architecture is runtime-neutral. The roster, the four-layer substrate, the gates, and the traceability spine are identical no matter where the coding agent runs. What differs per runtime is only how each affordance is provided, whether native, ported, or built by hand. Claude Code provides nearly all of it natively and flat. Pi provides less of it natively (MCP and tracing are extension work) but recovers nested teams and turns two layers, safety and economics, into deeper in-process interceptions.

Figure 12 - The Portability Matrix: The same workflow ports across five runtimes. Claude Code is native across the board but flat, Claude plus Pi adds nested teams and deeper hooks at the cost of a metered bill and extension work for MCP and tracing, and Codex, OpenCode, and Cursor each provide the affordances differently, with the orchestrator living outside the agent for every non-Claude-native runtime. The architecture is the constant; the wiring is the variable.
There is one cross-runtime finding that lands as a risk on this build rather than a tailwind, and it is easy to get backwards. Newer Claude models are being tuned toward Claude Code’s own edit tool, which means running Claude inside a third-party harness can degrade its custom tool-schema calling. The report comes from inside this build’s own runtime. Armin Ronacher, who builds Pi, hit it against Pi’s edit tool and Simon Willison relayed it: the newest Claude models get the edit intent right, then append invented fields to the nested edits[] array, so Pi rejects the malformed call and the model retries [8][9]. The direction is the surprising part. Opus 4.8 and Sonnet 5 do this and their older, smaller siblings do not, so on this one axis the more capable model is the less portable one. Ronacher’s proposed cause is reinforcement-learning post-training toward Claude Code’s own search-and-replace edit tool, which is his theory rather than an Anthropic-confirmed mechanism, and the account is a qualitative developer report with no published failure rate. For the Claude Code build that same effect is a tailwind, because its native edit tool is the optimization target. For Pi it is a caution to design around, and it is a cost this build pays for nesting: the mitigation is to keep the worker’s edit-tool schema close to the shape the model is trained on, and to validate tool calls at the boundary so a malformed call is caught and retried rather than silently mis-applied.
The same architecture ports to three more runtimes, each its own writeup: Codex, OpenCode, and Cursor. For every non-Claude-native runtime the orchestrator becomes external code, and the strongest current framework for that slot is Pydantic AI v2, a typed, model-agnostic agent-building framework with a native MCP client and OpenTelemetry tracing. It reached general availability in mid-2026 with a stated three-month breaking-change window, so we treat it as promising rather than settled, and note that its path to LangSmith is an OpenTelemetry bridge rather than a native sink, the same bridge Pi needs here.
Conclusion
The workflow that ran on GitHub Copilot and then on Claude Code survives a second runtime swap intact, because it was never really about the runtime. It is about organizing a decade of codebase knowledge into four durable memory layers, dispatching narrow agents against a written brief, tracing every run, and letting the system learn only through a blast-radius gate. Moving it onto a Claude Code orchestrator over Pi workers proves the point twice: the substrate, the gates, and the safety stack port without change, while the runtime recovers the nested teams the flat build could not express and makes tool-output compression a native interception instead of a downstream proxy.
Two honest costs come with that. Pi meters every token, so the model map that was a convenience on Max becomes a hard budget lever here, and Opus lives only in the two roles that earn it. Pi is also a third-party harness, so the schema-drift risk that is a tailwind for Claude Code becomes a caution to design around. Neither changes the architecture; they change what you tune. That is the entire reason to document this workflow across runtimes: the design is the constant, and each runtime tells you which knobs it hands you and which it takes away. The next writeups take the same stack to Codex, OpenCode, and Cursor, where the orchestrator moves outside the agent entirely.
Technologies
| Layer | Technology |
|---|---|
| Runtime | Pi coding-agent workers driven by TypeScript extensions, under a Claude Code orchestrator; nested team topology |
| Code graph | CodeGraphContext (CGC) over Neo4j, exposed to every agent via MCP added as a Pi extension |
| Knowledge substrate | File-based domain wiki, dated issue history, progressive-disclosure skills (ported SKILL.md), MapKit navigation map; identity in soul.md base plus per-role overlay |
| Traceability | Custom Pi emitter bridged to LangSmith over OpenTelemetry; TraceKit for cost and reliability harvest |
| Compounding | FlywheelKit gated refinement, Deterministic Gate Harness, the three-M blast-radius gate |
| Safety | Pi tool_call in-process deny hook, security-reviewer worker, RubricGate, Ingest-Guard, Trust-Ladder Deployer, typed-SDK action gate |
| Economics | Model-tier routing by cost per task on a metered API, prompt caching, ContextLedger compression via the tool_result hook |
| Models | Anthropic Opus 4.6 (orchestrator, planner), Sonnet 4.6 (implementer, reviewers, documentation, skill roles) |
As a Consulting Engagement
This is how we run a harness-engineering engagement when a client wants the workflow on infrastructure they own rather than a rented runtime. We assess the codebase, stand up the four-layer substrate and the trace spine, wire the compounding and safety gates, and route models by cost per task rather than cost per token, which on a metered API is a budget lever rather than a preference. Each of the eight instruments behind the six layers is independently deployable, so an engagement can start with the layer that hurts most, whether that is token cost, agent reliability, or injection exposure, and expand from there. The Pi build is the right call specifically when nested teams or deep in-process hooks earn their keep and a client wants to own the harness end to end. If you are running coding agents against a large legacy codebase and cannot tell which scaffolding to keep and which to delete as the models improve, we are happy to talk it through or lend a hand.
The Series
This is the second of five project writeups in the Ultimate Agent Coding Workflow series, one state-of-the-art coding harness documented per runtime:
- The Ultimate Agent Coding Workflow on Claude Code: the flat, fully native build on Max, where the code graph, skills, hooks, and tracing are all first-class.
- The Ultimate Agent Coding Workflow on Claude + Pi (this writeup): the hybrid that puts a Claude orchestrator over Pi workers to recover nested teams and deeper TypeScript hooks, and turns tool-output compression into a native interception.
- The Ultimate Agent Coding Workflow on Codex: an external OpenAI Agents SDK orchestrator driving Codex as an MCP server in a star topology.
- The Ultimate Agent Coding Workflow on OpenCode: an external TypeScript SDK conductor over a headless server, with a native permission frame and model-agnostic routing.
- The Ultimate Agent Coding Workflow on Cursor: the two-tier, IDE-first variant with native worktrees and a bolt-on trace spine.
References
[1] E. Schluntz and B. Zhang, “Building effective agents,” Anthropic Engineering, December 19, 2024. https://www.anthropic.com/engineering/building-effective-agents
[2] J. Young, “Effective harnesses for long-running agents,” Anthropic Engineering, November 26, 2025. https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents
[3] Cursor, “Towards self-driving codebases,” Cursor Blog, February 5, 2026. https://cursor.com/blog/self-driving-codebases
[4] Anthropic, “Prompt caching,” Claude Platform Documentation, 2026. https://platform.claude.com/docs/en/docs/build-with-claude/prompt-caching
[5] Anthropic, “Introducing advanced tool use on the Claude Developer Platform,” Anthropic Engineering, 2026. https://www.anthropic.com/engineering/advanced-tool-use
[6] S. Raschka, “Using Local Coding Agents,” Ahead of AI, June 27, 2026. https://magazine.sebastianraschka.com/p/using-local-coding-agents
[7] T. Chopra, “Headroom: A Context Optimization Layer for LLM Applications,” Open Source Summit + Embedded Linux Conference North America 2026, The Linux Foundation, Minneapolis, MN, May 19, 2026. https://www.youtube.com/watch?v=UOWSHg18cL0
[8] A. Ronacher, “Better Models: Worse Tools,” Armin Ronacher’s Thoughts and Writings, July 4, 2026. https://lucumr.pocoo.org/2026/7/4/better-models-worse-tools/
[9] S. Willison, “Better Models: Worse Tools,” Simon Willison’s Weblog, July 4, 2026. https://simonwillison.net/2026/Jul/4/better-models-worse-tools/
Have a project like this in mind?
That is the kind of work we do at Dotzlaw Consulting. Book a free 20-minute intro call and tell us what you are trying to build, or what is slowing you down.