Course: Master Course · Deep-Dive: DD-03 · Duration: 60 min · Prerequisites: Modules 0–12, DD-01, DD-02
156,000+ stars. The largest codebase in the terminal-harness category. Client/server architecture enabling remote sessions. The medium-thick reference.
| Metric | Value |
|---|---|
| Language | TypeScript |
| Stars | 156,000+ |
| License | MIT |
| Tools | ~15 |
| System prompt | ~5,000 tokens |
| Permission model | Session-scoped |
| Architecture | Client/server |
| Memory | Server-side persistent sessions |
| Context mgmt | repo-map + session truncation |
OpenCode is the largest terminal harness by stars (156K+) and the reference for the client/server architecture in the CLI-harness category. The key architectural decision: the harness loop runs as a server, and the client connects to it — enabling remote sessions, Docker sandboxing of the server, and multi-client access. On Module 0.1's thickness spectrum, OpenCode sits squarely in the medium-thick band — substantially larger than Pi's ~1,200 lines and Aider's monolithic single-process design, and the only CLI harness in the roster where the loop is a separate long-running service.
The client/server split is the load-bearing decision and the source of every downstream capability that distinguishes OpenCode:
This split is why OpenCode can sandbox effectively (the server is containerized; the client is just a UI) while Pi and Aider cannot (their loops run directly in the user's terminal process, so containerizing the loop means containerizing the user's shell). The client/server architecture is the prerequisite for Module 5's outside-sandbox pattern in a CLI context — the sandbox lives where the loop lives, and in OpenCode the loop lives somewhere the user's shell doesn't.
[client TUI] ←socket/transport→ [server: loop + tools + creds] → Docker container
stateless containerized network-isolated
read, write, edit, bash, search, lsp-integrated operations (go-to-definition, find-references, hover), plus remote-session tools. More than Aider's ~8; justified by the richer use case (LSP integration enables precise code navigation instead of text-grep heuristics). The tool registry follows Module 2's schema-first pattern — each tool is a JSON schema definition, same as Pi, just more of them.
More sophisticated than Aider — OpenCode uses a combination of repo-map (like Aider) and session-based context management with truncation when a session approaches the model's window. Still not as advanced as Claude Code's active compaction or Tau's non-destructive compaction tree (DD-21), but a real Module 3 implementation. The session-boundary truncation is what keeps long sessions functional where Pi's context rots.
Credential flow: API keys live in the server process (containerized), not the client. The agent's tool-execution context is inside the container; credentials can be mounted read-only and withheld from the tool surface. This is the strongest credential-isolation story in the CLI-harness category — Module 5's "keep credentials outside the agent's reach" realized as an architectural property.
Shell/exec/write paths: bash, write_file, and edit execute inside the container. A compromised agent process can affect the container filesystem and make network calls only if the container's network policy permits. Blast radius is bounded by the container, not the host — the defining difference from Pi/Aider/Codex CLI.
Injection test (reasoned): OpenCode still has no untrusted-content tagging on file reads. A file read via read that contains injected instructions enters context as raw content (Module 2.4 Vector 1, ASI01). The sandbox contains the blast radius of compliance; it does not prevent the injection itself. Same gap as Pi/Aider; the sandbox just makes the consequences less catastrophic.
| Module | Score | Key decision | vs Aider |
|---|---|---|---|
| 1 Loop | 4 | ReAct + client/server | = |
| 2 Tools | 4 | ~15, LSP-integrated | = (more tools, but justified by LSP) |
| 3 Context | 4 | repo-map + session truncation | = |
| 4 Memory | 4 | session-based + server-side persistence | +1 |
| 5 Sandbox | 4 | Docker (server containerized) | +3 |
| 6 Permission | 3 | session-scoped | = |
| 7 Errors | 3 | standard | = |
| 8 State | 3 | server-side | = |
| 9 Verification | 2 | limited | -1 |
| 10 Subagents | — | n/a | = |
| 11 Observability | 3 | structured (server-side) | = |
| 12 Prompt | 4 | ~5k | = |
| TOTAL | 34/60 | +2 vs Aider |
The +2 over Aider comes almost entirely from the sandboxing advantage (+3 on Module 5, partially offset by -1 on verification). The client/server architecture is the enabler — without it, Docker sandboxing of the loop is impractical in a CLI context.
OpenCode optimizes for remote-capable, sandboxed coding sessions via client/server architecture — the loop runs in a Docker container, the client is a stateless UI. It sacrifices simplicity (the largest codebase in the category) and verification (no built-in test-gate). Build on OpenCode for remote/team coding sessions requiring sandboxing; it is the most architecturally mature CLI harness at scale.
The client/server split enables real sandboxing (Module 5) — the server is containerized, credentials can be kept outside the agent's reach. This is OpenCode's defining security property: it is the thinnest CLI harness that can credibly claim multi-tenant-ready isolation.
# Deep-Dive DD-03 — OpenCode: Client/Server Architecture **Course**: Master Course · **Deep-Dive**: DD-03 · **Duration**: 60 min · **Prerequisites**: Modules 0–12, DD-01, DD-02 > *156,000+ stars. The largest codebase in the terminal-harness category. Client/server architecture enabling remote sessions. The medium-thick reference.* --- ## Learning Objectives 1. Apply the 6-phase methodology to OpenCode; produce a scored card. 2. Explain OpenCode's client/server split as the enabler of remote sessions and Docker sandboxing. 3. Compare OpenCode (medium-thick) against Aider (thin-medium) and Pi (thin). 4. State why the client/server architecture is the foundation for OpenCode's sandboxing advantage. --- ## The Subject | Metric | Value | | --- | --- | | Language | TypeScript | | Stars | 156,000+ | | License | MIT | | Tools | ~15 | | System prompt | ~5,000 tokens | | Permission model | Session-scoped | | Architecture | Client/server | | Memory | Server-side persistent sessions | | Context mgmt | repo-map + session truncation | OpenCode is the largest terminal harness by stars (156K+) and the reference for the **client/server architecture** in the CLI-harness category. The key architectural decision: the harness loop runs as a server, and the client connects to it — enabling remote sessions, Docker sandboxing of the server, and multi-client access. On Module 0.1's thickness spectrum, OpenCode sits squarely in the medium-thick band — substantially larger than Pi's ~1,200 lines and Aider's monolithic single-process design, and the only CLI harness in the roster where the loop is a separate long-running service. ## Architecture — Client/Server, the Defining Split The client/server split is the load-bearing decision and the source of every downstream capability that distinguishes OpenCode: - **Server**: the loop, tool execution, context management, memory. Runs in a Docker container (sandboxed). Holds the model API credentials. Persists session state across client disconnects. - **Client**: the terminal UI. Connects to the server via a local socket or remote transport. Stateless — can reconnect, switch machines, or run headless. Multiple clients can attach to one server (team/shared sessions). This split is why OpenCode can sandbox effectively (the server is containerized; the client is just a UI) while Pi and Aider cannot (their loops run directly in the user's terminal process, so containerizing the loop means containerizing the user's shell). The client/server architecture is the prerequisite for Module 5's outside-sandbox pattern in a CLI context — the sandbox lives where the loop lives, and in OpenCode the loop lives somewhere the user's shell doesn't. ``` [client TUI] ←socket/transport→ [server: loop + tools + creds] → Docker container stateless containerized network-isolated ``` ### Tools (~15) read, write, edit, bash, search, lsp-integrated operations (go-to-definition, find-references, hover), plus remote-session tools. More than Aider's ~8; justified by the richer use case (LSP integration enables precise code navigation instead of text-grep heuristics). The tool registry follows Module 2's schema-first pattern — each tool is a JSON schema definition, same as Pi, just more of them. ### Context management More sophisticated than Aider — OpenCode uses a combination of repo-map (like Aider) and session-based context management with truncation when a session approaches the model's window. Still not as advanced as Claude Code's active compaction or Tau's non-destructive compaction tree (DD-21), but a real Module 3 implementation. The session-boundary truncation is what keeps long sessions functional where Pi's context rots. ## Key Design Decisions 1. **Client/server over monolith.** This is the decision every other choice flows from. It costs complexity (the largest codebase in the category, ~25k+ LOC) and gains sandboxability, remoting, and multi-client access. Module 0.1's three-job separation is realized here as a process boundary, not just a code boundary. 2. **Docker as the default sandbox.** The server container is the blast-radius container. Credentials live outside the agent's reach. This is the Module 5 outside-sandbox pattern in its CLI-native form. 3. **Session-scoped permissions.** Permissions attach to a session, not globally. Reconnecting to a session restores its permission set. This is a middle ground between Pi's trust-the-model and Codex CLI's 3-tier model (DD-04). ## Phase 4 — Security Audit **Credential flow**: API keys live in the server process (containerized), not the client. The agent's tool-execution context is inside the container; credentials can be mounted read-only and withheld from the tool surface. This is the strongest credential-isolation story in the CLI-harness category — Module 5's "keep credentials outside the agent's reach" realized as an architectural property. **Shell/exec/write paths**: `bash`, `write_file`, and `edit` execute inside the container. A compromised agent process can affect the container filesystem and make network calls only if the container's network policy permits. Blast radius is bounded by the container, not the host — the defining difference from Pi/Aider/Codex CLI. **Injection test (reasoned)**: OpenCode still has no untrusted-content tagging on file reads. A file read via `read` that contains injected instructions enters context as raw content (Module 2.4 Vector 1, ASI01). The sandbox contains the *blast radius* of compliance; it does not prevent the *injection itself*. Same gap as Pi/Aider; the sandbox just makes the consequences less catastrophic. ## Score & Synthesize | Module | Score | Key decision | vs Aider | | --- | --- | --- | --- | | 1 Loop | 4 | ReAct + client/server | = | | 2 Tools | 4 | ~15, LSP-integrated | = (more tools, but justified by LSP) | | 3 Context | 4 | repo-map + session truncation | = | | 4 Memory | 4 | session-based + server-side persistence | +1 | | 5 Sandbox | 4 | Docker (server containerized) | **+3** | | 6 Permission | 3 | session-scoped | = | | 7 Errors | 3 | standard | = | | 8 State | 3 | server-side | = | | 9 Verification | 2 | limited | -1 | | 10 Subagents | — | n/a | = | | 11 Observability | 3 | structured (server-side) | = | | 12 Prompt | 4 | ~5k | = | | **TOTAL** | **34/60** | | **+2 vs Aider** | The +2 over Aider comes almost entirely from the sandboxing advantage (+3 on Module 5, partially offset by -1 on verification). The client/server architecture is the enabler — without it, Docker sandboxing of the loop is impractical in a CLI context. ### Architect's Verdict > *OpenCode optimizes for remote-capable, sandboxed coding sessions via client/server architecture — the loop runs in a Docker container, the client is a stateless UI. It sacrifices simplicity (the largest codebase in the category) and verification (no built-in test-gate). Build on OpenCode for remote/team coding sessions requiring sandboxing; it is the most architecturally mature CLI harness at scale.* ### MLSecOps Relevance > *The client/server split enables real sandboxing (Module 5) — the server is containerized, credentials can be kept outside the agent's reach. This is OpenCode's defining security property: it is the thinnest CLI harness that can credibly claim multi-tenant-ready isolation.* ### 3 things OpenCode does better 1. **Client/server = sandboxable**: the only CLI harness where Docker sandboxing is architecturally native. Module 5's outside-sandbox pattern, realized. 2. **LSP integration**: precise code navigation (go-to-definition, find-references) as tools, not just text search. Module 2 done right. 3. **Remote sessions**: connect from any client; the server persists. Enables team/shared sessions, headless runs, and reconnecting to long tasks. ### 3 things to fix 1. **Add computed verification (test gate)** — Module 9 is weak; the most production-mature CLI harness should not ship without a verification hook. 2. **Legibility** — the large codebase (~25k+ LOC) reduces legibility vs Pi/Aider; documentation of the client/server boundary would help. 3. **Add untrusted-tagging on file reads** — same injection gap as Pi/Aider (Module 2.4). The sandbox contains blast radius; it does not prevent injection. --- ## References 1. **OpenCode source** — the client/server reference for the CLI-harness category. 2. **DD-01 (Pi)** — the thin baseline; same schema-first tool pattern, opposite thickness. 3. **DD-02 (Aider)** — the thin-medium comparison; same category, monolithic vs client/server. 4. **DD-04 (Codex CLI)** — same total score (34/60), opposite bet (language-level vs architecture-level). 5. **DD-06 (oh-my-opencode)** — the meta-harness layered on top of OpenCode. 6. **Module 0.1** — thickness spectrum; OpenCode as the medium-thick reference. 7. **Module 5** — inside vs outside sandbox; OpenCode's client/server enables the outside pattern. 8. **Module 2.4** — untrusted-content tagging (the missing injection defense).