more docs on workspace strategy'
This commit is contained in:
parent
98b0e2fca1
commit
b754752164
1 changed files with 607 additions and 0 deletions
|
|
@ -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<Record<string, unknown>>;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
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.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue