4103 words
21 minutes
The Pi Comparison: What Claude Code's Open-Source Rival Reveals About Harness Design

Most “Claude Code vs the open-source alternative” articles are feature checklists. This one is not. We are not interested in which tool has more slash commands or a prettier terminal UI. We want to know what each harness is actually optimizing for, because that is the question that tells you which one belongs on your machine and when. The most useful foil for that question is Pi, the open-source coding agent built by Mario Zechner, because Pi was designed by someone who started from a clean sheet and asked a deliberately rude question: how much of the harness is load-bearing, and how much is habit?

Pi answers that question by deletion. It ships with a system prompt small enough to fit on one slide, a handful of primitive tools, no permission dialogs by default, and an extension model that is just TypeScript on disk. Claude Code answers it by inclusion: a large opinionated system prompt, a permission model, an auto-mode classifier, sandboxing, and a hook surface. Both answers are correct for their intended user. The interesting work is in seeing exactly where the two diverge and why.

Figure 1 - Diagram contrasting a minimal Pi harness (one-slide prompt, four primitives) against a feature-rich Claude Code harness across the design-space axes of trust, context, and extensibility.

Figure 1 - The harness design space: Pi and Claude Code sit at opposite ends of three axes: how much the system prompt tells the model, where containment lives, and how the harness is extended. Neither end is wrong. They are tuned for different engineers at different maturity stages.


What Claude Code Is Actually Optimizing For#

Start with the thing Pi deletes most aggressively: the system prompt. Zechner’s central design argument is that frontier models are now reinforcement-learning-trained to know they are coding agents, so the harness does not need to keep telling them. In his words, “It turns out frontier models are heavily RL trained to know what the coding agent is. So, why do you keep telling them that they’re a coding agent and how they should do coding tasks, right?” [2]. More bluntly: “You don’t need 10,000 tokens to tell them you’re a coding agent. They know, because they are coding agents now.” [3].

That 10,000-token figure is Zechner’s own estimate of the Claude Code system prompt, not a number Anthropic publishes [3]. The exact size shifts from release to release. The point is the order of magnitude and the direction of travel. Claude Code’s prompt is large and changes often, including its tool definitions, on essentially every release [2]. From Pi’s vantage point that instability is a defect. From Claude Code’s vantage point it is the product working as intended: the prompt is where Anthropic encodes safety behavior, permission-model description, and steering for the enormous range of people now running the tool. Zechner himself concedes the trajectory was deliberate, noting that over that period “the tool became a fit for a lot more people” [2].

This is the framing we want to hold for the whole article. Claude Code is optimizing for the median developer who has never thought about a harness in their life and should not have to. The opinionated defaults are a feature for that user. Pi is optimizing for the engineer who has outgrown defaults and wants to know, and control, exactly what their agent is doing. Neither is a mistake. They are tuned for different people.

Figure 2 - Diagram contrasting a stable minimal system prompt against a large prompt that changes every release and injects mid-session reminders into the model's working context.

Figure 2 - Two system-prompt strategies: A near-empty prompt stays stable across releases and leaves the context budget for the task. A large prompt changes often, including its tool definitions, and can inject reminders mid-session that compete with active work for the model’s attention.

Zechner’s specific complaint about Claude Code is sharper than “the prompt is big.” It is about timing. He describes the harness injecting context mid-session: “They would insert system reminders in the most in opportune place in your context telling the model, ‘Here’s some information. It may or may not be relevant to what you’re doing.’” [2]. Anyone who has watched a long Claude Code session has seen those reminders. The criticism is not that they exist; it is that they land in the middle of active work, where they compete for the model’s attention against the task. That is a context-engineering judgment call, and it is one of the places reasonable harness designers disagree.

KEY INSIGHT: The size of a system prompt is a design choice about how much you trust the model’s training versus how much you compensate for it in the harness. A bigger prompt is not automatically worse. The question to ask of your own harness is whether each token in it still earns its place, or whether it is there because it was there last release.


