Skip to content

Commit 404fea1

Browse files
GiniGini
authored andcommitted
docs: align Cowork with ephemeral E2B sessions
1 parent abbfc7a commit 404fea1

11 files changed

Lines changed: 331 additions & 60 deletions

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,20 @@ flowchart LR
2727
2828
Control --> Store[("Control PostgreSQL")]
2929
Control --> Controller["Workspace controller"]
30-
Controller --> Sandbox["Kasm sandbox"]
30+
Controller --> Computer["Kasm Computer sandbox"]
31+
Control --> Cowork["Cowork session adapter"]
32+
Cowork --> E2B["E2B Firecracker task VM"]
3133
Control --> Consent["OpenVTC consent service"]
3234
Control --> Gateway["LiteLLM gateway"]
3335
Control --> Broker["Channel broker"]
3436
Scheduler["Scheduler worker"] --> Control
3537
36-
Sandbox --> Gateway
37-
Sandbox --> Control
38-
Sandbox --> Egress["Per-workspace egress proxy"]
38+
Computer --> Gateway
39+
Computer --> Control
40+
Computer --> Egress["Per-workspace egress proxy"]
41+
E2B --> Gateway
42+
E2B --> Control
43+
E2B --> Egress
3944
Gateway --> Models["Model providers"]
4045
Gateway --> M365["Microsoft 365 MCP"]
4146
M365 --> Graph["Microsoft Graph"]
@@ -71,7 +76,8 @@ network isolation, policy integrity, and the approval protocol.
7176
| `workspace-ingress` | Serves the product origin and exchanges short-lived workspace launch links for scoped sessions | `127.0.0.1:4174` |
7277
| `web` | Static React application and authenticated reverse proxy to Control | Private |
7378
| `control-api` | Identity, policy, lifecycle orchestration, grants, governance, audit, and connection APIs | Private |
74-
| `workspace-controller` | Provisions Kasm workspaces through local Docker or the Kasm Developer API | Private |
79+
| `workspace-controller` | Provisions durable Computer/Kasm workspaces; managed providers are selected by policy | Private |
80+
| Cowork execution adapter | Creates disposable E2B task sessions for real ACP harnesses and application-scoped VCR | Private |
7581
| `litellm` | Model routing, per-user OAuth custody, scoped virtual keys, and MCP dispatch | `127.0.0.1:4000` |
7682
| `ms365-mcp` | Pinned Microsoft 365 MCP connector for Mail, Calendar, OneDrive, and Teams | OAuth bridge on `127.0.0.1:4311` |
7783
| `openvtc-consent` | OpenVTC executor identity, request signing, and proof verification | Private |

