Merge public-gh/master into paperclip-company-import-export
This commit is contained in:
1263
doc/plans/workspace-product-model-and-work-product.md
Normal file
1263
doc/plans/workspace-product-model-and-work-product.md
Normal file
File diff suppressed because it is too large
Load Diff
882
doc/plans/workspace-technical-implementation.md
Normal file
882
doc/plans/workspace-technical-implementation.md
Normal file
@@ -0,0 +1,882 @@
|
||||
# Workspace Technical Implementation Spec
|
||||
|
||||
## Role of This Document
|
||||
|
||||
This document translates [workspace-product-model-and-work-product.md](/Users/dotta/paperclip-subissues/doc/plans/workspace-product-model-and-work-product.md) into an implementation-ready engineering plan.
|
||||
|
||||
It is intentionally concrete:
|
||||
|
||||
- schema and migration shape
|
||||
- shared contract updates
|
||||
- route and service changes
|
||||
- UI changes
|
||||
- rollout and compatibility rules
|
||||
|
||||
This is the implementation target for the first workspace-aware delivery slice.
|
||||
|
||||
## Locked Decisions
|
||||
|
||||
These decisions are treated as settled for this implementation:
|
||||
|
||||
1. Add a new durable `execution_workspaces` table now.
|
||||
2. Each issue has at most one current execution workspace at a time.
|
||||
3. `issues` get explicit `project_workspace_id` and `execution_workspace_id`.
|
||||
4. Workspace reuse is in scope for V1.
|
||||
5. The feature is gated in the UI by `/instance/settings > Experimental > Workspaces`.
|
||||
6. The gate is UI-only. Backend model changes and migrations always ship.
|
||||
7. Existing users upgrade into compatibility-preserving defaults.
|
||||
8. `project_workspaces` evolves in place rather than being replaced.
|
||||
9. Work product is issue-first, with optional links to execution workspaces and runtime services.
|
||||
10. GitHub is the only PR provider in the first slice.
|
||||
11. Both `adapter_managed` and `cloud_sandbox` execution modes are in scope.
|
||||
12. Workspace controls ship first inside existing project properties, not in a new global navigation area.
|
||||
13. Subissues are out of scope for this implementation slice.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Building a full code review system
|
||||
- Solving subissue UX in this slice
|
||||
- Implementing reusable shared workspace definitions across projects in this slice
|
||||
- Reworking all current runtime service behavior before introducing execution workspaces
|
||||
|
||||
## Existing Baseline
|
||||
|
||||
The repo already has:
|
||||
|
||||
- `project_workspaces`
|
||||
- `projects.execution_workspace_policy`
|
||||
- `issues.execution_workspace_settings`
|
||||
- runtime service persistence in `workspace_runtime_services`
|
||||
- local git-worktree realization in `workspace-runtime.ts`
|
||||
|
||||
This implementation should build on that baseline rather than fork it.
|
||||
|
||||
## Terminology
|
||||
|
||||
- `Project workspace`: durable configured codebase/root for a project
|
||||
- `Execution workspace`: actual runtime workspace used for one or more issues
|
||||
- `Work product`: user-facing output such as PR, preview, branch, commit, artifact, document
|
||||
- `Runtime service`: process or service owned or tracked for a workspace
|
||||
- `Compatibility mode`: existing behavior preserved for upgraded installs with no explicit workspace opt-in
|
||||
|
||||
## Architecture Summary
|
||||
|
||||
The first slice should introduce three explicit layers:
|
||||
|
||||
1. `Project workspace`
|
||||
- existing durable project-scoped codebase record
|
||||
- extended to support local, git, non-git, and remote-managed shapes
|
||||
|
||||
2. `Execution workspace`
|
||||
- new durable runtime record
|
||||
- represents shared, isolated, operator-branch, or remote-managed execution context
|
||||
|
||||
3. `Issue work product`
|
||||
- new durable output record
|
||||
- stores PRs, previews, branches, commits, artifacts, and documents
|
||||
|
||||
The issue remains the planning and ownership unit.
|
||||
The execution workspace remains the runtime unit.
|
||||
The work product remains the deliverable/output unit.
|
||||
|
||||
## Configuration and Deployment Topology
|
||||
|
||||
## Important correction
|
||||
|
||||
This repo already uses `PAPERCLIP_DEPLOYMENT_MODE` for auth/deployment behavior (`local_trusted | authenticated`).
|
||||
|
||||
Do not overload that variable for workspace execution topology.
|
||||
|
||||
## New env var
|
||||
|
||||
Add a separate execution-host hint:
|
||||
|
||||
- `PAPERCLIP_EXECUTION_TOPOLOGY=local|cloud|hybrid`
|
||||
|
||||
Default:
|
||||
|
||||
- if unset, treat as `local`
|
||||
|
||||
Purpose:
|
||||
|
||||
- influences defaults and validation for workspace configuration
|
||||
- does not change current auth/deployment semantics
|
||||
- does not break existing installs
|
||||
|
||||
### Semantics
|
||||
|
||||
- `local`
|
||||
- Paperclip may create host-local worktrees, processes, and paths
|
||||
- `cloud`
|
||||
- Paperclip should assume no durable host-local execution workspace management
|
||||
- adapter-managed and cloud-sandbox flows should be treated as first-class
|
||||
- `hybrid`
|
||||
- both local and remote execution strategies may exist
|
||||
|
||||
This is a guardrail and defaulting aid, not a hard policy engine in the first slice.
|
||||
|
||||
## Instance Settings
|
||||
|
||||
Add a new `Experimental` section under `/instance/settings`.
|
||||
|
||||
### New setting
|
||||
|
||||
- `experimental.workspaces: boolean`
|
||||
|
||||
Rules:
|
||||
|
||||
- default `false`
|
||||
- UI-only gate
|
||||
- stored in instance config or instance settings API response
|
||||
- backend routes and migrations remain available even when false
|
||||
|
||||
### UI behavior when off
|
||||
|
||||
- hide workspace-specific issue controls
|
||||
- hide workspace-specific project configuration
|
||||
- hide issue `Work Product` tab if it would otherwise be empty
|
||||
- do not remove or invalidate any stored workspace data
|
||||
|
||||
## Data Model
|
||||
|
||||
## 1. Extend `project_workspaces`
|
||||
|
||||
Current table exists and should evolve in place.
|
||||
|
||||
### New columns
|
||||
|
||||
- `source_type text not null default 'local_path'`
|
||||
- `local_path | git_repo | non_git_path | remote_managed`
|
||||
- `default_ref text null`
|
||||
- `visibility text not null default 'default'`
|
||||
- `default | advanced`
|
||||
- `setup_command text null`
|
||||
- `cleanup_command text null`
|
||||
- `remote_provider text null`
|
||||
- examples: `github`, `openai`, `anthropic`, `custom`
|
||||
- `remote_workspace_ref text null`
|
||||
- `shared_workspace_key text null`
|
||||
- reserved for future cross-project shared workspace definitions
|
||||
|
||||
### Backfill rules
|
||||
|
||||
- if existing row has `repo_url`, backfill `source_type='git_repo'`
|
||||
- else if existing row has `cwd`, backfill `source_type='local_path'`
|
||||
- else backfill `source_type='remote_managed'`
|
||||
- copy existing `repo_ref` into `default_ref`
|
||||
|
||||
### Indexes
|
||||
|
||||
- retain current indexes
|
||||
- add `(project_id, source_type)`
|
||||
- add `(company_id, shared_workspace_key)` non-unique for future support
|
||||
|
||||
## 2. Add `execution_workspaces`
|
||||
|
||||
Create a new durable table.
|
||||
|
||||
### Columns
|
||||
|
||||
- `id uuid pk`
|
||||
- `company_id uuid not null`
|
||||
- `project_id uuid not null`
|
||||
- `project_workspace_id uuid null`
|
||||
- `source_issue_id uuid null`
|
||||
- `mode text not null`
|
||||
- `shared_workspace | isolated_workspace | operator_branch | adapter_managed | cloud_sandbox`
|
||||
- `strategy_type text not null`
|
||||
- `project_primary | git_worktree | adapter_managed | cloud_sandbox`
|
||||
- `name text not null`
|
||||
- `status text not null default 'active'`
|
||||
- `active | idle | in_review | archived | cleanup_failed`
|
||||
- `cwd text null`
|
||||
- `repo_url text null`
|
||||
- `base_ref text null`
|
||||
- `branch_name text null`
|
||||
- `provider_type text not null default 'local_fs'`
|
||||
- `local_fs | git_worktree | adapter_managed | cloud_sandbox`
|
||||
- `provider_ref text null`
|
||||
- `derived_from_execution_workspace_id uuid null`
|
||||
- `last_used_at timestamptz not null default now()`
|
||||
- `opened_at timestamptz not null default now()`
|
||||
- `closed_at timestamptz null`
|
||||
- `cleanup_eligible_at timestamptz null`
|
||||
- `cleanup_reason text null`
|
||||
- `metadata jsonb null`
|
||||
- `created_at timestamptz not null default now()`
|
||||
- `updated_at timestamptz not null default now()`
|
||||
|
||||
### Foreign keys
|
||||
|
||||
- `company_id -> companies.id`
|
||||
- `project_id -> projects.id`
|
||||
- `project_workspace_id -> project_workspaces.id on delete set null`
|
||||
- `source_issue_id -> issues.id on delete set null`
|
||||
- `derived_from_execution_workspace_id -> execution_workspaces.id on delete set null`
|
||||
|
||||
### Indexes
|
||||
|
||||
- `(company_id, project_id, status)`
|
||||
- `(company_id, project_workspace_id, status)`
|
||||
- `(company_id, source_issue_id)`
|
||||
- `(company_id, last_used_at desc)`
|
||||
- `(company_id, branch_name)` non-unique
|
||||
|
||||
## 3. Extend `issues`
|
||||
|
||||
Add explicit workspace linkage.
|
||||
|
||||
### New columns
|
||||
|
||||
- `project_workspace_id uuid null`
|
||||
- `execution_workspace_id uuid null`
|
||||
- `execution_workspace_preference text null`
|
||||
- `inherit | shared_workspace | isolated_workspace | operator_branch | reuse_existing`
|
||||
|
||||
### Foreign keys
|
||||
|
||||
- `project_workspace_id -> project_workspaces.id on delete set null`
|
||||
- `execution_workspace_id -> execution_workspaces.id on delete set null`
|
||||
|
||||
### Backfill rules
|
||||
|
||||
- all existing issues get null values
|
||||
- null should be interpreted as compatibility/inherit behavior
|
||||
|
||||
### Invariants
|
||||
|
||||
- if `project_workspace_id` is set, it must belong to the issue's project and company
|
||||
- if `execution_workspace_id` is set, it must belong to the issue's company
|
||||
- if `execution_workspace_id` is set, the referenced workspace's `project_id` must match the issue's `project_id`
|
||||
|
||||
## 4. Add `issue_work_products`
|
||||
|
||||
Create a new durable table for outputs.
|
||||
|
||||
### Columns
|
||||
|
||||
- `id uuid pk`
|
||||
- `company_id uuid not null`
|
||||
- `project_id uuid null`
|
||||
- `issue_id uuid not null`
|
||||
- `execution_workspace_id uuid null`
|
||||
- `runtime_service_id uuid null`
|
||||
- `type text not null`
|
||||
- `preview_url | runtime_service | pull_request | branch | commit | artifact | document`
|
||||
- `provider text not null`
|
||||
- `paperclip | github | vercel | s3 | custom`
|
||||
- `external_id text null`
|
||||
- `title text not null`
|
||||
- `url text null`
|
||||
- `status text not null`
|
||||
- `active | ready_for_review | approved | changes_requested | merged | closed | failed | archived`
|
||||
- `review_state text not null default 'none'`
|
||||
- `none | needs_board_review | approved | changes_requested`
|
||||
- `is_primary boolean not null default false`
|
||||
- `health_status text not null default 'unknown'`
|
||||
- `unknown | healthy | unhealthy`
|
||||
- `summary text null`
|
||||
- `metadata jsonb null`
|
||||
- `created_by_run_id uuid null`
|
||||
- `created_at timestamptz not null default now()`
|
||||
- `updated_at timestamptz not null default now()`
|
||||
|
||||
### Foreign keys
|
||||
|
||||
- `company_id -> companies.id`
|
||||
- `project_id -> projects.id on delete set null`
|
||||
- `issue_id -> issues.id on delete cascade`
|
||||
- `execution_workspace_id -> execution_workspaces.id on delete set null`
|
||||
- `runtime_service_id -> workspace_runtime_services.id on delete set null`
|
||||
- `created_by_run_id -> heartbeat_runs.id on delete set null`
|
||||
|
||||
### Indexes
|
||||
|
||||
- `(company_id, issue_id, type)`
|
||||
- `(company_id, execution_workspace_id, type)`
|
||||
- `(company_id, provider, external_id)`
|
||||
- `(company_id, updated_at desc)`
|
||||
|
||||
## 5. Extend `workspace_runtime_services`
|
||||
|
||||
This table already exists and should remain the system of record for owned/tracked services.
|
||||
|
||||
### New column
|
||||
|
||||
- `execution_workspace_id uuid null`
|
||||
|
||||
### Foreign key
|
||||
|
||||
- `execution_workspace_id -> execution_workspaces.id on delete set null`
|
||||
|
||||
### Behavior
|
||||
|
||||
- runtime services remain workspace-first
|
||||
- issue UIs should surface them through linked execution workspaces and work products
|
||||
|
||||
## Shared Contracts
|
||||
|
||||
## 1. `packages/shared`
|
||||
|
||||
### Update project workspace types and validators
|
||||
|
||||
Add fields:
|
||||
|
||||
- `sourceType`
|
||||
- `defaultRef`
|
||||
- `visibility`
|
||||
- `setupCommand`
|
||||
- `cleanupCommand`
|
||||
- `remoteProvider`
|
||||
- `remoteWorkspaceRef`
|
||||
- `sharedWorkspaceKey`
|
||||
|
||||
### Add execution workspace types and validators
|
||||
|
||||
New shared types:
|
||||
|
||||
- `ExecutionWorkspace`
|
||||
- `ExecutionWorkspaceMode`
|
||||
- `ExecutionWorkspaceStatus`
|
||||
- `ExecutionWorkspaceProviderType`
|
||||
|
||||
### Add work product types and validators
|
||||
|
||||
New shared types:
|
||||
|
||||
- `IssueWorkProduct`
|
||||
- `IssueWorkProductType`
|
||||
- `IssueWorkProductStatus`
|
||||
- `IssueWorkProductReviewState`
|
||||
|
||||
### Update issue types and validators
|
||||
|
||||
Add:
|
||||
|
||||
- `projectWorkspaceId`
|
||||
- `executionWorkspaceId`
|
||||
- `executionWorkspacePreference`
|
||||
- `workProducts?: IssueWorkProduct[]`
|
||||
|
||||
### Extend project execution policy contract
|
||||
|
||||
Replace the current narrow policy with a more explicit shape:
|
||||
|
||||
- `enabled`
|
||||
- `defaultMode`
|
||||
- `shared_workspace | isolated_workspace | operator_branch | adapter_default`
|
||||
- `allowIssueOverride`
|
||||
- `defaultProjectWorkspaceId`
|
||||
- `workspaceStrategy`
|
||||
- `branchPolicy`
|
||||
- `pullRequestPolicy`
|
||||
- `runtimePolicy`
|
||||
- `cleanupPolicy`
|
||||
|
||||
Do not try to encode every possible provider-specific field in V1. Keep provider-specific extensibility in nested JSON where needed.
|
||||
|
||||
## Service Layer Changes
|
||||
|
||||
## 1. Project service
|
||||
|
||||
Update project workspace CRUD to handle the extended schema.
|
||||
|
||||
### Required rules
|
||||
|
||||
- when setting a primary workspace, clear `is_primary` on siblings
|
||||
- `source_type=remote_managed` may have null `cwd`
|
||||
- local/git-backed workspaces should still require one of `cwd` or `repo_url`
|
||||
- preserve current behavior for existing callers that only send `cwd/repoUrl/repoRef`
|
||||
|
||||
## 2. Issue service
|
||||
|
||||
Update create/update flows to handle explicit workspace binding.
|
||||
|
||||
### Create behavior
|
||||
|
||||
Resolve defaults in this order:
|
||||
|
||||
1. explicit `projectWorkspaceId` from request
|
||||
2. `project.executionWorkspacePolicy.defaultProjectWorkspaceId`
|
||||
3. project's primary workspace
|
||||
4. null
|
||||
|
||||
Resolve `executionWorkspacePreference`:
|
||||
|
||||
1. explicit request field
|
||||
2. project policy default
|
||||
3. compatibility fallback to `inherit`
|
||||
|
||||
Do not create an execution workspace at issue creation time unless:
|
||||
|
||||
- `reuse_existing` is explicitly chosen and `executionWorkspaceId` is provided
|
||||
|
||||
Otherwise, workspace realization happens when execution starts.
|
||||
|
||||
### Update behavior
|
||||
|
||||
- allow changing `projectWorkspaceId` only if the workspace belongs to the same project
|
||||
- allow setting `executionWorkspaceId` only if it belongs to the same company and project
|
||||
- do not automatically destroy or relink historical work products when workspace linkage changes
|
||||
|
||||
## 3. Workspace realization service
|
||||
|
||||
Refactor `workspace-runtime.ts` so realization produces or reuses an `execution_workspaces` row.
|
||||
|
||||
### New flow
|
||||
|
||||
Input:
|
||||
|
||||
- issue
|
||||
- project workspace
|
||||
- project execution policy
|
||||
- execution topology hint
|
||||
- adapter/runtime configuration
|
||||
|
||||
Output:
|
||||
|
||||
- realized execution workspace record
|
||||
- runtime cwd/provider metadata
|
||||
|
||||
### Required modes
|
||||
|
||||
- `shared_workspace`
|
||||
- reuse a stable execution workspace representing the project primary/shared workspace
|
||||
- `isolated_workspace`
|
||||
- create or reuse a derived isolated execution workspace
|
||||
- `operator_branch`
|
||||
- create or reuse a long-lived branch workspace
|
||||
- `adapter_managed`
|
||||
- create an execution workspace with provider references and optional null `cwd`
|
||||
- `cloud_sandbox`
|
||||
- same as adapter-managed, but explicit remote sandbox semantics
|
||||
|
||||
### Reuse rules
|
||||
|
||||
When `reuse_existing` is requested:
|
||||
|
||||
- only list active or recently used execution workspaces
|
||||
- only for the same project
|
||||
- only for the same project workspace if one is specified
|
||||
- exclude archived and cleanup-failed workspaces
|
||||
|
||||
### Shared workspace realization
|
||||
|
||||
For compatibility mode and shared-workspace projects:
|
||||
|
||||
- create a stable execution workspace per project workspace when first needed
|
||||
- reuse it for subsequent runs
|
||||
|
||||
This avoids a special-case branch in later work product linkage.
|
||||
|
||||
## 4. Runtime service integration
|
||||
|
||||
When runtime services are started or reused:
|
||||
|
||||
- populate `execution_workspace_id`
|
||||
- continue populating `project_workspace_id`, `project_id`, and `issue_id`
|
||||
|
||||
When a runtime service yields a URL:
|
||||
|
||||
- optionally create or update a linked `issue_work_products` row of type `runtime_service` or `preview_url`
|
||||
|
||||
## 5. PR and preview reporting
|
||||
|
||||
Add a service for creating/updating `issue_work_products`.
|
||||
|
||||
### Supported V1 product types
|
||||
|
||||
- `pull_request`
|
||||
- `preview_url`
|
||||
- `runtime_service`
|
||||
- `branch`
|
||||
- `commit`
|
||||
- `artifact`
|
||||
- `document`
|
||||
|
||||
### GitHub PR reporting
|
||||
|
||||
For V1, GitHub is the only provider with richer semantics.
|
||||
|
||||
Supported statuses:
|
||||
|
||||
- `draft`
|
||||
- `ready_for_review`
|
||||
- `approved`
|
||||
- `changes_requested`
|
||||
- `merged`
|
||||
- `closed`
|
||||
|
||||
Represent these in `status` and `review_state` rather than inventing a separate PR table in V1.
|
||||
|
||||
## Routes and API
|
||||
|
||||
## 1. Project workspace routes
|
||||
|
||||
Extend existing routes:
|
||||
|
||||
- `GET /projects/:id/workspaces`
|
||||
- `POST /projects/:id/workspaces`
|
||||
- `PATCH /projects/:id/workspaces/:workspaceId`
|
||||
- `DELETE /projects/:id/workspaces/:workspaceId`
|
||||
|
||||
### New accepted/returned fields
|
||||
|
||||
- `sourceType`
|
||||
- `defaultRef`
|
||||
- `visibility`
|
||||
- `setupCommand`
|
||||
- `cleanupCommand`
|
||||
- `remoteProvider`
|
||||
- `remoteWorkspaceRef`
|
||||
|
||||
## 2. Execution workspace routes
|
||||
|
||||
Add:
|
||||
|
||||
- `GET /companies/:companyId/execution-workspaces`
|
||||
- filters:
|
||||
- `projectId`
|
||||
- `projectWorkspaceId`
|
||||
- `status`
|
||||
- `issueId`
|
||||
- `reuseEligible=true`
|
||||
- `GET /execution-workspaces/:id`
|
||||
- `PATCH /execution-workspaces/:id`
|
||||
- update status/metadata/cleanup fields only in V1
|
||||
|
||||
Do not add top-level navigation for these routes yet.
|
||||
|
||||
## 3. Work product routes
|
||||
|
||||
Add:
|
||||
|
||||
- `GET /issues/:id/work-products`
|
||||
- `POST /issues/:id/work-products`
|
||||
- `PATCH /work-products/:id`
|
||||
- `DELETE /work-products/:id`
|
||||
|
||||
### V1 mutation permissions
|
||||
|
||||
- board can create/update/delete all
|
||||
- agents can create/update for issues they are assigned or currently executing
|
||||
- deletion should generally archive rather than hard-delete once linked to historical output
|
||||
|
||||
## 4. Issue routes
|
||||
|
||||
Extend existing create/update payloads to accept:
|
||||
|
||||
- `projectWorkspaceId`
|
||||
- `executionWorkspacePreference`
|
||||
- `executionWorkspaceId`
|
||||
|
||||
Extend `GET /issues/:id` to return:
|
||||
|
||||
- `projectWorkspaceId`
|
||||
- `executionWorkspaceId`
|
||||
- `executionWorkspacePreference`
|
||||
- `currentExecutionWorkspace`
|
||||
- `workProducts[]`
|
||||
|
||||
## 5. Instance settings routes
|
||||
|
||||
Add support for:
|
||||
|
||||
- reading/writing `experimental.workspaces`
|
||||
|
||||
This is a UI gate only.
|
||||
|
||||
If there is no generic instance settings storage yet, the first slice can store this in the existing config/instance settings mechanism used by `/instance/settings`.
|
||||
|
||||
## UI Changes
|
||||
|
||||
## 1. `/instance/settings`
|
||||
|
||||
Add section:
|
||||
|
||||
- `Experimental`
|
||||
- `Enable Workspaces`
|
||||
|
||||
When off:
|
||||
|
||||
- hide new workspace-specific affordances
|
||||
- do not alter existing project or issue behavior
|
||||
|
||||
## 2. Project properties
|
||||
|
||||
Do not create a separate `Code` tab yet.
|
||||
Ship inside existing project properties first.
|
||||
|
||||
### Add or re-enable sections
|
||||
|
||||
- `Project Workspaces`
|
||||
- `Execution Defaults`
|
||||
- `Provisioning`
|
||||
- `Pull Requests`
|
||||
- `Previews and Runtime`
|
||||
- `Cleanup`
|
||||
|
||||
### Display rules
|
||||
|
||||
- only show when `experimental.workspaces=true`
|
||||
- keep wording generic enough for local and remote setups
|
||||
- only show git-specific fields when `sourceType=git_repo`
|
||||
- only show local-path-specific fields when not `remote_managed`
|
||||
|
||||
## 3. Issue create dialog
|
||||
|
||||
When the workspace experimental flag is on and the selected project has workspace automation or workspaces:
|
||||
|
||||
### Basic fields
|
||||
|
||||
- `Codebase`
|
||||
- select from project workspaces
|
||||
- default to policy default or primary workspace
|
||||
- `Execution mode`
|
||||
- `Project default`
|
||||
- `Shared workspace`
|
||||
- `Isolated workspace`
|
||||
- `Operator branch`
|
||||
|
||||
### Advanced section
|
||||
|
||||
- `Reuse existing execution workspace`
|
||||
|
||||
This control should query only:
|
||||
|
||||
- same project
|
||||
- same codebase if selected
|
||||
- active/recent workspaces
|
||||
- compact labels with branch or workspace name
|
||||
|
||||
Do not expose all execution workspaces in a noisy unfiltered list.
|
||||
|
||||
## 4. Issue detail
|
||||
|
||||
Add a `Work Product` tab when:
|
||||
|
||||
- the experimental flag is on, or
|
||||
- the issue already has work products
|
||||
|
||||
### Show
|
||||
|
||||
- current execution workspace summary
|
||||
- PR cards
|
||||
- preview cards
|
||||
- branch/commit rows
|
||||
- artifacts/documents
|
||||
|
||||
Add compact header chips:
|
||||
|
||||
- codebase
|
||||
- workspace
|
||||
- PR count/status
|
||||
- preview status
|
||||
|
||||
## 5. Execution workspace detail page
|
||||
|
||||
Add a detail route but no nav item.
|
||||
|
||||
Linked from:
|
||||
|
||||
- issue work product tab
|
||||
- project workspace/execution panels
|
||||
|
||||
### Show
|
||||
|
||||
- identity and status
|
||||
- project workspace origin
|
||||
- source issue
|
||||
- linked issues
|
||||
- branch/ref/provider info
|
||||
- runtime services
|
||||
- work products
|
||||
- cleanup state
|
||||
|
||||
## Runtime and Adapter Behavior
|
||||
|
||||
## 1. Local adapters
|
||||
|
||||
For local adapters:
|
||||
|
||||
- continue to use existing cwd/worktree realization paths
|
||||
- persist the result as execution workspaces
|
||||
- attach runtime services and work product to the execution workspace and issue
|
||||
|
||||
## 2. Remote or cloud adapters
|
||||
|
||||
For remote adapters:
|
||||
|
||||
- allow execution workspaces with null `cwd`
|
||||
- require provider metadata sufficient to identify the remote workspace/session
|
||||
- allow work product creation without any host-local process ownership
|
||||
|
||||
Examples:
|
||||
|
||||
- cloud coding agent opens a branch and PR on GitHub
|
||||
- Vercel preview URL is reported back as a preview work product
|
||||
- remote sandbox emits artifact URLs
|
||||
|
||||
## 3. Approval-aware PR workflow
|
||||
|
||||
V1 should support richer PR state tracking, but not a full review engine.
|
||||
|
||||
### Required actions
|
||||
|
||||
- `open_pr`
|
||||
- `mark_ready`
|
||||
|
||||
### Required review states
|
||||
|
||||
- `draft`
|
||||
- `ready_for_review`
|
||||
- `approved`
|
||||
- `changes_requested`
|
||||
- `merged`
|
||||
- `closed`
|
||||
|
||||
### Storage approach
|
||||
|
||||
- represent these as `issue_work_products` with `type='pull_request'`
|
||||
- use `status` and `review_state`
|
||||
- store provider-specific details in `metadata`
|
||||
|
||||
## Migration Plan
|
||||
|
||||
## 1. Existing installs
|
||||
|
||||
The migration posture is backward-compatible by default.
|
||||
|
||||
### Guarantees
|
||||
|
||||
- no existing project must be edited before it keeps working
|
||||
- no existing issue flow should start requiring workspace input
|
||||
- all new nullable columns must preserve current behavior when absent
|
||||
|
||||
## 2. Project workspace migration
|
||||
|
||||
Migrate `project_workspaces` in place.
|
||||
|
||||
### Backfill
|
||||
|
||||
- derive `source_type`
|
||||
- copy `repo_ref` to `default_ref`
|
||||
- leave new optional fields null
|
||||
|
||||
## 3. Issue migration
|
||||
|
||||
Do not backfill `project_workspace_id` or `execution_workspace_id` on all existing issues.
|
||||
|
||||
Reason:
|
||||
|
||||
- the safest migration is to preserve current runtime behavior and bind explicitly only when new workspace-aware flows are used
|
||||
|
||||
Interpret old issues as:
|
||||
|
||||
- `executionWorkspacePreference = inherit`
|
||||
- compatibility/shared behavior
|
||||
|
||||
## 4. Runtime history migration
|
||||
|
||||
Do not attempt a perfect historical reconstruction of execution workspaces in the migration itself.
|
||||
|
||||
Instead:
|
||||
|
||||
- create execution workspace records forward from first new run
|
||||
- optionally add a later backfill tool for recent runtime services if it proves valuable
|
||||
|
||||
## Rollout Order
|
||||
|
||||
## Phase 1: Schema and shared contracts
|
||||
|
||||
1. extend `project_workspaces`
|
||||
2. add `execution_workspaces`
|
||||
3. add `issue_work_products`
|
||||
4. extend `issues`
|
||||
5. extend `workspace_runtime_services`
|
||||
6. update shared types and validators
|
||||
|
||||
## Phase 2: Service wiring
|
||||
|
||||
1. update project workspace CRUD
|
||||
2. update issue create/update resolution
|
||||
3. refactor workspace realization to persist execution workspaces
|
||||
4. attach runtime services to execution workspaces
|
||||
5. add work product service and persistence
|
||||
|
||||
## Phase 3: API and UI
|
||||
|
||||
1. add execution workspace routes
|
||||
2. add work product routes
|
||||
3. add instance experimental settings toggle
|
||||
4. re-enable and revise project workspace UI behind the flag
|
||||
5. add issue create/update controls behind the flag
|
||||
6. add issue work product tab
|
||||
7. add execution workspace detail page
|
||||
|
||||
## Phase 4: Provider integrations
|
||||
|
||||
1. GitHub PR reporting
|
||||
2. preview URL reporting
|
||||
3. runtime-service-to-work-product linking
|
||||
4. remote/cloud provider references
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Existing installs continue to behave predictably with no required reconfiguration.
|
||||
2. Projects can define local, git, non-git, and remote-managed project workspaces.
|
||||
3. Issues can explicitly select a project workspace and execution preference.
|
||||
4. Each issue can point to one current execution workspace.
|
||||
5. Multiple issues can intentionally reuse the same execution workspace.
|
||||
6. Execution workspaces are persisted for both local and remote execution flows.
|
||||
7. Work products can be attached to issues with optional execution workspace linkage.
|
||||
8. GitHub PRs can be represented with richer lifecycle states.
|
||||
9. The main UI remains simple when the experimental flag is off.
|
||||
10. No top-level workspace navigation is required for this first slice.
|
||||
|
||||
## Risks and Mitigations
|
||||
|
||||
## Risk: too many overlapping workspace concepts
|
||||
|
||||
Mitigation:
|
||||
|
||||
- keep issue UI to `Codebase` and `Execution mode`
|
||||
- reserve execution workspace details for advanced pages
|
||||
|
||||
## Risk: breaking current projects on upgrade
|
||||
|
||||
Mitigation:
|
||||
|
||||
- nullable schema additions
|
||||
- in-place `project_workspaces` migration
|
||||
- compatibility defaults
|
||||
|
||||
## Risk: local-only assumptions leaking into cloud mode
|
||||
|
||||
Mitigation:
|
||||
|
||||
- make `cwd` optional for execution workspaces
|
||||
- use `provider_type` and `provider_ref`
|
||||
- use `PAPERCLIP_EXECUTION_TOPOLOGY` as a defaulting guardrail
|
||||
|
||||
## Risk: turning PRs into a bespoke subsystem too early
|
||||
|
||||
Mitigation:
|
||||
|
||||
- represent PRs as work products in V1
|
||||
- keep provider-specific details in metadata
|
||||
- defer a dedicated PR table unless usage proves it necessary
|
||||
|
||||
## Recommended First Engineering Slice
|
||||
|
||||
If we want the narrowest useful implementation:
|
||||
|
||||
1. extend `project_workspaces`
|
||||
2. add `execution_workspaces`
|
||||
3. extend `issues` with explicit workspace fields
|
||||
4. persist execution workspaces from existing local workspace realization
|
||||
5. add `issue_work_products`
|
||||
6. show project workspace controls and issue workspace controls behind the experimental flag
|
||||
7. add issue `Work Product` tab with PR/preview/runtime service display
|
||||
|
||||
This slice is enough to validate the model without yet building every provider integration or cleanup workflow.
|
||||
Reference in New Issue
Block a user