OpenCode: How a Minimal Harness Can Still Get It Wrong#

Before crowning minimalism, it is worth looking at a harness that tried to be open and lean and still made expensive mistakes. OpenCode is the obvious comparison, and Zechner spends a good portion of both talks on it, because it shows that “open-source and minimal” is not a guarantee of good design. The errors are specific and instructive.

The first is compaction. Zechner describes OpenCode calling session.compaction.prune on every turn, which “prunes all tool results um before the last 40,000 tokens” [2]. He then asks the audience the question every harness engineer should be asking: “What does this do to your prompt cache? Lost the prompt cache.” [2]. This is mechanically correct. Anthropic’s prompt cache keys on a stable prefix. If you rewrite the conversation history on every turn, you invalidate that prefix and force a full re-read at the standard rate instead of the discounted cache-read rate. A compaction strategy that fires every turn does not just cost a little extra; it negates one of the primary cost and latency benefits of running on Anthropic models at all.

Figure 3 - Diagram showing a stable prompt prefix preserving the cache on the left versus per-turn pruning invalidating the cached prefix on the right, forcing a full re-read.

Figure 3 - Compaction versus the prompt cache: A stable prefix lets the cache serve reads at the discounted rate. Pruning tool results on every turn rewrites the prefix, invalidates the cache, and forces a full re-read at standard cost. Compaction strategy is a load-bearing harness decision, not a detail.

Figure 4 - Diagram comparing per-edit validation that injects errors after every edit against per-completion validation that runs once when the agent thinks it is done.

Figure 4 - When to validate: Injecting language-server errors after every edit tells the model its incomplete work is broken and pushes it toward giving up. Running validation once, at the natural phase boundary when the agent is done, keeps the edit sequence clean.

The second error is the LSP-on-edit pattern. OpenCode, at the time of Zechner’s talk, injected language-server error feedback after every single edit tool call. His objection is about synchronization points: “You’re not writing a line of code, checking the errors, writing the next line, checking the errors. You don’t do that. You finish your work and then you check the errors. This confuses the model.” [3]. When the harness reports errors after edit one of ten, the model is told its incomplete work is broken, and “if you do this often enough, the model will just give up and that leads to very bad outcomes.” [2]. The principle generalizes: validation feedback belongs at phase boundaries, when the agent thinks it is done, not after every atomic operation. Zechner himself flags that OpenCode had changed this behavior by the time of his talk, so treat it as a cautionary design tale rather than a current bug report [2].

The third set of errors is not a judgment call. OpenCode shipped a local server with default CORS headers that allowed any website to reach it, which Zechner describes as RCE baked in by default and “open for a long time” [2]. This is documented as CVE-2026-22812, a CORS misconfiguration leading to remote code execution, alongside CVE-2026-22813 [4][5]. These are verified disclosures, not talk-stage characterizations. The lesson is the harshest one in harness design: the parts of the harness you do not think about, the local server you spun up for convenience, are exactly the parts that become your attack surface.

KEY INSIGHT: Minimal is not the same as correct. A small harness can still destroy your prompt cache, inject feedback at the wrong moment, or expose a local server to the open web. The discipline is not “fewer features.” It is being deliberate about every feature that remains, including the ones that run in the background.


What Pi Keeps, and Why#

Now the positive case. Pi keeps four things and trusts the model for the rest.

The first is the tiny system prompt. We read the actual prompt assembly in Pi’s source, and the core behavioral instruction is a single sentence telling the model it is an expert coding assistant working inside Pi that reads files, runs commands, edits code, and writes files. The rest of the static prose is a short guidelines list and a conditional documentation reference [6]. The full static block, before any tool schemas or project context are appended at runtime, is on the order of a few hundred tokens. Zechner characterizes it as roughly 200 tokens, small enough that the audience laughed when he put it on screen [2]. We will not quote a precise integer, because the prompt is assembled dynamically and no single number is correct across configurations. A few hundred tokens is the honest description.

The second is the tool set. Zechner’s philosophy framing is that a coding agent needs only four primitives: read, write, edit, and bash [3]. That was the talk-era description and it remains the design thesis. The currently shipped Pi enumerates seven built-in tools: read, bash, edit, write, grep, find, and ls [6]. The difference is not a contradiction; the three search-and-list tools are conveniences layered on the same minimal philosophy. We mention both because the gap between “the philosophy” and “the current build” is itself a useful reminder that you should always check the source rather than the slide.

Figure 5 - Comparison diagram of Pi's four philosophy primitives and its seven shipped tools (read, bash, edit, write, grep, find, ls) against a much larger feature-rich tool surface.

Figure 5 - The primitive tool surface: Pi’s design thesis is four primitives. The current build ships seven built-in tools. Both are tiny next to a feature-rich harness. The bet is that a frontier model composes primitives better than it navigates a large menu of specialized tools.

The third is trust by default. Pi runs in what Zechner calls YOLO mode: no per-action permission dialogs [2]. His argument is that real security comes from containment, running the agent inside a container with a controlled blast radius, not from asking a human to approve each command. We will come back to this, because it is the single sharpest philosophical disagreement between Pi and Claude Code, and the data on it is more interesting than either camp’s slogan.

The fourth is extensibility through code rather than configuration. Pi extensions are TypeScript modules, in the simplest case a single file on disk, in the published case an NPM package, and they hot-reload during a session [6]. The extension API exposes tools, slash commands, event hooks, session state, custom compaction, and custom providers. Zechner’s framing of the build loop is the part that sticks: “How do you build a Pi extension? You don’t. You tell Pi to build it for you based on your specifications and then you just iterate with it on that and hot reload during the session.” [3]. This is a meaningfully different model from Claude Code’s hooks, which Zechner critiques as shallow and as spawning a new process per hook [3]. Pi’s extensions run in-process and expose the full harness surface.

The empirical backbone under all of this is the Terminal Bench finding. The Terminal Bench project ships its own minimal harness, Terminus, which gives the model only the ability to send keystrokes to a tmux session and read back the output. No file tools, no sub-agents, none of the usual furniture. Zechner’s observation is that this bare interface “performs like top of the line of the entire leaderboard,” and does so “irrespective of model family,” often scoring higher than the model’s own native harness [2][3]. That is the strongest available evidence that harness features are not what drives task performance. Pi itself placed sixth on Terminal Bench in October 2025, running Opus 4.5 without any compaction at all [3]. We flag that as a dated historical placement, not a current ranking: Pi is not on the current Terminal Bench 2.0 board, whose top entries are other harness-and-model combinations [7]. The minimalism thesis is what survives; the specific Pi ranking is a 2025 snapshot.

Figure 6 - Diagram of the Terminus harness exposing only two capabilities, send keystrokes to tmux and read output, placing atop a benchmark leaderboard across model families.

Figure 6 - The minimalism finding: Terminus gives the model only tmux keystrokes and terminal output, and ranks at the top of Terminal Bench across model families, often beating the native harness for the same model. This is the empirical case that bare access is sufficient for a large class of tasks. Pi’s historical sixth-place run (October 2025, Opus 4.5, no compaction) sits in the same evidence column.


Tree-Structured Sessions: A Feature Worth Stealing#

Not everything Pi does is subtraction. Its session model is genuinely additive, and it is the one feature we wish every harness had. Standard fork mechanics in Claude Code and Codex are forward-copy: they take the context at the current position and copy it into a new thread. If you want to revisit an earlier decision, you had to anticipate it and fork proactively at the right moment.

Pi’s /tree command removes that requirement. It is documented in Pi’s official usage docs as a way to “Jump to any point in the session and continue from there” [6]. You navigate back to any past point and continue non-destructively, with every path you have explored preserved in the same session file. Pi also documents distinct /fork and /clone commands, so /tree is specifically the in-session navigator rather than a copy operation [6]. Community walkthroughs demonstrate richer behavior on top of this: rolling back with no summary, rolling back with the skipped context compacted, or rolling back while injecting a custom instruction at the branch point, and treating individual tool calls as navigable nodes you can interrogate after the fact. Those specifics are demonstrated behavior from community demos rather than documented spec, so we present them as such. The documented core, jump back anywhere and continue without losing history, is the part that matters and it is real.

Figure 7 - Diagram contrasting forward-copy forking, which branches only from the current position, against tree-structured sessions that branch retroactively from any past node.

Figure 7 - Forward-copy versus tree-structured sessions: Forward-copy forks branch only from where you are now, so you must anticipate the split in advance. A tree-structured session lets you jump back to any past point and continue non-destructively, with every explored path preserved in the same session file.

The reason this is worth stealing is that it changes how you debug agent behavior. When an agent makes a confusing tool call, you can roll back to that exact moment and ask it why it decided to do that, then patch whatever skill or instruction drove the decision, all inside the same session. That is a meta-debugging capability the forward-copy model cannot offer.


The Trust Question: Where Does Containment Actually Live?#

This is the disagreement that matters most, and it is where Pi’s YOLO default looks most reckless to a Claude Code user and most honest to a Pi user. Pi runs without permission dialogs and relies on containerization for safety. Claude Code asks for approval and layers on an auto-mode classifier and sandboxing. On the surface this looks like “no guardrails versus guardrails.” The data says the gap is narrower than it looks.

Anthropic’s own telemetry, published in its containment writeup, reports that users approved roughly 93% of permission prompts in practice [1]. Sit with that number. At a 93% approval rate, the permission tier is already most of the way to YOLO mode. The prompts are not functioning as careful review; they are functioning as a reflex. Anthropic drew the same conclusion and moved containment into the architecture rather than the prompt, building a sandbox boundary and an agentic auto-mode classifier, the latter catching roughly 83% of overeager behaviors before they execute [1]. The honest reframing is not “prompts versus no prompts.” It is “where does containment actually live,” and both Anthropic and Zechner landed on the same answer: in the environment, not in the human’s clicking finger. Pi just started there.

Figure 8 - Diagram reframing agent trust from a per-action permission prompt with a 93 percent approval rate toward containment that lives in the runtime environment, sandbox and blast-radius limits.

Figure 8 - Where containment lives: A 93% prompt-approval rate means the permission dialog is closer to YOLO mode than it looks. The load-bearing question is not whether the harness prompts you, but whether the environment caps the blast radius when a prompt is approved on reflex. Pi answers with containers; Claude Code answers with sandboxing plus an auto-mode classifier.

We are deliberately keeping this to a single beat. The full treatment of blast radius and the layered safe-mode model is the subject of the next article in this series. The point here is narrower: the comparison people reach for, “Pi is unsafe because it does not ask,” dissolves once you look at how often the asking actually changes anything.

KEY INSIGHT: A permission prompt that is approved 93% of the time is not a security control; it is a speed bump that trains you to tap “yes.” Real containment lives in the runtime environment, where a wrong decision is bounded regardless of who or what made it. Audit your own setup for prompts that you always approve, and move that safety somewhere it can actually hold.


Where This Leaves Multi-Provider Orchestration#

There is a second beat worth naming, because it is where the practitioner question gets real. Pi supports custom providers as part of its extension API, which means it can route to different model backends [6]. That makes it attractive as one node in a multi-provider setup, for example a Claude Code primary doing the building with a separate agent acting as an independent verifier. One practitioner, IndyDevDan, has described splitting his own work roughly 80% on Claude Code and 20% on Pi, offered as a personal workflow anecdote rather than a general recommendation.

