The Ultimate Agent Coding Workflow on OpenCode
The same state-of-the-art multi-agent coding harness as our Claude Code and Codex builds, moved onto OpenCode: an external TypeScript SDK conductor drives OpenCode over a headless server, with the orchestrator outside the agent graph. Run on a large enterprise codebase with 10,000+ functions across 22 modules, with a real per-agent permission frame (allow / ask / deny) as the enforcement boundary, best-in-class model-agnostic routing, experimental OTEL bridged to LangSmith, a 44% reversible tool-output token reduction, and an independent-judge gate that took task success from 0/3 to 3/3. A companion to our Claude Code, Codex, 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 and again as an external orchestrator driving Codex as an MCP server. This one moves it onto OpenCode, and the orchestrator stays outside the agent entirely: an external TypeScript SDK conductor (or a Pydantic AI v2 process) drives OpenCode over a headless opencode serve HTTP server, and every stage agent hangs off that conductor as a flat leaf. The runtime changed and the transport became a persistent server; the throughline did not. A large codebase is a knowledge-organization problem, not a context-window problem.

Figure 1 - The OpenCode Harness at a Glance: An external TypeScript SDK conductor (or Pydantic AI v2) drives OpenCode over a headless opencode serve HTTP server, dispatching seven stage agents in a flat fan because the orchestrator lives outside the agent graph. The pipeline runs inside a real per-agent permission frame (allow, ask, deny, with wildcards), with experimental OTEL export correlated into LangSmith. Underneath sits the same four-layer knowledge substrate mounted as MCP servers, with identity in AGENTS.md and native SKILL.md.
The Problem
The target is a large enterprise line-of-business application, the same one from our Copilot, Claude Code, Claude plus Pi, and Codex 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. Documenting the same answer on OpenCode matters because OpenCode is the strongest neutral host in the field: it gives you the strongest native parts of any non-Claude runtime and still ships no assembled pipeline, so the runtime decides how much you build yourself, and here you build the conductor.
What We Built
On OpenCode, the workflow is the same roster of narrowly scoped agents, but there is no in-runtime orchestrator to dispatch them. OpenCode always runs as a client plus a local HTTP server, so the idiomatic build is an external process, a TypeScript @opencode-ai/sdk conductor or a Pydantic AI v2 orchestrator, that drives opencode serve and treats each stage as a leaf on a flat fan. It sits 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 with the conductor outside the agent on a neutral, model-agnostic host. 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. On OpenCode the topology layer moves the orchestrator outside the agent graph, and the safety layer is a real per-agent permission frame.
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 OpenCode each role is a stage agent defined in a .opencode/agents/*.md file with its own model and its own permission block, and skills are native SKILL.md files that OpenCode reads directly, including from .claude/skills for free. The code graph, wiki, and issue history reach the agents as MCP servers, local or remote, configured in opencode.json.
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; on OpenCode it just means the reviewer is another flat leaf the external conductor dispatches, not a nested child.
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 OpenCode build; what OpenCode changes is the wiring around them, 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, and the Codex build inverted the topology so the orchestrator became external code. The OpenCode build keeps every one of those layers, keeps the orchestrator external, and trades Codex’s advisory-hook caveat for a genuine strength: a real per-agent permission frame that is the enforcement boundary.
| Dimension | Claude Code build | OpenCode build |
|---|---|---|
| Orchestrator | Claude Code main thread, in-runtime | External TypeScript SDK conductor or Pydantic AI v2, over a headless server |
| Transport | Native dispatch inside the thread | opencode serve HTTP + OpenAPI, async prompt plus SSE |
| Topology | Flat: one hub over seven leaves | Flat fan you enforce: nesting is unbounded, so hold depth at one |
| Security boundary | PreToolUse deny hook is a real boundary | Per-agent permission frame (allow / ask / deny) is a real boundary |
| MCP wiring | Native .mcp.json | Native, local and remote, via opencode.json |
| Model routing | Native per-agent selection | Best-in-class model-agnostic (Models.dev, 75+ providers, local possible) |
| Pipeline state machine | Orchestrator dispatches natively | You build the seven-stage DAG and both gates externally |
| Tracing | Native LangSmith (stop hook or plugin) | Experimental OTEL, correlated into LangSmith over OTLP |
| Cost model | Flat-rate on Max, Opus orchestrator free at the margin | Provider-dependent: billing follows whichever provider each tier resolves to |
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. On OpenCode there is no native pipeline, so the external conductor is the state machine: it reads a work list, opens a session against opencode serve, dispatches each stage to a fresh stage agent, 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 OpenCode the external conductor owns the sequence, so the pipeline is a program you write, not a runtime feature you configure. 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 agent writes a findings file, the planner reads it cold and writes a plan, the implementer reads the plan cold and writes code. Each agent 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. On OpenCode this discipline is also what keeps the headless server honest: because OpenCode ships no seven-stage state machine, the durable artifacts on disk are how one stage’s output becomes the next stage’s input, and a restart reconnects to opencode serve and resumes from files rather than from a lost session.
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 conductor is a program you write, so this loop is an edge in its state machine, not a convention you hope the agents follow: a failing verify closes the implementer’s session and opens a fresh planner session against opencode serve with the failing evidence attached. 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 OpenCode it mounts as an MCP server inopencode.json, reachable by every stage agent. - 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. On OpenCode the issue history is one of the MCP servers you build, because there is no native episodic layer.
- 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 also 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. OpenCode reads the same
SKILL.mdformat natively, and reads.claude/skillsas well, so the procedural layer ports with no work at all.

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. On OpenCode the four layers mount as MCP servers and identity lives in AGENTS.md.
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 OpenCode, 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. On OpenCode the emission is real but young: OpenCode’s OpenTelemetry export is experimental, so the LangSmith spine is a shim in the same shape as on Codex, but you are bridging from an experimental emitter. You point OpenCode’s OTEL export at LangSmith’s OpenTelemetry ingest and own the span correlation into one pipeline-run trace, and you keep an eye on the export because it is not yet a settled feature. The payoff is the same as on the other runtimes: 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 OpenCode through an experimental OTEL export correlated into LangSmith over OTLP. 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 to state. 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 OpenCode differs most, and where its neutral-host strength is clearest. OpenCode gives you strong stage agents, native MCP in both local and remote form, best-in-class model-agnostic routing, a real permission frame, and a headless server with an OpenAPI surface and a TypeScript SDK. What it does not ship is a seven-stage state machine or the gates. So the conductor is external code: a TypeScript @opencode-ai/sdk program or a Pydantic AI v2 process that drives opencode serve and dispatches each stage as a flat leaf. The transport is a persistent HTTP server, async prompt plus SSE, rather than Codex’s driven-as-an-MCP-server shape, but the principle is identical: the orchestrator lives outside the agent graph.

Figure 7 - The Flat Fan: An external TypeScript SDK conductor drives OpenCode over a headless opencode serve HTTP server and fans out to seven stage agents kept deliberately flat. OpenCode allows subagent nesting with no depth cap and no circuit breaker, so the discipline is to keep the orchestrator outside the agent graph, hold depth at one, and fork in parallel only at the two reviewers. Flatness is not enforced for you here as it is on Claude Code; you enforce it yourself.
That flat discipline is the sharpest OpenCode-specific caution in the whole build, and it is the inverse of the Claude Code constraint. Claude Code forbids nesting outright, so flatness is enforced for you. Codex caps nesting at one level, so it cannot run away. OpenCode allows nesting with no depth cap and no circuit breaker, a behavior its own issue tracker documents, which means a stage agent that spawns a stage agent can recurse without a natural floor. The safe topology is therefore self-imposed: the conductor sits outside the agent graph, every stage is depth one, and the only concurrency inside the pipeline is the parallel review fork. Nesting is a capability you keep switched off by design, not a wall the runtime provides.
The strongest current framework for that external conductor is Pydantic AI v2, and it maps onto this architecture unusually cleanly. Its typed, schema-validated structured outputs are the stage gates and the refinement gate, because a gate is a branchable typed verdict object. Its agent delegation and graphs are the seven-stage sequence and the parallel review fan-out. Its durable execution with first-class human-in-the-loop approval is the restart-safe run and the gate that pauses for a person. Its Logfire and OpenTelemetry emission is the trace spine, and its MCP client is how the substrate mounts. 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 OpenCode TypeScript SDK and Pydantic AI v2 are two instances of the same slot: an external, typed conductor over the headless server.
Two orchestration cautions carry across from the research. 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 a flat fan of scoped stage agents dispatched by one conductor is exactly that role separation. The second is parallel fan-out via git worktrees, one worktree per work item, so parallel file mutation never collides and a plain git merge resolves two half-solutions mechanically. On OpenCode that pattern needs care because there is no native worktree flag, and each parallel lane needs its own opencode serve port, so worktree isolation is a pattern you enforce with a worktree plus a port per lane, not a native guarantee. We present it 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. OpenCode’s model-agnostic routing is best-in-class, drawing on Models.dev and more than seventy-five providers including local models, so preserving the same constant map is trivial and the comparison across runtimes stays clean. Local models are possible here in a way they are not on the vendor-locked runtimes, though we hold the published map for this build. 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. On OpenCode the gate has a native expression: a permission: ask verdict on the write, so the runtime itself pauses the edit for a human rather than relying on the conductor to remember to. 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. On OpenCode you can wire that gate straight into the permission frame as an ask verdict.
Quality, Safety, and Economics
Safety is a stack, not a reviewer. Each layer catches what the others miss, and on OpenCode the second layer is a genuine strength rather than a caveat: the permission frame is a real enforcement boundary, not advice.
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 the permission frame, and here OpenCode is the opposite of Codex in a way that matters: its per-agent permission system (allow, ask, deny, with wildcards) is a real boundary the runtime enforces, not an advisory hook the agent can talk past. A tool call must clear its permission verdict before it reaches application state, allow passes, deny blocks, and ask routes to a human, and a separate security-reviewer stage agent still 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 Permission Frame: OpenCode’s per-agent permission system (allow, ask, deny, with wildcards) is a real enforcement boundary, not advice. A tool call from a stage agent must clear its permission verdict before it can reach application state: allow passes, deny blocks, and ask routes to a human, which is exactly how the refinement gate is expressed. This is the opposite of an advisory hook that can only warn, and it is the sharpest reason OpenCode is a strong neutral host.
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 OpenCode the tiers resolve through model-agnostic routing, and billing follows whichever provider each tier picks.
OpenCode’s billing is provider-dependent, which changes the economics conversation from the one on Max or on Codex. There is no single flat-rate plan and no single metered API; the model map resolves through Models.dev to whatever provider each tier names, and the bill follows that provider. That is exactly why the constant Opus 4.6 and Sonnet 4.6 map is easy to hold here, and why the routing decision matters: the flagship tier is confined to the two low-volume, high-leverage roles so that whatever a provider charges, the expensive model runs only where it earns its cost. The re-feed problem is the other cost lever, because 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. 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]. That is one author’s five-task private benchmark, so we read it as directional rather than definitive. The mitigation 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]. OpenCode reads raw files, so AST compression applies, and our implementation plugs in as an MCP server or a plugin between the tool and the agent. We built that 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 provider-metered tier that reduction is money, 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. Compress that output reversibly and by content type, and you cut the bill at its actual source while losing nothing, because the original is one retrieve(id) call away.

Figure 11 - Tool-Output Compression: A large raw tool result passes through a content router into a type-aware compressor (AST-strip for code, field-prune for JSON, smart-filter for shell). A compact payload goes to the OpenCode agent carrying a retrieve(id) handle, while the original is cached in a store. On OpenCode the layer plugs in as an MCP server or a plugin between the tool and the agent, and the measured result on a real session is a 44% reduction in tool-output tokens, fully reversible.
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. Codex provides strong parts and no assembled pipeline, so the orchestrator becomes external code. OpenCode is the strongest neutral host of the non-Claude runtimes: native MCP both directions, a real permission boundary, native skills that even read Claude’s own skill folder, and best-in-class model routing, with the conductor still external and the trap being nesting you must switch off yourself.

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 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 worth stating plainly, because it applies to OpenCode the moment you route an Anthropic model through it. 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. Armin Ronacher, who builds the Pi harness, reported exactly this effect and Simon Willison relayed it: the newest Claude models are worse than their older siblings at correctly calling Pi’s edit-tool schema, appending invented fields to the call so the harness rejects it and the model retries [8][9]. Ronacher’s proposed cause, reinforcement-learning post-training toward Claude Code’s own edit tool, is his theory rather than an Anthropic-confirmed mechanism, and the account is a qualitative developer report with no published failure rate. OpenCode’s whole appeal is running any model, including Claude, through a neutral host, which makes the mitigation worth building in from the start: keep each stage agent’s edit-tool schema close to what the chosen model is trained on, and validate tool calls at the boundary so a malformed call is caught and retried rather than silently mis-applied. The neutral host is a strength, and this is the one place it asks for care.
The same architecture ports to one more runtime, its own writeup: Cursor. For every non-Claude-native runtime the orchestrator stays external code, and Pydantic AI v2 is the strongest current framework for that slot, the typed, model-agnostic conductor this build already leans on. The pattern the OpenCode build makes sharpest, that a real permission boundary can carry the enforcement an advisory hook cannot, is the safety lesson that closes the series.
Conclusion
The workflow that ran on GitHub Copilot, then on Claude Code, then as an external orchestrator over Codex, survives its move to OpenCode 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 OpenCode proves the point on the most model-agnostic host in the field: the substrate, the gates, and the safety stack port without change, while the conductor stays external, the permission frame carries real enforcement, and the model map holds because routing is provider-agnostic.
Two honest costs come with that. OpenCode ships no seven-stage state machine, so you build the conductor and both gates yourself, and its subagent nesting is unbounded with no circuit breaker, so the flat topology is a discipline you enforce rather than a wall the runtime provides. Neither changes the architecture; they change what you assemble and what you keep switched off. That is the entire reason to document this workflow across runtimes: the design is the constant, and each runtime tells you which parts it hands you, which you build, and which you must guard against. The last writeup takes the same stack to Cursor, where the orchestrator stays external and the affordances shift one final time.
Technologies
| Layer | Technology |
|---|---|
| Runtime | OpenCode stage agents (.opencode/agents/*.md, each own model + permission block), driven over a headless opencode serve HTTP server; flat fan, depth held at one |
| Orchestrator | External TypeScript @opencode-ai/sdk conductor or Pydantic AI v2 process over opencode serve (HTTP + OpenAPI, async prompt plus SSE); typed gates, durable execution, human-in-the-loop approval |
| Code graph | CodeGraphContext (CGC) over Neo4j, mounted as an MCP server in opencode.json |
| Knowledge substrate | File-based domain wiki, dated issue history, native SKILL.md (also reads .claude/skills), MapKit navigation map; identity in AGENTS.md |
| Traceability | Experimental OTEL export correlated into LangSmith over OTLP; TraceKit for cost and reliability harvest |
| Compounding | FlywheelKit gated refinement (gate expressed as permission: ask), Deterministic Gate Harness, the three-M blast-radius gate |
| Safety | Real per-agent permission frame (allow / ask / deny, wildcards), security-reviewer stage agent, RubricGate, Ingest-Guard, Trust-Ladder Deployer, typed-SDK action gate |
| Economics | Model-tier routing by cost per task on provider-agnostic Models.dev routing, prompt caching, ContextLedger compression as an MCP server or plugin |
| Models | Anthropic Opus 4.6 (orchestrator, planner), Sonnet 4.6 (implementer, reviewers, documentation, skill roles), routed model-agnostically (local models possible) |
As a Consulting Engagement
This is how we run a harness-engineering engagement when a client wants a neutral, model-agnostic host and the orchestrator as their own external code rather than a single vendor’s runtime. We assess the codebase, stand up the four-layer substrate as MCP servers and the trace spine, build the external conductor and both gates (Pydantic AI v2 or the OpenCode TypeScript SDK for that slot), put the enforcement into the per-agent permission frame where OpenCode actually enforces it, and route models by cost per task rather than cost per token. 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 OpenCode build is the right call specifically when a team wants provider independence, including the option of local models, and a real permission boundary rather than an advisory one. 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 fourth 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: the hybrid that puts a Claude orchestrator over Pi workers to recover nested teams and deeper TypeScript hooks.
- The Ultimate Agent Coding Workflow on Codex: the external OpenAI Agents SDK or Pydantic AI v2 orchestrator driving Codex as an MCP server in a star topology, with a two-ring security model.
- The Ultimate Agent Coding Workflow on OpenCode (this writeup): an external TypeScript SDK conductor over a headless server, with a real per-agent permission frame and best-in-class 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.