sandbox-agent/foundry/research/specs/async-action-fixes/04-workbench-session-creation-without-inline-provisioning.md
Nathan Flurry eacbc602e7 Refactor Foundry GitHub state and sandbox runtime
Refactors Foundry around organization/repository ownership and adds an organization-scoped GitHub state actor plus a user-scoped GitHub auth actor, removing the old project PR/branch sync actors and repo PR cache.

Updates sandbox provisioning to rely on sandbox-agent for in-sandbox work, hardens Daytona startup and image-build behavior, and surfaces runtime and task-startup errors more clearly in the UI.

Extends workbench and GitHub state handling to track merged PR state, adds runtime-issue tracking, refreshes client/test/config wiring, and documents the main live Foundry test flow plus actor coordination rules.

Also updates the remaining Sandbox Agent install-version references in docs/examples to the current pinned minor channel.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-03-13 02:43:00 -07:00

3 KiB

Workbench Session Creation Must Not Trigger Inline Provisioning

Read 00-end-to-end-async-realtime-plan.md first for the governing migration order, runtime constraints, and realtime client model this brief assumes.

Problem

Creating a workbench tab currently provisions the whole task if no active sandbox exists. A user action that looks like "open tab" can therefore block on sandbox creation and agent setup.

Current Code Context

  • Workspace workbench action entry point: foundry/packages/backend/src/actors/workspace/actions.ts
  • Task workbench behavior: foundry/packages/backend/src/actors/task/workbench.ts
  • Task provision action: foundry/packages/backend/src/actors/task/index.ts
  • Sandbox session creation path: foundry/packages/backend/src/actors/sandbox-instance/index.ts
  • Remote workbench refresh behavior: foundry/packages/client/src/remote/workbench-client.ts

Target Contract

  • Creating a tab returns quickly.
  • If the task is not provisioned yet, the tab enters a pending state and becomes usable once provisioning completes.
  • Provisioning remains a task workflow concern, not a workbench request concern.

Proposed Fix

  1. Split tab creation from sandbox session creation.
  2. On createWorkbenchSession:
    • create session metadata or a placeholder tab row immediately
    • if the task is not provisioned, enqueue the required background work and return the placeholder id
    • if the task is provisioned, enqueue background session creation if that step can also be slow
  3. Add a tab/session state model such as:
    • pending_provision
    • pending_session_create
    • ready
    • error
  4. When provisioning or session creation finishes, update the placeholder row with the real sandbox/session identifiers and notify the workbench.

Files Likely To Change

  • foundry/packages/backend/src/actors/workspace/actions.ts
  • foundry/packages/backend/src/actors/task/workbench.ts
  • foundry/packages/backend/src/actors/task/index.ts
  • foundry/packages/backend/src/actors/task/db/schema.ts
  • foundry/packages/backend/src/actors/task/db/migrations.ts
  • foundry/packages/client/src/remote/workbench-client.ts
  • foundry/packages/frontend/src/components/mock-layout.tsx

Client Impact

  • The workbench can show a disabled composer or "Preparing environment" state for a pending tab.
  • The UI no longer needs to block on the mutation itself.

Acceptance Criteria

  • createWorkbenchSession never calls task provisioning inline.
  • Opening a tab on an unprovisioned task returns promptly with a placeholder tab id.
  • The tab transitions to ready through background updates only.

Implementation Notes

  • The main design choice here is placeholder identity. Decide early whether placeholder tab ids are durable synthetic ids or whether a pending row can be updated in place once a real session exists.
  • Avoid coupling this design to Daytona specifically; it should work for local and remote providers.
  • Fresh-agent check: confirm composer, unread state, and tab close behavior all handle pending/error tabs cleanly.