repo: push all current workspace changes

This commit is contained in:
Nathan Flurry 2026-03-13 01:12:43 -07:00
parent 252fbdc93b
commit e7dfff5836
29 changed files with 577 additions and 98 deletions

View file

@ -0,0 +1,51 @@
# Task Creation Should Return After Actor Bootstrap
## Problem
Task creation currently waits for full provisioning: naming, repo checks, sandbox creation/resume, sandbox-agent install/start, sandbox-instance wiring, and session creation.
That makes a user-facing action depend on queue-backed and provider-backed work that can take minutes. The client only needs the task actor to exist so it can navigate to the task and observe progress.
## Target Contract
- `createTask` returns once the task actor exists and initial task metadata is persisted.
- The response includes the task identity the client needs for follow-up reads and subscriptions.
- Provisioning continues in the background through the task workflow.
- Progress and failure are surfaced through task state, history events, and workbench updates.
## Proposed Fix
1. Restore the async split between `initialize` and `provision`.
2. Keep `task.command.initialize` responsible for:
- creating the task actor
- bootstrapping DB rows
- persisting any immediately-known metadata
- returning the current task record
3. After initialize completes, enqueue `task.command.provision` with `wait: false`.
4. Change `workspace.createTask` to:
- create or resolve the project
- create the task actor
- call `task.initialize(...)`
- stop awaiting `task.provision(...)`
- broadcast a workbench/task update
- return the task record immediately
5. Persist a clear queued/running state for provisioning so the frontend can distinguish:
- `init_enqueue_provision`
- `init_ensure_name`
- `init_create_sandbox`
- `init_ensure_agent`
- `init_create_session`
- `running`
- `error`
## Client Impact
- Task creation UI should navigate immediately to the task page.
- The page should render a provisioning state from task status instead of treating create as an all-or-nothing spinner.
- Any tab/session creation that depends on provisioning should observe task state and wait for readiness asynchronously.
## Acceptance Criteria
- Creating a task never waits on sandbox creation or session creation.
- A timeout in provider setup does not make the original create request fail after several minutes.
- After a backend restart, the task workflow can resume provisioning from durable state without requiring the client to retry create.

View file

@ -0,0 +1,45 @@
# Repo Overview Should Read Cached State Only
## Problem
Repo overview currently forces PR sync and branch sync inline before returning data. That turns a read path into:
- repo fetch
- branch enumeration
- diff/conflict calculations
- GitHub PR listing
The frontend polls repo overview repeatedly, so this design multiplies slow work and ties normal browsing to sync latency.
## Target Contract
- `getRepoOverview` returns the latest cached repo projection immediately.
- Sync happens on a background cadence or on an explicit async refresh trigger.
- Overview responses include freshness metadata so the client can show "refreshing" or "stale" state without blocking.
## Proposed Fix
1. Remove inline `forceProjectSync()` from `getRepoOverview`.
2. Add freshness fields to the project projection, for example:
- `branchSyncAt`
- `prSyncAt`
- `branchSyncStatus`
- `prSyncStatus`
3. Let the existing polling actors own cache refresh.
4. If the client needs a manual refresh, add a non-blocking command such as `project.requestOverviewRefresh` that:
- enqueues refresh work
- updates sync status to `queued` or `running`
- returns immediately
5. Keep `getRepoOverview` as a pure read over project SQLite state.
## Client Impact
- The repo overview screen should render cached rows immediately.
- If the user requests a refresh, the UI should show a background sync indicator instead of waiting for the GET call to complete.
- Polling frequency can be reduced because reads are now cheap and sync is event-driven.
## Acceptance Criteria
- `getRepoOverview` does not call `force()` on polling actors.
- Opening the repo overview page does not trigger network/git work inline.
- Slow branch sync or PR sync no longer blocks the page request.

View file