When the question turns to actually orchestrating multiple providers in a disciplined way, our recommended starting point is Dotzlaw Consulting’s Bootstrap Framework, which treats the whole harness, agents, providers, and routing, as declarative state you can version and replay. Pi’s TypeScript extension model is the closest existing primary-source example of harness-as-versioned-code, and it is genuinely good prior art for the idea. The broader open-source landscape has parallel efforts in this space, Archon among them, which are useful to study as prior art. But for a team that wants a first-party orchestrator designed around the declarative-harness-state idea rather than a fork of someone else’s agent, the Bootstrap Framework is where we point people. We are ramping that work deliberately and will have more to say as it matures.

The real-world proof that the minimal-core approach scales is OpenClaw, an open-source project that embeds Pi’s SDK as its agent core [8]. It is the highest-profile deployment of Pi’s four-primitive philosophy in production, and it is a stronger argument for the design than any benchmark, because it is a real system that other people depend on. The minimal core turned out to be a good foundation to build something larger on, which is exactly the claim Pi makes about itself.


What Pi Trades Away#

Honesty requires the other column. Pi gives up the things Claude Code’s defaults provide for free. There is no opinionated safety prompt steering the model away from destructive patterns; you are trusting the model’s training and your container boundary. There is no built-in permission UI for the cases where you genuinely do want a human gate. The minimal tool set means the harness will not hold your hand through workflows that Claude Code packages out of the box. The extension-everything model also assumes you are comfortable writing and reviewing TypeScript that runs in your agent’s process, which is itself an attack surface if you install community extensions carelessly.

Figure 9 - Two-column diagram weighing what Pi gives back, control over prompt, tools, compaction and extensions, against what it trades away, opinionated defaults and packaged workflows.

Figure 9 - The trade, both columns: Pi gives back full control over the prompt, the tools, compaction, and extensions. It trades away the opinionated safety steering, the built-in permission gate, and the packaged workflows that make Claude Code productive for a newcomer on day one. The right costs for the right user.

These are real costs, and they are the right costs for the wrong user. A developer three weeks into using an agent should not be wiring up their own compaction strategy or auditing community extensions. Claude Code’s defaults exist precisely so that user can be productive without making twelve harness-design decisions first. Pi assumes you have already made those decisions and resents the harness making them for you. The ownership note here is worth stating plainly: Pi remains MIT-licensed and open source after Earendil acquired it on April 8, 2026, with the core agent staying open per the published licensing RFC [9][10]. The acquisition did not change the trade-off; it just put a company behind the open core.


Conclusion#

Claude Code and Pi are not really competitors. They are tools for different maturity stages of the same engineer. Claude Code is optimized for the median developer who benefits from opinionated defaults and should not have to think about the harness at all. Pi is optimized for the engineer who has outgrown those defaults and wants to know, and control, every token and every tool. The system-prompt size, the permission model, the compaction strategy, and the extension surface are all expressions of that single difference in target user.

The transferable lesson is not “switch to Pi.” It is to interrogate the defaults you have stopped noticing. The 10,000-token system prompt, the per-edit validation, the permission prompt you approve 93% of the time, the compaction that fires every turn: each of these is a design decision that someone made on your behalf, and each is worth re-examining against your own workload. Pi’s value to a Claude Code user is not as a replacement. It is as a mirror that shows you which parts of your harness are load-bearing and which parts are habit.

If you run Claude Code seriously, as we do with a customized .claude/ structure, a multi-agent team, a knowledge base, and hook-driven session setup, you are already expressing the same composable instinct Pi is built around. You are just doing it from inside the product rather than from a fork outside it. The next article in this series takes the trust question we opened here and follows it all the way down, into the five levels of agentic security and why the most interesting one starts by deleting the bash tool.


The Series#