docs/COWORK_E2B_ACP_PLAN.md

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
# Cowork on E2B: canonical architecture and delivery plan
2+
3+
**Status:** implementation contract (2026-08-01)
4+
**Branch:** `codex/onevibe-computer`
5+
**Owner:** ONEComputer Control + Cowork runtime
6+
7+
This is the single source of truth for the lightweight Cowork runtime. It
8+
supersedes any earlier plan that describes Cowork as a Kasm workspace or that
9+
requires KasmVNC parity inside an ephemeral chat sandbox.
10+
11+
## Product boundary
12+
13+
ONEComputer has two deliberately different experiences:
14+
15+
| Experience | User mental model | Runtime | State lifetime | Visual surface |
16+
| --- | --- | --- | --- | --- |
17+
| **Computer** | “I am using my governed computer.” | Kasm/KasmVNC (or a later durable provider) | Persistent workspace and home volume | Full desktop, human takeover, clipboard, office apps |
18+
| **Cowork / ONEVibe** | “An agent is doing this task for me.” | E2B Firecracker microVM per conversation/task | Disposable task session; fixed TTL; destroy by default | Application-scoped evidence (browser/document PNGs), not a desktop login |
19+
20+
Cowork is not a lightweight alias for Computer. It does not create, open, or
21+
list a Kasm workspace; it does not mount a durable home volume; and it does not
22+
expose port 6901. If a user needs a persistent desktop, human takeover,
23+
clipboard, or long-running office state, Control must route them to Computer.
24+
25+
The current `/v1/onevibe/tasks` implementation still uses an internal
26+
workspace-shaped handle for compatibility with existing task/event tables. That
27+
handle is transitional and is never a durable workspace or a user-selectable
28+
Computer resource. New APIs and code must use a first-class Cowork session
29+
identifier and must not add dependencies on the workspace lifecycle.
30+
31+
## Canonical Cowork session model
32+
33+
The target Control model is an owned `cowork_session` with:
34+
35+
- `sessionId`, tenant, subject, task, agent, policy hash, provider profile;
36+
- an immutable image/template digest and provider sandbox id;
37+
- a short creation-anchored deadline, turn budget, byte budget, and state;
38+
- durable redacted activity, ACP transcript references, VCR frame references,
39+
artifact ownership, and cleanup evidence;
40+
- no durable user home, no provider credential, and no hidden reasoning.
41+
42+
The session is the authorization and retention boundary. The E2B sandbox is an
43+
implementation detail behind an `EphemeralExecutionAdapter`; it is never
44+
returned as a launch URL or treated as a workspace by the UI.
45+
46+
### Target endpoints
47+
48+
The compatibility endpoints remain read-only/deprecation paths while the
49+
following session-scoped endpoints are introduced:
50+
51+
```text
52+
POST /v1/cowork/sessions
53+
GET /v1/cowork/sessions/:sessionId
54+
POST /v1/cowork/sessions/:sessionId/turns
55+
GET /v1/cowork/sessions/:sessionId/events?after=N
56+
GET /v1/cowork/sessions/:sessionId/events/stream?after=N
57+
POST /v1/cowork/sessions/:sessionId/frames
58+
GET /v1/cowork/sessions/:sessionId/vcr
59+
GET /v1/cowork/sessions/:sessionId/artifacts/:artifactId
60+
DELETE /v1/cowork/sessions/:sessionId
61+
```
62+
63+
Every route checks tenant, subject, session, task, policy, and expiry. Expired
64+
sessions are immutable for audit reads and reject all new turns, captures,
65+
approvals, and artifact mutations.
66+
67+
## E2B Cowork runtime profile
68+
69+
The first managed profile is `cowork-e2b-ephemeral-v1`:
70+
71+
- pinned `linux/amd64` E2B template built from a minimal single-stage image;
72+
- Node 22, the official ACP SDK, pinned `codex-acp`, pinned OpenCode, and the
73+
`/usr/local/libexec/onecomputer-acp-chat.mjs` bridge;
74+
- Playwright and a pinned Chromium/Firefox runtime for browser tasks;
75+
- optional document tooling only when the image explicitly declares it;
76+
- a task-confined filesystem under `/workspace/task`, with no host mounts;
77+
- provider-native network allowlist plus the signed external egress proxy;
78+
- no Kasm daemon, VNC server, desktop login, nested KVM, or durable volume.
79+
80+
The image is promoted by digest, carries SBOM/provenance, and never contains
81+
model-provider keys, enterprise OAuth tokens, E2B credentials, or registry
82+
passwords. E2B template build credentials are short-lived and supplied only to
83+
the build command.
84+
85+
### Application-scoped VCR
86+
87+
Cowork VCR means “what the agent did in the application,” not “a streamed
88+
desktop.” The capture contract is explicit:
89+
90+
- browser: Playwright captures the actual page/context inside E2B;
91+
- document: a document-aware capture helper is used only if the profile has
92+
that application installed;
93+
- desktop: unsupported by the Cowork profile and fails closed with a typed
94+
capability error; Computer is the correct route.
95+
96+
Each PNG is size-bounded, signature-checked, hash-linked to an activity
97+
sequence, and stored through Control. A screenshot produced by the browser UI,
98+
a fixture, or a host process is not evidence.
99+
100+
## ACP and model boundary
101+
102+
Codex and OpenCode run inside E2B as real ACP stdio servers. Control starts the
103+
allow-listed binary, negotiates the ACP protocol version/capabilities, and
104+
maps updates to the canonical event stream. Model traffic goes only through
105+
the governed LiteLLM route using a short-lived broker grant. The E2B guest never
106+
receives an OpenAI, Anthropic, Kimi, or LiteLLM administrator key.
107+
108+
ACP is not the sandbox, approval, VCR, or model protocol. ACP permission
109+
requests are converted to an exact Control operation and otherwise cancelled;
110+
the UI cannot approve an action by itself. Product-facing SSE is Control’s
111+
ordered replay stream, not a direct unauthenticated ACP socket.
112+
113+
## Lifecycle and failure semantics
114+
115+
1. Authenticate and resolve the signed effective policy.
116+
2. Create an idempotent Cowork session and reserve its budget.
117+
3. Create the E2B microVM from the pinned profile and inject scoped grants.
118+
4. Start Codex or OpenCode ACP in the confined task directory.
119+
5. Stream redacted canonical events; capture application frames at governed
120+
action boundaries; persist artifacts before returning them to the UI.
121+
6. Pause only as an E2B cost optimization if the session deadline remains
122+
authoritative; never extend the deadline because a sandbox resumed.
123+
7. Destroy the sandbox, revoke grants, and purge task state at completion,
124+
cancellation, expiry, budget exhaustion, policy revocation, or provider
125+
failure. Preserve only the minimum redacted audit evidence.
126+
127+
Provider, process, SSE, browser, and storage disconnects produce explicit
128+
failed/expired states. There is no synthetic assistant response, fake VCR
129+
frame, or “ready” state when a real ACP/model call did not happen.
130+
131+
## Migration sequence
132+
133+
### Phase 0 — contract and documentation (current)
134+
135+
- Adopt this document as the canonical plan.
136+
- Keep Kasm Computer behavior unchanged.
137+
- Add `cowork-e2b-ephemeral-v1` capability metadata and an adapter seam that
138+
cannot call `open()` or `purgeWorkspace()`.
139+
- Mark the workspace-shaped task handle as compatibility-only.
140+
141+
**Exit:** architecture tests prove Cowork cannot be exposed through the durable
142+
workspace list or a Kasm launch route.
143+
144+
### Phase 1 — local image and ACP qualification
145+
146+
- Build the minimal Cowork image locally or on a large-disk builder.
147+
- Run real Codex and OpenCode ACP against the local LiteLLM route where the
148+
binaries are available; assert initialize, streaming, cancellation,
149+
permission cancellation, malformed input, and path confinement.
150+
- Run Playwright in the image and retrieve a real PNG before any UI test.
151+
152+
**Exit:** API qualification is green with no fixture response involved.
153+
154+
### Phase 2 — E2B template and API-first live gate
155+
156+
- Publish the image by digest and create a named E2B template.
157+
- Configure provider-reachable Control, LiteLLM, and egress HTTPS routes.
158+
- Prove create/resume/turn/stream/capture/artifact/cleanup with real E2B
159+
resources, including owner isolation, budget limits, and zero secret leakage.
160+
- Record sandbox/template ids, image digest, event hashes, PNG hashes, and
161+
final kill/purge evidence without recording credentials.
162+
163+
**Exit:** the real API gate passes for Codex and OpenCode before browser work.
164+
165+
### Phase 3 — browser UX and Manus-like VCR
166+
167+
- Exercise the Cowork page against the same live API session.
168+
- Render left-side streaming activity and right-side application VCR with
169+
previous/next, scrub, jump-to-live, reconnect, and truthful degraded states.
170+
- Generate and download a real PPTX from a Cowork session; validate the Office
171+
package and its evidence links.
172+
173+
**Exit:** browser E2E is a projection of a previously qualified API run.
174+
175+
### Phase 4 — Computer handoff and optional providers
176+
177+
- Add an explicit “open in Computer” handoff that creates/uses a durable Kasm
178+
workspace only when the user asks for desktop state or takeover.
179+
- Qualify Modal/gVisor or another provider against the same ephemeral contract;
180+
do not claim Kasm desktop parity for a provider that lacks it.
181+
182+
## Non-negotiable QA gates
183+
184+
- `npm test`, strict TypeScript build, and Playwright regression suite;
185+
- API E2E: real ACP initialize, ordered stream, terminal event, cancellation,
186+
budget/backpressure, owner isolation, PNG signature/hash, PPTX validation,
187+
and provider cleanup;
188+
- negative tests: no workspace listing, no Kasm open route, no desktop capture,
189+
expired-session mutation, invalid policy/grant, route rejection, secret
190+
leakage, and fabricated/fixture response rejection;
191+
- browser E2E only after API evidence exists; browser failures cannot be hidden
192+
by fixtures or simulated state.
193+
194+
## Done means
195+
196+
ONEComputer reaches Manus-like Cowork parity when a user can submit a task,
197+
watch a real Codex/OpenCode ACP stream, see truthful browser/document evidence,
198+
scrub and replay it, receive a real artifact, resume within the fixed session
199+
deadline, and observe deterministic cleanup—without ever creating or depending
200+
on a full Kasm workspace.

