Definition of done: create-agent-app → fill agent.config.ts + profile → wrangler deploy = a working multimodal chat product, in one day, with CI that makes the known incident classes unshippable. Everything below is derived from a measured audit (2026-07-15) of agent-app, agent-dev-container, legal-agent, and tax-agent — each item cites the gap it closes. Nothing speculative.
Ground truth today: every primitive exists and is production-proven (client streamChatTurn w/ resume, D1 turn-buffer, PromptInputPart[] dispatch as of #187, interactions contract as of #176, teams/access/seat-billing, harness-native images on all 3 product harnesses). What's missing is the assembly: legal wrote 2,190 lines of chat orchestration, tax wrote 1,058 — differently (legal skips the turn-buffer, tax skips onInteraction, both fork the question-card stack ~1,000 lines each, neither delivers an image part). The scaffold emits a JSON tool-loop worker, not a chat app.
Phase 1 — the assembled chat vertical (kills ~3,500–4,500 lines of per-app glue)
Phase 2 — provable (works, tests, ships)
Phase 3 — platform closers (agent-dev-container)
Deliberately excluded (not "necessary to ship")
User-facing AgentProfile customization UI (the only true L — seams exist via userSkills/ProfileOverlay, zero producers; build when a product needs it), additional harness attachment support beyond the 3 product harnesses, balance-manager adoption (S, cleanup not blocker).
Sequencing / effort
Phase 1 items are independent → parallelizable; ~1 focused engineer-week total, or 2–3 orchestrated days. Phase 2 gates are hours each. Phase 3 is Lin's lane and mostly S. After Phase 1 + scaffold variant, the one-day claim is real and the scaffold test enforces it forever.
Definition of done:
create-agent-app→ fillagent.config.ts+ profile →wrangler deploy= a working multimodal chat product, in one day, with CI that makes the known incident classes unshippable. Everything below is derived from a measured audit (2026-07-15) of agent-app, agent-dev-container, legal-agent, and tax-agent — each item cites the gap it closes. Nothing speculative.Ground truth today: every primitive exists and is production-proven (client
streamChatTurnw/ resume, D1 turn-buffer,PromptInputPart[]dispatch as of #187, interactions contract as of #176, teams/access/seat-billing, harness-native images on all 3 product harnesses). What's missing is the assembly: legal wrote 2,190 lines of chat orchestration, tax wrote 1,058 — differently (legal skips the turn-buffer, tax skipsonInteraction, both fork the question-card stack ~1,000 lines each, neither delivers an image part). The scaffold emits a JSON tool-loop worker, not a chat app.Phase 1 — the assembled chat vertical (kills ~3,500–4,500 lines of per-app glue)
createChatTurnRoutes()(M): one exported factory assembling body-parse → sandbox producer → turn-buffer tap → SSEResponse, plus replay + interaction-answer endpoints. Consumers: replace legalapi.chat.ts(895 lines) and taxchat-turn.ts(1,058 lines) with it — the migration is the acceptance test./chat-store(S–M): threads+messages drizzle table factory (same injection pattern ascreateTeamTables) + thread/message CRUD incl. batched + bulk delete. Legal/tax each hand-roll incompatible schemas today; tax re-declares the framework's ownturn_eventsDDL.fs.uploadData+ path-ref part — the 1 MiB gateway cap makes this a required two-step), file→PromptInputPartassembly, andChatComposeremitting parts fromonSend(today it emitsonSend(string)and a disjointFileList; both products drop attachments on the floor).createAppAuth()(S): better-auth config factory (drizzle adapter, providers, cookie prefix, SSO wiring). Both apps hand-roll; tax re-implements cookie signing.Phase 2 — provable (works, tests, ships)
ensureWorkspaceSandbox; composed-prompt byte budget (default 40 KB) in profile composition;onErrorEventfail-loud when unhandled (silent-empty-answer class); generalize the/catalogimport-graph walker over a declared browser-safe manifest (all ~12 browser subpaths); env-var size check (E2BIG class) piggybacked on the payload gate.RUN_*_LIVE_E2Eflags — the test content exists; the flags appear in zero of 30 workflows. This is the class behind every "green CI, dead in prod" event this month.create-agent-app --chatassembles Phase 1; the existing scaffold test (which already typechecks generated apps against real dist) extends to run one fake-backend turn + the prompt/theme budget checks./preflightsecret-liveness bin (M): declared probes (router chat ping, sandbox auth ping, platform HEAD) run as a deploy step — the one class that can't be a CI gate (4 dead secrets in one day last incident).Phase 3 — platform closers (agent-dev-container)
OPENCODE_CONFIG_CONTENTis still an unbounded env var (sdk-provider-opencode/src/server.ts:357); write config to the on-diskopencode.jsoncit already points at. #3621 covered file mounts only.getCapabilities().multimodal(registryimageInput: trueis not the whole truth on app-server configs). Document the check in the SDK README.Deliberately excluded (not "necessary to ship")
User-facing AgentProfile customization UI (the only true L — seams exist via
userSkills/ProfileOverlay, zero producers; build when a product needs it), additional harness attachment support beyond the 3 product harnesses, balance-manager adoption (S, cleanup not blocker).Sequencing / effort
Phase 1 items are independent → parallelizable; ~1 focused engineer-week total, or 2–3 orchestrated days. Phase 2 gates are hours each. Phase 3 is Lin's lane and mostly S. After Phase 1 + scaffold variant, the one-day claim is real and the scaffold test enforces it forever.