diff --git a/docs/feature-divide.md b/docs/feature-divide.md index 25c58ffe..d4a5d6bb 100644 --- a/docs/feature-divide.md +++ b/docs/feature-divide.md @@ -40,7 +40,7 @@ optional login chrome). | Per-user MCP tools (connect + execute) | **Vercel backend** | `lib/mcp/*`; keys under tenant DEK; never Wasm/client | | `search` code-grep tool | **Vercel backend** | Read-grant-only; runs `rg` argv-only in the sandbox jail; no Wasm/bridge change | | Builtin HTTPS fetch (`http_get`) | **Vercel backend** | Always-available when a running HTTP instance exists; attach-only (Settings Create HTTP instance); see [builtin-http.md](builtin-http.md) | -| Workflow run/step (backend-agents) | **Vercel backend** | Server-only fixtures (`lib/workflows/*`, `"use workflow"` orchestration via the `workflow` SDK + `withWorkflow` in `next.config.js`), authed smoke (`app/api/workflows/smoke`), Vercel Workflows platform (Functions + Queues, dashboard-visible Observability). Durable-turn SSE uses the same `AgentStreamEvent` types as `/api/agent`; stream write/close run in `'use step'` only (not in the `'use workflow'` orchestrator). Never Wasm/DOM; never the tab-owned `/api/agent` as the smoke path. Verify via GHA `workflows-smoke` | +| Workflow run/step (backend-agents) | **Vercel backend** | Server-only fixtures (`lib/workflows/*`, `"use workflow"` orchestration via the `workflow` SDK + `withWorkflow` in `next.config.js`), authed smoke (`app/api/workflows/smoke`), Vercel Workflows platform (Functions + Queues, dashboard-visible Observability). **The Workflow run owns the turn** — it is the durable turn owner, independent of any attached viewport. One `'use step'` = one model round **or** one **`toolExecuteStep` (one model round's `toolCalls` / waves)** **or** one persist — never a mega-step and never wrap `runAgentStream`. The **worker is the Blob writer**: when the viewport is detached the worker persists the transcript/checkpoint segment to Blob itself (the detach only closes a reader; it never stops the run). Durable-turn SSE uses the same `AgentStreamEvent` types as `/api/agent`; stream write/close run in `'use step'` only (not in the `'use workflow'` orchestrator). Never Wasm/DOM; never the tab-owned `/api/agent` as the smoke path. Verify via GHA `workflows-smoke` | | **Transcript (read messages)** | **Wasm** | Primary UX; rich MD + images + math + diff/patch fence paint in-canvas (`rich/*`) — no DOM markdown | | Transcript left rail (collapsible session list) | **Wasm** | Inside the transcript band only (canvas top → composer). Default closed: 40 px icon strip. Open: 220 px TEAL column with the session list (scroll). Host pushes summaries (`GET /api/sessions`); Wasm paints and raises a pending switch; host hydrates. New session / Persona / Clear stay in DOM `AppNav`. No host CSS sidebar. | | Image bytes (fetch/decode) | **DOM host** | Browser fetch → RGBA → `inv_image_cache_put`; paint stays Wasm |