| # 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. |
|
|