docs/E2B-MODAL-SANDBOX-IMPLEMENTATION.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
# E2B and Modal sandbox implementation
22

3-
Status: implemented behind the workspace-controller provider contract; automated
4-
conformance is green. Live cloud qualification is pending provider credentials,
5-
a published workspace image/template, and a public governed egress endpoint.
3+
Status: implemented behind the workspace-controller provider contract for the
4+
durable-provider compatibility path; automated conformance is green. Live cloud
5+
qualification is pending provider credentials, a published image/template, and
6+
a public governed egress endpoint. The lightweight Cowork contract is defined
7+
separately in [COWORK_E2B_ACP_PLAN.md](COWORK_E2B_ACP_PLAN.md).
68

79
## Decision
810

911
ONEComputer now supports four controller drivers:
1012

1113
- `kasm-local`: durable local Docker/KasmVNC workspaces.
1214
- `kasm`: Kasm Developer API sessions.
13-
- `e2b`: Firecracker microVM sandboxes through the official E2B TypeScript SDK.
15+
- `e2b`: Firecracker microVM sandboxes through the official E2B TypeScript SDK
16+
for the existing durable-provider compatibility path.
1417
- `modal`: gVisor sandboxes through the official Modal JavaScript SDK.
1518

16-
E2B and Modal run the same reviewed ONEComputer workspace image and KasmVNC
17-
desktop surface. This preserves the browser/Word/LibreOffice viewing model used
18-
by VCR instead of substituting a terminal-only sandbox.
19+
The existing E2B/Modal adapter tests cover the reviewed workspace contract. They
20+
do **not** define Cowork: Cowork uses a separate minimal image/profile with no
21+
KasmVNC, no desktop launch, and application-scoped browser/document capture.
22+
Kasm remains the full Computer visual surface.
1923

2024
## Contract parity
2125

@@ -30,15 +34,16 @@ by VCR instead of substituting a terminal-only sandbox.
3034
| Restricted/full-web policy proxy | Local sidecar | External TLS proxy | External TLS proxy |
3135
| Live egress grant rotation | Yes | Yes | Yes |
3236
| Native provider egress backstop | Docker networks | E2B `allowOut` | Modal domain allowlist |
33-
| KasmVNC desktop/VCR | Private relay | Authenticated KasmVNC | Modal connect token |
37+
| Full desktop/VCR | Private relay | Computer-only compatibility path | Computer-only compatibility path |
3438
| Clipboard policy | Yes | Yes | Yes |
3539
| Idle suspension | Container stop | Firecracker pause/auto-resume | Timeout/recreate |
3640
| Nested KVM/Cowork | Optional local KVM | No | No |
3741

3842
Nested KVM is an explicit routing constraint, not a silently degraded feature.
39-
Cowork workspaces remain on a Kasm-capable node. E2B and Modal are parity
40-
targets for browser, office, CLI-agent, chat-runtime, persistence, policy,
41-
egress, and VCR flows.
43+
Cowork sessions do not remain on a Kasm-capable node. They use the
44+
`cowork-e2b-ephemeral-v1` profile and are parity targets for ACP, browser
45+
evidence, policy, egress, artifacts, budgets, and cleanup—not desktop login,
46+
clipboard, or durable office state.
4247

4348
## Security behavior
4449

docs/ONEVIBE_E2B_ACP_FINAL_PLAN.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# ONEVibe-MonoRepo: E2B + ACP final execution plan
22

3+
> **Canonical update (2026-08-01):** [COWORK_E2B_ACP_PLAN.md](./COWORK_E2B_ACP_PLAN.md)
4+
> is now the source of truth for the lightweight Cowork architecture. This
5+
> document retains the broader provider and ACP sequencing; any reference below
6+
> to a Cowork “workspace”, KasmVNC parity, or a persistent E2B volume applies
7+
> only to the durable Computer compatibility path and is not a Cowork
8+
> requirement.
9+
310
> Current execution addendum: see [ONEVIBE_EPHEMERAL_COWORK_ACP.md](./ONEVIBE_EPHEMERAL_COWORK_ACP.md) for the task-scoped sandbox philosophy and API-first ACP/VCR qualification order.
411
512
**Status:** approved architecture plan
@@ -9,7 +16,7 @@
916
## Executive decision
1017

