anomalyco / anomalyco/opencode
question(v2): supported session isolation model for multi-workspace clients
@kitlangton is already working on this.
Since Aug 21, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Question
What is the supported OpenCode V2 architecture for a multi-workspace client that needs shared sessions and configuration but also needs workload isolation? Should integrations use the one global daemon, multiple isolated servers, or a future SessionExecution placement layer, and what storage, ownership, event, and fencing rules make that topology safe?
Summary
CodeNomad is migrating from one OpenCode V1 server process per workspace to the native OpenCode V2 architecture. Following the V2 documentation leads to one user-wide background server for every workspace, window, session, subagent, permission, and tool execution, but neither the documentation nor the API defines the isolation, fairness, capacity, or multi-process placement contract required by a multi-workspace client.
We need guidance on the supported architecture. Today we cannot determine whether an integration should accept one shared execution process, create private servers, or wait for clustered session placement. Each option has correctness or responsiveness risks that the public contract does not resolve.
CodeNomad Integration Context
CodeNomad is a public Electron/Tauri client that can keep many workspaces, windows, tabs, sessions, and background subagents active concurrently.
Its V1 architecture started one opencode serve --port 0 process per workspace, giving each workspace an OS process, port, lifecycle, and failure boundary (previous runtime).
The V2 migration deliberately removed that architecture and followed the native V2 model:
- The migration replaces per-workspace runtimes with one externally owned global service (migration summary).
- A CodeNomad workspace is now a logical instance over an OpenCode
LocationRef, not a process (workspace model). OpenCodeSharedServiceholds one endpoint and one generated client (service adapter).WorkspaceManagerreuses that service for every location (manager).- One upstream
client.event.subscribe()stream is routed to all logical workspaces (event bridge).
This is not a theoretical concern. In #43891, heavy background-subagent activity in one V2 session makes navigation and text input across the TUI sluggish even though the service remains healthy and total host CPU is not saturated. For CodeNomad, the same shared execution plane serves every independent workspace and native window, so one workload can affect the entire application rather than one tab.
What The Documentation Says
The V2 CLI documentation says:
By default, OpenCode discovers or starts one shared background server for your user account. Every local OpenCode client connects to that server, which owns sessions, configuration, integrations, permissions, and tool execution.
It offers --standalone for a private server and --server for an explicit endpoint.
The V2 client documentation tells Node integrations to use Service.ensure(). It also permits a custom registration file and service command, which appears to make multiple managed endpoints possible.
The troubleshooting documentation describes one standard registration, one service configuration, and one default database. It documents OPENCODE_DB as an override, but does not define whether private or custom servers should share or isolate that database.
The agents documentation documents foreground and background subagents in child sessions, but gives no global or per-session concurrency limit and no fairness/backpressure guidance for shared-service clients.
These pages describe the available modes, but they do not define which topology is safe for an application that needs shared user state and concurrent workload isolation.
What Beta 17793 Implements
The installed 0.0.0-beta-17793 release was built from 4d22d4e.
- Default clients resolve one managed endpoint;
--standalonestarts a private child server for the entire client invocation (connection selection, standalone process). SessionExecutionexplicitly runs drains in the current process (execution layer).- Different sessions use keyed Effect fibers, not dedicated worker threads or processes (run coordinator).
- A subagent is a child session registered in the process-local Job service (subagent, job registry).
- The V2 session specification states: "Local execution remains process-owned until clustering introduces an explicit placement and fencing protocol" (session specification).
- Restart recovery assumes every orphaned claim owner is dead, and the source explicitly says claims are recovery markers rather than locks (restart recovery, claims are not locks).
No session worker pool, process-placement configuration, documented global subagent limit, or cross-process execution fencing was found in this release.
Related Issues
- #31307 concerns V1 instances unintentionally sharing SQLite state. This issue asks for the supported V2 topology and explicitly avoids assuming that multiple servers may safely share the database.
- #39181 concerns incorrect cross-directory event application. CodeNomad already routes one upstream stream by native location; event scoping does not provide execution isolation or session placement.
- #38849 concerns V1 multi-process SQLite contention. CodeNomad's single V2 daemon avoids multiple database writers, but it also removes the former workspace process boundary. Returning to private servers without a documented storage/fencing model risks reintroducing that class of failure.
Why The Available Choices Are Insufficient
One shared daemon
This preserves one session database, permissions, integrations, configuration, and event stream. It also puts all CodeNomad workspaces and subagents in one process-local execution plane, with no documented fairness or isolation guarantee.
One private server per workspace or active session
This restores OS-level isolation, but the supported ownership model is unclear:
- Should each server use a separate database, losing global session/state visibility?
- Is it safe for multiple unregistered/private servers to use the standard database concurrently?
- How is a session prevented from executing in two servers when execution claims are not locks?
- How should sessions move between locations or processes?
- Which process owns permissions, integrations, plugins, configuration, and restart recovery?
- How should an integration aggregate event streams without losing ordering or duplicating global events?
- How should host and WSL services coexist while preserving location ownership?
--standalone alone does not answer these questions. It creates a process boundary for a whole CLI invocation, not session placement behind one long-lived integration.
Integration-managed routing
CodeNomad could invent a coordinator and partition storage itself, but that would duplicate OpenCode lifecycle, ownership, recovery, and fencing policy outside the native API. It would also rely on undocumented database and execution semantics.
Requested Contract Or Guidance
Could the V2 team clarify the intended architecture for multi-workspace integrations?
- Is one global daemon the only supported topology when sessions and state must remain shared?
- What responsiveness, fairness, or backpressure guarantees should clients expect across unrelated sessions and subagents?
- Is concurrent use of multiple private/custom servers supported, and if so, must their databases and config directories be isolated?
- Is a session guaranteed to execute in at most one server process? If so, what provides placement, leases, and fencing?
- Is the
SessionExecutionboundary intended to gain a worker/process pool or remote placement implementation? - Is there a recommended short-term global or per-session subagent concurrency limit?
- How should an embedding application retain one logical event/permission/session view while execution is distributed?
Any of these outcomes would unblock the migration:
- documented fairness/backpressure guarantees for the shared daemon;
- a supported coordinator/worker topology with session affinity and fencing;
- or a documented multi-server isolation recipe covering registration, storage, events, permissions, and recovery.
We are not asking OpenCode to add CodeNomad-specific APIs. We need a supported V2 execution and ownership contract so integrations do not have to choose between global state correctness and workload isolation.
Environment
- OpenCode runtime:
0.0.0-beta-17793 - OpenCode source revision for references:
4d22d4e75fb949db5a6302cc605e9af87ea671bf - CodeNomad V2 migration revision:
3445de6b20b51cf4f0f78bca703a69b5d6a13023 - OS used for the observed responsiveness problem: Windows 10.0.26200.9168, 24 cores / 32 logical processors
- Related runtime symptom: #43891
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.