From b7547521643a028ccb9639ecab632ed6fdfef88a Mon Sep 17 00:00:00 2001 From: Dotta Date: Tue, 10 Mar 2026 14:49:53 -0500 Subject: [PATCH] more docs on workspace strategy' --- .../workspace-strategy-and-git-worktrees.md | 607 ++++++++++++++++++ 1 file changed, 607 insertions(+) diff --git a/doc/plans/workspace-strategy-and-git-worktrees.md b/doc/plans/workspace-strategy-and-git-worktrees.md index 178d6828..8ab63794 100644 --- a/doc/plans/workspace-strategy-and-git-worktrees.md +++ b/doc/plans/workspace-strategy-and-git-worktrees.md @@ -88,6 +88,613 @@ It also avoids forcing a host-filesystem model onto cloud agents. A cloud adapte - create an isolated branch/workspace inside the provider's remote environment - ignore local-only fields like host cwd while still honoring branch/ref/isolation intent +## Product and UX Requirements + +The current technical model is directionally right, but the product surface needs clearer separation between: + +- the generic cross-adapter concept of an **execution workspace** +- the user-visible local-git implementation concept of an **isolated issue checkout** +- the specific git implementation detail of a **git worktree** + +Those should not be collapsed into one label in the UI. + +### Terminology recommendation + +For product/UI copy: + +- use **execution workspace** for the generic cross-adapter concept +- use **isolated issue checkout** for the user-facing feature when we want to say "this issue gets its own branch/checkout" +- reserve **git worktree** for advanced or implementation detail views + +That gives Paperclip room to support: + +- local git worktrees +- remote sandbox checkouts +- adapter-managed remote workspaces + +without teaching users that "workspace" always means "git worktree on my machine". + +### Project-level defaults should drive the feature + +The main place this should be configured is the **project**, not the agent form. + +Reasoning: + +- whether a repo/project wants isolated issue checkouts is primarily a project workflow decision +- most operators do not want to configure runtime JSON per agent +- agents should inherit the project's workspace policy unless there is a strong adapter-specific override +- the board needs a place to express repo workflow defaults such as branching, PRs, cleanup, and preview lifecycle + +So the project should own a setting like: + +- `isolatedIssueCheckouts.enabled` or equivalent + +and that should be the default driver for new issues in that project. + +### Issue-level use should stay optional + +Even when a project supports isolated issue checkouts, not every issue should be forced into one. + +Examples: + +- a small fix may be fine in the main project workspace +- an operator may want to work directly on a long-lived branch +- a board user may want to create a task without paying the setup/cleanup overhead + +So the model should be: + +- project defines whether isolated issue checkouts are available and what the defaults are +- each issue can opt in or out when created +- the default issue value can be inherited from the project + +This should not require showing advanced adapter config in normal issue creation flows. + +### Runtime services should usually be hidden from the agent form + +The current raw runtime service JSON is too low-level as a primary UI for most local agents. + +For `claude_local` and `codex_local`, the likely desired behavior is: + +- Paperclip handles workspace runtime services under the hood using project/workspace policy +- operators do not need to hand-author generic runtime JSON in the agent form +- if a provider-specific adapter later needs richer runtime configuration, give it a purpose-built UI rather than generic JSON by default + +So the UI recommendation is: + +- keep runtime service JSON out of the default local-agent editing experience +- allow it only behind an advanced section or adapter-specific expert mode +- move the common workflow settings up to project-level workspace automation settings + +### Pull request workflow needs explicit ownership and approval rules + +Once Paperclip is creating isolated issue checkouts, it is implicitly touching a bigger workflow: + +- branch creation +- runtime service start/stop +- commit and push +- PR creation +- cleanup after merge or abandonment + +That means the product needs an explicit model for **who owns PR creation and merge readiness**. + +At minimum there are two valid modes: + +- agent-managed PR creation +- approval-gated PR creation + +And likely three distinct decision points: + +1. should the agent commit automatically? +2. should the agent open the PR automatically? +3. does opening or marking-ready require board approval? + +Those should not be buried inside adapter prompts. They are workflow policy. + +### Human operator workflows are different from issue-isolation workflows + +A human operator may want a long-lived personal integration branch such as `dotta` and may not want every task to create a new branch/workspace dance. + +That is a legitimate workflow and should be supported directly. + +So Paperclip should distinguish: + +- **isolated issue checkout workflows**: optimized for agent parallelism and issue-scoped isolation +- **personal branch workflows**: optimized for a human or operator making multiple related changes on a long-lived branch and creating PRs back to the main branch when convenient + +This implies: + +- isolated issue checkouts should be optional even when available +- project workflow settings should support a "use base branch directly" or "use preferred operator branch" path +- PR policy should not assume that every unit of work maps 1:1 to a new branch or PR + +## Recommended UX Model + +### 1. Project-level "Execution Workspace" settings + +Projects should have a dedicated settings area for workspace automation. + +Suggested structure: + +- `Execution Workspaces` + - `Enable isolated issue checkouts` + - `Default for new issues` + - `Checkout implementation` + - `Branch and PR behavior` + - `Runtime services` + - `Cleanup behavior` + +For a local git-backed project, the visible language can be more concrete: + +- `Enable isolated issue checkouts` +- `Implementation: Git worktree` + +For remote or adapter-managed projects, the same section can instead say: + +- `Implementation: Adapter-managed workspace` + +### 2. Issue creation should expose a simple opt-in + +When creating an issue inside a project with execution workspace support enabled: + +- show a checkbox or toggle such as `Use isolated issue checkout` +- default it from the project setting +- hide advanced workspace controls unless the operator has expanded an advanced section + +If the project does not support execution workspaces, do not show the control at all. + +This keeps the default UI light while preserving control. + +### 3. Agent configuration should be mostly inheritance-based + +The agent form should not be the primary place where operators assemble worktree/runtime policy for common local agents. + +Instead: + +- local coding agents inherit the project's execution workspace policy +- the agent form only exposes an override when truly necessary +- raw JSON config is advanced-only + +That means the common case becomes: + +- configure the project once +- assign a local coding agent +- create issues with optional isolated checkout behavior + +### 4. Advanced implementation detail can still exist + +There should still be an advanced view for power users that shows: + +- execution workspace strategy payload +- runtime service intent payload +- adapter-specific overrides + +But that should be treated like an expert/debugging surface, not the default mental model. + +## Recommended Workflow Policy Model + +### Workspace realization policy + +Suggested policy values: + +- `shared_project_workspace` +- `isolated_issue_checkout` +- `adapter_managed_isolated_workspace` + +For local git projects, `isolated_issue_checkout` may map to `git_worktree`. + +### Branch policy + +Suggested project-level branch policy fields: + +- `baseBranch` +- `branchMode`: `issue_scoped | operator_branch | project_primary` +- `branchTemplate` for issue-scoped branches +- `operatorPreferredBranch` for human/operator workflows + +This allows: + +- strict issue branches for agents +- long-lived personal branches for humans +- direct use of the project primary workspace when desired + +### Pull request policy + +Suggested project-level PR policy fields: + +- `prMode`: `none | agent_may_open | agent_auto_open | approval_required` +- `autoPushOnDone`: boolean +- `requireApprovalBeforeOpen`: boolean +- `requireApprovalBeforeReady`: boolean +- `defaultBaseBranch` + +This keeps PR behavior explicit and governable. + +### Cleanup policy + +Suggested project-level cleanup fields: + +- `stopRuntimeServicesOnDone` +- `removeIsolatedCheckoutOnDone` +- `removeIsolatedCheckoutOnMerged` +- `deleteIssueBranchOnMerged` +- `retainFailedWorkspaceForInspection` + +These matter because workspace automation is not just setup. The cleanup path is part of the product. + +## Design Recommendations for the Current UI Problem + +Based on the concerns above, the UI should change in these ways: + +### Agent UI + +- remove generic runtime service JSON from the default local-agent configuration surface +- keep raw workspace/runtime JSON behind advanced settings only +- prefer inheritance from project settings for `claude_local` and `codex_local` +- only add adapter-specific runtime UI when an adapter truly needs settings that Paperclip cannot infer + +### Project UI + +- add a project-level execution workspace settings section +- allow enabling isolated issue checkouts for that project +- store default issue behavior there +- expose branch, PR, runtime service, and cleanup defaults there + +### Issue creation UI + +- only show `Use isolated issue checkout` when the project has execution workspace support enabled +- keep it as an issue-level opt-in/out, defaulted from the project +- hide advanced execution workspace details unless requested + +## Consequences for the Spec + +This changes the emphasis of the plan in a useful way: + +- the project becomes the main workflow configuration owner +- the issue becomes the unit of opt-in/out for isolated checkout behavior +- the agent becomes an executor that usually inherits the workflow policy +- raw runtime JSON becomes an advanced/internal representation, not the main UX + +It also clarifies that PR creation and cleanup are not optional side notes. They are core parts of the workspace automation product surface. + +## Concrete Integration Checklist + +This section turns the product requirements above into a concrete implementation plan for the current codebase. + +### Guiding precedence rule + +The runtime decision order should become: + +1. issue-level execution workspace override +2. project-level execution workspace policy +3. agent-level adapter override +4. current default behavior + +That is the key architectural change. Today the implementation is too agent-config-centered for the desired UX. + +## Proposed Field Names + +### Project-level fields + +Add a project-owned execution workspace policy object. Suggested shared shape: + +```ts +type ProjectExecutionWorkspacePolicy = { + enabled: boolean; + defaultMode: "inherit_project_default" | "shared_project_workspace" | "isolated_issue_checkout"; + implementation: "git_worktree" | "adapter_managed"; + branchPolicy: { + baseBranch: string | null; + branchMode: "issue_scoped" | "operator_branch" | "project_primary"; + branchTemplate: string | null; + operatorPreferredBranch: string | null; + }; + pullRequestPolicy: { + mode: "none" | "agent_may_open" | "agent_auto_open" | "approval_required"; + autoPushOnDone: boolean; + requireApprovalBeforeOpen: boolean; + requireApprovalBeforeReady: boolean; + defaultBaseBranch: string | null; + }; + cleanupPolicy: { + stopRuntimeServicesOnDone: boolean; + removeExecutionWorkspaceOnDone: boolean; + removeExecutionWorkspaceOnMerged: boolean; + deleteIssueBranchOnMerged: boolean; + retainFailedWorkspaceForInspection: boolean; + }; + runtimeServices: { + mode: "disabled" | "project_default"; + services?: Array>; + }; +}; +``` + +Notes: + +- `enabled` controls whether the project exposes isolated issue checkout behavior at all +- `defaultMode` controls issue creation defaults +- `implementation` stays generic enough for local or remote adapters +- runtime service config stays nested here, not in the default agent form + +### Issue-level fields + +Add issue-owned opt-in/override fields. Suggested shape: + +```ts +type IssueExecutionWorkspaceSettings = { + mode?: "inherit_project_default" | "shared_project_workspace" | "isolated_issue_checkout"; + branchOverride?: string | null; + pullRequestModeOverride?: "inherit" | "none" | "agent_may_open" | "agent_auto_open" | "approval_required"; +}; +``` + +This should usually be hidden behind simple UI: + +- a checkbox like `Use isolated issue checkout` +- advanced controls only when needed + +### Agent-level fields + +Keep agent-level workspace/runtime configuration, but reposition it as advanced override only. + +Suggested semantics: + +- if absent, inherit project + issue policy +- if present, override only the implementation detail needed for that adapter + +## Shared Type and API Changes + +### 1. Shared project types + +Files to change first: + +- `packages/shared/src/types/project.ts` +- `packages/shared/src/validators/project.ts` + +Add: + +- `executionWorkspacePolicy?: ProjectExecutionWorkspacePolicy | null` + +### 2. Shared issue types + +Files to change: + +- `packages/shared/src/types/issue.ts` +- `packages/shared/src/validators/issue.ts` + +Add: + +- `executionWorkspaceSettings?: IssueExecutionWorkspaceSettings | null` + +### 3. DB schema + +If we want these fields persisted directly on existing entities instead of living in opaque JSON: + +- `packages/db/src/schema/projects.ts` +- `packages/db/src/schema/issues.ts` +- migration generation in `packages/db/src/migrations/` + +Recommended first cut: + +- store project policy as JSONB on `projects` +- store issue setting override as JSONB on `issues` + +That minimizes schema churn while the product model is still moving. + +Suggested columns: + +- `projects.execution_workspace_policy jsonb` +- `issues.execution_workspace_settings jsonb` + +## Server-Side Resolution Changes + +### 4. Project service read/write path + +Files: + +- `server/src/services/projects.ts` +- project routes in `server/src/routes/projects.ts` + +Tasks: + +- accept and validate project execution workspace policy +- return it from project API payloads +- enforce company scoping as usual + +### 5. Issue service create/update path + +Files: + +- `server/src/services/issues.ts` +- `server/src/routes/issues.ts` + +Tasks: + +- accept issue-level `executionWorkspaceSettings` +- when creating an issue in a project with execution workspaces enabled, default the issue setting from the project policy if not explicitly provided +- keep issue payload simple for normal clients; advanced fields may be optional + +### 6. Heartbeat and run resolution + +Primary file: + +- `server/src/services/heartbeat.ts` + +Current behavior should be refactored so workspace resolution is based on: + +- issue setting +- then project policy +- then adapter override + +Specific technical work: + +- load project execution workspace policy during run resolution +- load issue execution workspace settings during run resolution +- derive an effective execution workspace decision object before adapter launch +- keep adapter config as override only + +Suggested internal helper: + +```ts +type EffectiveExecutionWorkspaceDecision = { + mode: "shared_project_workspace" | "isolated_issue_checkout"; + implementation: "git_worktree" | "adapter_managed" | "project_primary"; + branchPolicy: {...}; + pullRequestPolicy: {...}; + cleanupPolicy: {...}; + runtimeServices: {...}; +}; +``` + +## UI Changes + +### 7. Project settings UI + +Likely files: + +- `ui/src/components/ProjectProperties.tsx` +- project detail/settings pages under `ui/src/pages/` +- project API client in `ui/src/api/projects.ts` + +Add a project-owned section: + +- `Execution Workspaces` + - enable isolated issue checkouts + - default for new issues + - implementation type + - branch settings + - PR settings + - cleanup settings + - runtime service defaults + +Important UX rule: + +- runtime service config should not default to raw JSON +- if the first cut must use JSON internally, wrap it in a minimal structured form or advanced disclosure + +### 8. Issue creation/edit UI + +Likely files: + +- issue create UI components and issue detail edit surfaces in `ui/src/pages/` +- issue API client in `ui/src/api/issues.ts` + +Add: + +- `Use isolated issue checkout` toggle, only when project policy enables it +- advanced workspace behavior controls only when expanded + +Do not show: + +- raw runtime service JSON +- raw strategy payloads + +in the default issue creation flow. + +### 9. Agent UI cleanup + +Files: + +- `ui/src/adapters/local-workspace-runtime-fields.tsx` +- `ui/src/adapters/codex-local/config-fields.tsx` +- `ui/src/adapters/claude-local/config-fields.tsx` + +Technical direction: + +- keep the existing config surface as advanced override +- remove it from the default form flow for local coding agents +- add explanatory copy that project execution workspace policy is inherited unless overridden + +## Adapter and Orchestration Changes + +### 10. Local adapter behavior + +Files: + +- `packages/adapters/codex-local/src/ui/build-config.ts` +- `packages/adapters/claude-local/src/ui/build-config.ts` +- local adapter execute paths already consuming env/context + +Tasks: + +- continue to accept resolved workspace/runtime context from heartbeat +- stop assuming the agent config is the primary source of workspace policy +- preserve adapter-specific override support + +### 11. Runtime service orchestration + +Files: + +- `server/src/services/workspace-runtime.ts` + +Tasks: + +- accept runtime service defaults from the effective project/issue policy +- keep adapter-config runtime service JSON as override-only +- preserve portability for remote adapters + +## Pull Request and Cleanup Workflow + +### 12. PR policy execution + +This is not fully implemented today and should be treated as a separate orchestration layer. + +Likely files: + +- `server/src/services/heartbeat.ts` +- future git/provider integration helpers + +Needed decisions: + +- when issue moves to done, should Paperclip auto-commit? +- should it auto-push? +- should it auto-open a PR? +- should PR open/ready be approval-gated? + +Suggested approach: + +- store PR policy on project +- resolve effective PR policy per issue/run +- emit explicit workflow actions rather than relying on prompt text alone + +### 13. Cleanup policy execution + +Likely files: + +- `server/src/services/workspace-runtime.ts` +- `server/src/services/heartbeat.ts` +- any future merge-detection hooks + +Needed behaviors: + +- stop runtime services on done or merged +- remove isolated checkout on done or merged +- delete branch on merged if policy says so +- optionally retain failed workspace for inspection + +## Recommended First Implementation Sequence + +To integrate these ideas without destabilizing the system, implement in this order: + +1. Add project policy fields to shared types, validators, DB, services, routes, and project UI. +2. Add issue-level execution workspace setting fields to shared types, validators, DB, services, routes, and issue create/edit UI. +3. Refactor heartbeat to compute effective execution workspace policy from issue -> project -> agent override. +4. Change local-agent UI so workspace/runtime JSON becomes advanced-only. +5. Move default runtime service behavior to project settings. +6. Add explicit PR policy storage and resolution. +7. Add explicit cleanup policy storage and resolution. + +## Definition of Done for This Product Shift + +This design shift is complete when all are true: + +- project settings own the default workspace policy +- issue creation exposes a simple opt-in/out when available +- local agent forms no longer require raw runtime JSON for common cases +- heartbeat resolves effective workspace behavior from project + issue + override precedence +- PR and cleanup behavior are modeled as explicit policy, not implied prompt behavior +- the UI language distinguishes execution workspace from local git worktree implementation details + ## What the Current Code Already Supports Paperclip already has the right foundation for a project-first model.