1118
Use E2B Firecracker microVMs as the first managed execution provider for
12-
conversation-scoped Cowork tasks. Run an allow-listed agent harness inside the
19+
conversation-scoped Cowork sessions. Run an allow-listed agent harness inside the
1320
microVM through the Agent Client Protocol (ACP), and normalize all output into
1421
ONEComputer's canonical governed event stream.
1522

@@ -25,7 +32,7 @@ User / Cowork UI
2532
ONEComputer Control + durable coordinator
2633
│ signed policy, budget, broker grant
2734
├── execution provider: E2B (conversation microVM)
28-
│ └── workspace image + OpenCode/Claude/Codex ACP harness
35+
│ └── minimal Cowork image + OpenCode/Codex ACP harness
2936
├── execution provider: Kasm (persistent visual workspace)
3037
└── execution provider: Modal (later gVisor burst tier)
3138
@@ -61,7 +68,7 @@ merge old `App.jsx`, migrations, or provider routes.
6168
The R&D evidence has three caveats:
6269

6370
1. E2B/Modal adapters are automated-conformance green but live qualification
64-
still requires provider credentials, an immutable workspace image/template,
71+
still requires provider credentials, an immutable image/template,
6572
public governed egress, and provider quotas.
6673
2. Codex ACP has a qualification lane through LiteLLM. Claude ACP is packaged,
6774
but intentionally remains disabled until broker-provided governed authority
@@ -82,9 +89,9 @@ Add an explicit execution scope to the task model:
8289
- `turn`: disposable environment for one request;
8390
- `conversation`: one E2B microVM per chat session, paused between turns;
8491
- `task`: environment retained across related Cowork interactions;
85-
- `workspace`: current Kasm-style durable desktop.
92+
- `workspace`: current Kasm-style durable Computer desktop.
8693

87-
Default Manus-like web chat to `conversation` + E2B. Route to Kasm when the
94+
Default Manus-like web chat to `conversation` + E2B. Route to Kasm Computer when the
8895
user needs a long-lived desktop, durable GUI state, nested virtualization, or
8996
human takeover that E2B has not yet qualified. The model/agent cannot choose a
9097
weaker boundary or extend retention.
@@ -125,13 +132,14 @@ forks where policy permits, and usage-based spend controls.
125132

126133
Required qualifications:
127134

128-
- immutable `linux/amd64` workspace image and E2B template;
135+
- immutable `linux/amd64` minimal Cowork image and E2B template;
129136
- E2B API key held only by the controller secret boundary;
130137
- external TLS egress proxy reachable from the provider;
131138
- default-deny provider network and exact route allowlist;
132139
- scoped model/control grants injected through the broker;
133140
- ACP process, filesystem, and terminal confinement;
134-
- browser/office capability only after KasmVNC/WebSocket/clipboard qualification;
141+
- application-scoped browser/document capture; desktop/KasmVNC/clipboard remain
142+
Computer-only capabilities;
135143
- frame capture sidecar with no raw prompts, cookies, secrets, or hidden
136144
reasoning in replay evidence;
137145
- create/resume/pause/kill reconciliation and explicit volume purge.
@@ -255,9 +263,10 @@ turn, cancellation, resume, owner isolation, spend limit, and destruction.
255263
**Exit:** harness choice changes runtime implementation only; event, policy,
256264
approval, VCR, artifact, and budget contracts remain identical.
257265

258-
### Phase 3 — visual E2B/VCR qualification
266+
### Phase 3 — application-scoped E2B/VCR qualification
259267

260-
- Prove KasmVNC or equivalent read-only computer view inside the E2B image.
268+
- Prove Playwright/application capture inside the minimal Cowork E2B image;
269+
KasmVNC and desktop takeover remain Computer-only.
261270
- Add capture sidecar at semantic action boundaries and bounded active cadence.
262271
- Implement live-follow, previous/next, pause/play, scrub, event markers,
263272
frame availability, jump-to-live, and capture-degraded states.

0 commit comments

Comments
 (0)