@ -0,0 +1,50 @@
# Repo Sync And Stack Actions Should Run In Background Workflows
## Problem
Repo stack actions currently run inside a synchronous action and surround the action with forced sync before and after. Branch-backed task creation also forces repo sync inline before it can proceed.
These flows depend on repo/network state and can take minutes. They should not hold an action open.
## Target Contract
- Repo-affecting actions are accepted quickly and run in the background.
- The project actor owns a durable action record with progress and final result.
- Clients observe status via project/task state instead of waiting for a single response.
## Proposed Fix
1. Introduce a project-level workflow/job model for repo actions, for example:
- `sync_repo`
- `restack_repo`
- `restack_subtree`
- `rebase_branch`
- `reparent_branch`
- `register_existing_branch`
2. Persist a job row with:
- job id
- action kind
- target branch fields
- status
- message
- timestamps
3. Change `runRepoStackAction` to:
- validate cheap local inputs only
- create a job row
- enqueue the workflow with `wait: false`
- return the job id and accepted status immediately
4. Move pre/post sync into the background workflow.
5. For branch-backed task creation:
- use the cached branch projection if present
- if branch data is stale or missing, enqueue branch registration/refresh work and surface pending state instead of blocking create
## Client Impact
- Repo action buttons should show queued/running/completed/error job state.
- Task creation from an existing branch may produce a task in a pending branch-attach state rather than blocking on repo sync.
## Acceptance Criteria
- No repo stack action waits for full git-spice execution inside the request.
- No action forces branch sync or PR sync inline.
- Action result state survives retries and backend restarts because the workflow status is persisted.

View file

@ -0,0 +1,36 @@
# Workbench Session Creation Must Not Trigger Inline Provisioning
## 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.
## 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.
## 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.

View file

@ -0,0 +1,43 @@
# Workbench Snapshots Should Read Derived State, Not Recompute It
## Problem
Workbench snapshot reads currently execute expensive sandbox commands and transcript reads inline:
- `git status`
- `git diff --numstat`
- one diff per changed file
- file tree enumeration
- transcript reads for each session
- session status lookups
The remote workbench client refreshes after each action and on update events, so this synchronous snapshot work is amplified.
## Target Contract
- `getWorkbench` reads a cached projection only.
- Expensive sandbox- or session-derived data is updated asynchronously and stored in actor-owned tables.
- Detail-heavy payloads are fetched separately when the user actually opens that view.
## Proposed Fix
1. Split the current monolithic workbench snapshot into:
- lightweight task/workbench summary
- session transcript endpoint
- file diff endpoint
- file tree endpoint
2. Cache derived git state in SQLite, updated by background jobs or targeted invalidation after mutating actions.
3. Cache transcript/session metadata incrementally from sandbox events instead of reading full transcripts on every snapshot.
4. Keep `getWorkbench` limited to summary fields needed for the main screen.
5. Update the remote workbench client to rely more on push updates and less on immediate full refresh after every mutation.
## Client Impact
- Main workbench loads faster and remains responsive with many tasks/files/sessions.
- Heavy panes can show their own loading states when opened.
## Acceptance Criteria
- `getWorkbench` does not run per-file diff commands inline.
- `getWorkbench` does not read full transcripts for every tab inline.
- Full workbench refresh cost stays roughly proportional to task count, not task count times changed files times sessions.

View file

@ -0,0 +1,51 @@
# Daytona Provisioning Should Be A Staged Background Flow
## Problem
Daytona provisioning currently performs long-running setup inline:
- sandbox create/start
- package/tool installation
- repo clone/fetch/checkout
- sandbox-agent install
- agent plugin install
- sandbox-agent boot
- health wait loop
This is acceptable inside a durable background workflow, but not as part of a user-facing action response.
## Target Contract
- Requests that need Daytona resources only wait for persisted actor/job creation.
- Daytona setup progresses through durable stages with explicit status.
- Follow-up work resumes from persisted state after crashes or restarts.
## Proposed Fix
1. Introduce a provider-facing staged readiness model, for example:
- `sandbox_allocated`
- `repo_prepared`
- `agent_installing`
- `agent_starting`
- `agent_ready`
- `session_creating`
- `ready`
- `error`
2. Persist stage transitions in task or sandbox-instance state.
3. Keep provider calls inside background workflow steps only.
4. Replace synchronous health-wait loops in request paths with:
- background step execution
- status updates after each step
- follow-up workflow progression once the prior stage completes
5. If sandbox-agent session creation is also slow, treat that as its own stage instead of folding it into request completion.
## Client Impact
- Users see staged progress instead of a long spinner.
- Failures point to a concrete stage, which makes retries and debugging much easier.
## Acceptance Criteria
- No user-facing request waits for Daytona package installs, repo clone, sandbox-agent installation, or health polling.
- Progress survives backend restarts because the stage is persisted.
- The system can resume from the last completed stage instead of replaying the whole provisioning path blindly.