Architecture
CodeSpace separates the agent's decisions from workspace execution. The MCP server owns authorization and operation records. A Runner performs already-authorized filesystem and process work. Codex libraries stay behind adapters.
Current layout
External Agent Loop
→ MCP server: registry, policy, patch records, work/instruction queue
→ Runner
├─ InProcessRunner (default)
└─ UdsRunner → codespace-codex-runtime → InProcessRunner
├─ file operations → codespace-fs
├─ patch transaction → codespace-patch
└─ process supervisor
├─ pipes / codespace-pty
└─ Linux helper when available → sandbox / managed proxyThe UDS worker and default runner both execute on the same host. A Linux command sandbox can wrap either runner's spawn path. Neither path dispatches into the Compose container fixture.
Responsibilities and state
| Component | Responsibility |
|---|---|
server | MCP transport, HTTP authentication/inbox, request validation and orchestration |
domain | CodeSpace tool parameters, results, IDs, error and execution types |
policy | Registered roots, environments, profiles, and network policy |
store | SQLite patch operations, confirmation holds, logical works, user instructions; in-memory occupancy |
runner | Execution DTOs, file scope, patch transaction, process supervision, UDS client/server protocol |
| Isolated adapters | Codex patch, PTY, filesystem, worker hardening/socket, Linux sandbox mechanisms |
Patch operations, confirmation holds, and works/intents survive restart only with a configured SQLite file. Process handles and occupancy leases are memory-only. operation_status does not track exec requests. The transport request ID, patch operation ID, process ID, work ID, instruction ID, and approval ID serve different purposes.
Patch transaction
The gateway authorizes the workspace, obtains the write lease, checks the operation key, dispatches one Runner patch request, and records its result. The Runner checks expected versions, performs preflight, snapshots affected files, invokes the patch helper, and verifies resulting disk hashes.
If helper application fails, the Runner attempts per-file snapshot restoration. Post-apply verification errors currently propagate without entering that restoration branch. This is not an atomic filesystem transaction. See patch behavior for client-visible consequences.
Process lifetime
MCP request completion does not end a managed process. Clients continue with its process_id. Server restart loses those handles. In UDS mode the gateway owns the worker: internal disconnect/shutdown ends the worker and its children, with no reconnect. See runner isolation for the distinct transport and isolation boundaries.
Extension boundaries
The core does not import Codex types directly. Adapters may depend on a broader Codex execution graph; this does not make the gateway a Codex agent. Operator configuration selects environments, while MCP clients select only registered workspaces. Container execution, remote runners, and a resource scheduler are not implemented.
Confirmation-hold tools (approval_create, approval_resolve, operation_resume) are implemented. They pause a mutation the profile already allows until the hold is granted. This is not a security boundary: they do not raise read-only to write/exec, honor ClientClaims.approved, or change the permission profile. The same MCP caller can grant. Resume re-checks policy. v1 does not separate host and model callers.
Keep a patch transaction as one Runner call when adding transports. Keep permission decisions in the gateway rather than importing Codex user/session permissions as authority. Execution contracts describe current invariants; Codex reuse lists connected adapters.
Tool and protocol references
For callable tools and integration examples, use Agent Loop integration. For revision negotiation and transport tests, use protocol compatibility. This avoids maintaining a second tool reference inside the architecture document.