You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Status update (2026-07-23): Phase 1 shipped via the #191–#220 series and is adopted by legal (legal-agent#263/#264), tax (tax-agent#378/#379), and gtm (gtm-agent#601–#603) — the migration acceptance test below is satisfied. Remaining shared-code work and fleet-wide adoption are tracked in the consolidation epic #228; the Phase-2 gates + nightly live-e2e are implemented by #226 — work them there, not here. This issue stays open only for the /preflight bin wiring and Phase 3.
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)
createAppAuth() (S): better-auth config factory (drizzle adapter, providers, cookie prefix, SSO wiring). Both apps hand-roll; tax re-implements cookie signing. — shipped and adopted by all three migrated apps (e.g. gtm-agent#602)
Phase 2 — provable (works, tests, ships)
Five S-cost gates in agent-app (each an assertion at an existing choke point): provision-payload size (<240 KiB, per-section breakdown) in ensureWorkspaceSandbox; composed-prompt byte budget (default 40 KB) in profile composition; onErrorEvent fail-loud when unhandled (silent-empty-answer class); generalize the /catalog import-graph walker over a declared browser-safe manifest (all ~12 browser subpaths); env-var size check (E2BIG class) piggybacked on the payload gate. — implemented by [INFRA] Ship the Phase-2 CI gates + nightly live-e2e from the #188 roadmap #226
Nightly live-e2e workflow in agent-dev-container (S): one workflow flipping the existing RUN_*_LIVE_E2E flags — 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.
/preflight secret-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). — library half shipped (/preflight subpath: runPreflight + router/sandbox/HEAD probe builders); the agent-app-preflight bin entry and deploy-step wiring are still missing — this is the live remainder
Phase 3 — platform closers (agent-dev-container)
#3539 E2BIG (S–M): OPENCODE_CONFIG_CONTENT is still an unbounded env var (sdk-provider-opencode/src/server.ts:357); write config to the on-disk opencode.jsonc it already points at. #3621 covered file mounts only.
Attachment workflow docs + opencode live image test (S): the upload-then-path two-step is mechanically solid and documented nowhere; opencode's native image path has no live proof that the model sees the image.
Codex images × interactions — blocked upstream (#3586); until then apps must check runtime getCapabilities().multimodal (registry imageInput: true is 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.
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. — shipped in feat(chat-routes): assembled chat-turn vertical + multimodal upload→parts (#188 Phase 1) #194 (+ product seams feat(chat-routes): product turn-lifecycle seams (heartbeat, beforeTurn, lifecycle, context-gate, turn-lock) #200, hardening feat(sandbox): optional billingOwnerId on create + keyless model metadata #204–feat(chat-routes): let authorize suppress the user-row insert for a dispatched turn #207); legal-agent#263 and tax-agent#378 replaced their orchestration with it/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. — shipped in feat(chat-store): shared chat thread/message persistence (issue #188 Phase 1) #191fs.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). — upload→parts shipped in feat(chat-routes): assembled chat-turn vertical + multimodal upload→parts (#188 Phase 1) #194, durable object-store in feat(object-store): portable signed-URL object store for durable attachments #211/fix(web-react,object-store): guard tool-detail render + reject interior slash in key segments #217, composer attach UX in sandbox-ui 0.84+; client-half completeness across products continues in [FEAT] Uplift the attachment client half — structured dispatch + eager file-part promotion #224 / [EPIC] One chat vertical across the fleet — consolidate agent-app, adopt in every app #228createAppAuth()(S): better-auth config factory (drizzle adapter, providers, cookie prefix, SSO wiring). Both apps hand-roll; tax re-implements cookie signing. — shipped and adopted by all three migrated apps (e.g. gtm-agent#602)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. — implemented by [INFRA] Ship the Phase-2 CI gates + nightly live-e2e from the #188 roadmap #226RUN_*_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. — shipped via feat(sandbox+chat-routes): durable interactive turn — detach + running discovery #209/feat(create-agent-app): scaffold chat turns durable by default (detach) #210 —create-agent-app --chatexists, durable by default, with a scaffold test that runs the generated app's own fake-backend turn e2e; the prompt/theme budget-check extension rides with [INFRA] Ship the Phase-2 CI gates + nightly live-e2e from the #188 roadmap #226 — implemented by [INFRA] Ship the Phase-2 CI gates + nightly live-e2e from the #188 roadmap #226/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). — library half shipped (/preflightsubpath:runPreflight+ router/sandbox/HEAD probe builders); theagent-app-preflightbin entry and deploy-step wiring are still missing — this is the live remainderPhase 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.