This is Part 1 of the 3-part Harness Architecture & Security sub-series:

  1. The Pi Comparison: What Claude Code’s Open-Source Rival Reveals About Harness Design (this article). What Pi’s minimalism reveals about Claude Code’s design choices, and which harness trade-offs are actually load-bearing.
  2. Delete the Bash Tool: Five Levels of Agentic Security. The layered safe-mode model, blast radius, and why removing a single tool changes the threat model.
  3. Your Agent Harness Belongs in Git: The Case for Declarative Harness State. Treating the whole harness as versioned, replayable declarative state.

References#

[1] Anthropic, “How we contain Claude across products,” Anthropic Engineering, May 25, 2026. https://www.anthropic.com/engineering/how-we-contain-claude

[2] Mario Zechner, “Building Pi in a World of Slop,” AI Engineer Europe 2026, April 10, 2026. https://www.youtube.com/watch?v=RjfbvDXpFls

[3] Mario Zechner, “I Hated Every Coding Agent, So I Built My Own,” AI Engineer London #10 (hosted by Tessl), published March 31, 2026. https://www.youtube.com/watch?v=Dli5slNaJu0

[4] “RCE and file read vulnerability,” opencode GitHub Issues #6355, 2026. https://github.com/anomalyco/opencode/issues/6355

[5] “CVE-2026-22812: OpenCode RCE Vulnerability,” CVEReports.com, 2026. https://cvereports.com/reports/CVE-2026-22812

[6] Pi monorepo, badlogic/pi-mono (system prompt: packages/coding-agent/src/core/system-prompt.ts; commands and tools: packages/coding-agent/docs/usage.md), GitHub, observed 2026-06-15. https://github.com/badlogic/pi-mono

[7] Terminal-Bench 2.0 leaderboard, tbench.ai, observed 2026-06-15. https://www.tbench.ai/leaderboard/terminal-bench/2.0

[8] “OpenClaw,” Wikipedia. https://en.wikipedia.org/wiki/OpenClaw

[9] Earendil, “Announcing Pi & Lefos,” earendil.com, April 8, 2026. https://earendil.com/posts/announcing-pi-and-lefos/

[10] Earendil, “RFC 0015: Pi Licensing,” rfc.earendil.com. https://rfc.earendil.com/0015/

The Pi Comparison: What Claude Code's Open-Source Rival Reveals About Harness Design
https://dotzlaw.com/insights/claude-code-10-pi-comparison/
Author
Gary Dotzlaw, Katrina Dotzlaw, Ryan Dotzlaw
Published at
2026-07-20
License
CC BY-NC-SA 4.0

Building production AI, or modernizing a legacy system?

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.

Related reading

Claude Code Security: Building Defense-in-Depth with Five Primitives
Most Claude Code projects ship with zero security infrastructure. The same 5 building blocks you use for capability -- hooks, agents, skills, commands, and teams -- become a comprehensive defense-in-depth architecture when configured for security.
2026-01-27·Claude Code
The Development Workflow: How Seven Agents Turn a Ticket into Reviewed Code
One AI agent cannot research, plan, implement, review, and document effectively. Seven specialized agents can. Here is how we built a structured development workflow with handoff buttons, file-based artifacts, and cross-model orchestration for a large-scale enterprise codebase.
2026-03-23·GitHub Copilot
Beyond Code Completion: Building an AI Development Methodology with GitHub Copilot
GitHub Copilot suggests a line of code. Our enterprise codebase has 10,000+ functions across 22 modules. The gap between code completion and business context is where most AI adoption stalls. We closed it with 7 specialized agents, a code graph database, and a self-improving knowledge loop.
2026-03-22·GitHub Copilot
The Escalation Wave: Why Patches Work but Architecture Doesn't
Round 2 re-ran all 10 original attacks against patched code -- 8 were blocked (20% ASR). Then 7 new attacks hit structural weaknesses: Unicode zero-width characters bypassed every regex, 5 rapid requests crashed the server, and a pattern gap between security layers let 11 injection techniques through. Escalation ASR: 85.7%.
2026-03-03·AI Security
← Back to Insights