728 lines
25 KiB
Markdown
728 lines
25 KiB
Markdown
# Workspace Strategy and Git Worktrees
|
|
|
|
## Context
|
|
|
|
`PAP-447` asks how Paperclip should support worktree-driven coding workflows for local coding agents without turning that into a universal product requirement.
|
|
|
|
The motivating use case is strong:
|
|
|
|
- when an issue starts, a local coding agent may want its own isolated checkout
|
|
- the agent may need a dedicated branch and a predictable path to push later
|
|
- the agent may need to start one or more long-lived workspace runtime services, discover reachable ports or URLs, and report them back into the issue
|
|
- the workflow should reuse the same Paperclip instance and embedded database instead of creating a blank environment
|
|
- local agent auth should remain low-friction
|
|
|
|
At the same time, we do not want to hard-code "every agent uses git worktrees" into Paperclip:
|
|
|
|
- some operators use Paperclip to manage Paperclip and want worktrees heavily
|
|
- other operators will not want worktrees at all
|
|
- not every adapter runs in a local git repository
|
|
- not every adapter runs on the same machine as Paperclip
|
|
- Claude and Codex expose different built-in affordances, so Paperclip should not overfit to one tool
|
|
|
|
## Core Product Decision
|
|
|
|
Paperclip should model **execution workspaces**, not **worktrees**.
|
|
|
|
More specifically:
|
|
|
|
- the durable anchor is the **project workspace** or repo checkout
|
|
- an issue may derive a temporary **execution workspace** from that project workspace
|
|
- one implementation of an execution workspace is a **git worktree**
|
|
- adapters decide whether and how to use that derived workspace
|
|
|
|
This keeps the abstraction portable:
|
|
|
|
- `project workspace` is the repo/project-level concept
|
|
- `execution workspace` is the runtime checkout/cwd for a run
|
|
- `git worktree` is one strategy for creating that execution workspace
|
|
- `workspace runtime services` are long-lived processes or previews attached to that workspace
|
|
|
|
This also keeps the abstraction valid for non-local adapters:
|
|
|
|
- local adapters may receive a real filesystem cwd produced by Paperclip
|
|
- remote or cloud adapters may receive the same execution intent in structured form and realize it inside their own environment
|
|
- Paperclip should not assume that every adapter can see or use a host filesystem path directly
|
|
|
|
## Answer to the Main Framing Questions
|
|
|
|
### Are worktrees for agents or for repos/projects?
|
|
|
|
They should be treated as **repo/project-scoped infrastructure**, not agent identity.
|
|
|
|
The stable object is the project workspace. Agents come and go, ownership changes, and the same issue may be reassigned. A git worktree is a derived checkout of a repo workspace for a specific task or issue. The agent uses it, but should not own the abstraction.
|
|
|
|
If Paperclip makes worktrees agent-first, it will blur:
|
|
|
|
- agent home directories
|
|
- project repo roots
|
|
- issue-specific branches/checkouts
|
|
|
|
That makes reuse, reassignment, cleanup, and UI visibility harder.
|
|
|
|
### How do we preserve optionality?
|
|
|
|
By making execution workspace strategy **opt-in at the adapter/config layer**, not a global invariant.
|
|
|
|
Defaults should remain:
|
|
|
|
- existing project workspace resolution
|
|
- existing task-session resume
|
|
- existing agent-home fallback
|
|
|
|
Then local coding agents can opt into a strategy like `git_worktree`.
|
|
|
|
### How do we make this portable and adapter-appropriate?
|
|
|
|
By splitting responsibilities:
|
|
|
|
- Paperclip core resolves and records execution workspace state
|
|
- a shared local runtime helper can implement git-based checkout strategies
|
|
- each adapter launches its tool inside the resolved cwd using adapter-specific flags
|
|
|
|
This avoids forcing a Claude-shaped or Codex-shaped model onto all adapters.
|
|
|
|
It also avoids forcing a host-filesystem model onto cloud agents. A cloud adapter may interpret the same requested strategy as:
|
|
|
|
- create a fresh sandbox checkout from repo + ref
|
|
- 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
|
|
|
|
## What the Current Code Already Supports
|
|
|
|
Paperclip already has the right foundation for a project-first model.
|
|
|
|
### Project workspace is already first-class
|
|
|
|
- `project_workspaces` already exists in `packages/db/src/schema/project_workspaces.ts`
|
|
- the shared `ProjectWorkspace` type already includes `cwd`, `repoUrl`, and `repoRef` in `packages/shared/src/types/project.ts`
|
|
- docs already state that agents use the project's primary workspace for project-scoped tasks in `docs/api/goals-and-projects.md`
|
|
|
|
### Heartbeat already resolves workspace in the right order
|
|
|
|
Current run resolution already prefers:
|
|
|
|
1. project workspace
|
|
2. prior task session cwd
|
|
3. agent-home fallback
|
|
|
|
See `server/src/services/heartbeat.ts`.
|
|
|
|
### Session resume is already cwd-aware
|
|
|
|
Both local coding adapters treat session continuity as cwd-bound:
|
|
|
|
- Codex: `packages/adapters/codex-local/src/server/execute.ts`
|
|
- Claude: `packages/adapters/claude-local/src/server/execute.ts`
|
|
|
|
That means the clean insertion point is before adapter execution: resolve the final execution cwd first, then let the adapter run normally.
|
|
|
|
### Server-spawned local auth already exists
|
|
|
|
For server-spawned local adapters, Paperclip already injects a short-lived local JWT:
|
|
|
|
- JWT creation: `server/src/services/heartbeat.ts`
|
|
- adapter env injection:
|
|
- `packages/adapters/codex-local/src/server/execute.ts`
|
|
- `packages/adapters/claude-local/src/server/execute.ts`
|
|
|
|
The manual-local bootstrap path is still weaker in authenticated mode, but that is a related auth ergonomics problem, not a reason to make worktrees a core invariant.
|
|
|
|
## Tooling Observations from Vendor Docs
|
|
|
|
The linked tool docs support a project-first, adapter-specific launch model.
|
|
|
|
### Codex
|
|
|
|
- Codex app has a native worktree concept for parallel tasks in git repos
|
|
- Codex CLI documents running in a chosen working directory and resuming sessions from the current working directory
|
|
- Codex CLI does not present a single first-class portable CLI worktree abstraction that Paperclip should mirror directly
|
|
|
|
Implication:
|
|
|
|
- for `codex_local`, Paperclip should usually create/select the checkout itself and then launch Codex inside that cwd
|
|
|
|
### Claude
|
|
|
|
- Claude documents explicit git worktree workflows for parallel sessions
|
|
- Claude CLI supports `--worktree` / `-w`
|
|
- Claude sessions also remain tied to directory context
|
|
|
|
Implication:
|
|
|
|
- `claude_local` can optionally use native `--worktree`
|
|
- but Paperclip should still treat that as an adapter optimization, not the canonical cross-adapter model
|
|
|
|
## Local vs Remote Adapters
|
|
|
|
This plan must explicitly account for the fact that many adapters are not local.
|
|
|
|
Examples:
|
|
|
|
- local CLI adapters such as `codex_local` and `claude_local`
|
|
- cloud-hosted coding agents such as Cursor cloud agents
|
|
- future hosted Codex or Claude agent modes
|
|
- custom sandbox adapters built on E2B, Cloudflare, or similar environments
|
|
|
|
These adapters do not all share the same capabilities:
|
|
|
|
- some can use host git worktrees directly
|
|
- some can clone a repo and create branches remotely
|
|
- some may expose a virtual workspace concept with no direct git worktree equivalent
|
|
- some may not allow persistent filesystem state at all
|
|
|
|
Because of that, Paperclip should separate:
|
|
|
|
- **execution workspace intent**: what isolation/branch/repo behavior we want
|
|
- **adapter realization**: how a specific adapter implements that behavior
|
|
|
|
### Execution workspace intent
|
|
|
|
Paperclip should be able to express intentions such as:
|
|
|
|
- use the project's primary workspace directly
|
|
- create an isolated issue-scoped checkout
|
|
- base work on a given repo ref
|
|
- derive a branch name from the issue
|
|
- expose one or more reachable preview or service URLs if runtime services are started
|
|
|
|
### Adapter realization
|
|
|
|
Adapters should be free to map that intent into their own environment:
|
|
|
|
- local adapter: create a host git worktree and run in that cwd
|
|
- cloud sandbox adapter: clone repo into a sandbox, create a branch there, and return sandbox metadata
|
|
- hosted remote coding agent: call provider APIs that create a remote workspace/thread bound to the requested branch/ref
|
|
|
|
The important constraint is that the adapter reports back the realized execution workspace metadata in a normalized shape, even if the underlying implementation is not a git worktree.
|
|
|
|
## Proposed Model
|
|
|
|
Use three layers:
|
|
|
|
1. `project workspace`
|
|
2. `execution workspace`
|
|
3. `workspace runtime services`
|
|
4. `adapter session`
|
|
|
|
### 1. Project workspace
|
|
|
|
Long-lived repo anchor.
|
|
|
|
Examples:
|
|
|
|
- `./paperclip`
|
|
- repo URL and base ref
|
|
- primary checkout for a project
|
|
|
|
### 2. Execution workspace
|
|
|
|
Derived runtime checkout for a specific issue/run.
|
|
|
|
Examples:
|
|
|
|
- direct use of the project primary workspace
|
|
- git worktree derived from the project workspace
|
|
- remote sandbox checkout derived from repo URL + ref
|
|
- custom checkout produced by an adapter-specific script
|
|
|
|
### 3. Adapter session
|
|
|
|
Long-lived or semi-long-lived processes associated with a workspace.
|
|
|
|
Examples:
|
|
|
|
- local web server
|
|
- background worker
|
|
- sandbox preview URL
|
|
- test watcher
|
|
- tunnel process
|
|
|
|
These are not specific to Paperclip. They are a common property of working in a dev workspace, whether local or remote.
|
|
|
|
### 4. Adapter session
|
|
|
|
Claude/Codex conversation continuity and runtime state, which remains cwd-aware and should follow the execution workspace rather than define it.
|
|
|
|
## Recommended Configuration Surface
|
|
|
|
Introduce a generic execution workspace strategy in adapter config.
|
|
|
|
Example shape:
|
|
|
|
```json
|
|
{
|
|
"workspaceStrategy": {
|
|
"type": "project_primary"
|
|
}
|
|
}
|
|
```
|
|
|
|
Or:
|
|
|
|
```json
|
|
{
|
|
"workspaceStrategy": {
|
|
"type": "git_worktree",
|
|
"baseRef": "origin/main",
|
|
"branchTemplate": "{{issue.identifier}}-{{slug}}",
|
|
"worktreeParentDir": ".paperclip/instances/default/worktrees/projects/{{project.id}}",
|
|
"cleanupPolicy": "on_merged",
|
|
"startDevServer": true,
|
|
"devServerCommand": "pnpm dev",
|
|
"devServerReadyUrlTemplate": "http://127.0.0.1:{{port}}/api/health"
|
|
}
|
|
}
|
|
```
|
|
|
|
Remote adapters may instead use shapes like:
|
|
|
|
```json
|
|
{
|
|
"workspaceStrategy": {
|
|
"type": "isolated_checkout",
|
|
"provider": "adapter_managed",
|
|
"baseRef": "origin/main",
|
|
"branchTemplate": "{{issue.identifier}}-{{slug}}"
|
|
}
|
|
}
|
|
```
|
|
|
|
The important point is that `git_worktree` is a strategy value for adapters that can use it, not the universal contract.
|
|
|
|
### Workspace runtime services
|
|
|
|
Do not model this as a Paperclip-specific `devServer` flag.
|
|
|
|
Instead, model it as a generic list of workspace-attached runtime services.
|
|
|
|
Example shape:
|
|
|
|
```json
|
|
{
|
|
"workspaceRuntime": {
|
|
"services": [
|
|
{
|
|
"name": "web",
|
|
"description": "Primary app server for this workspace",
|
|
"command": "pnpm dev",
|
|
"cwd": ".",
|
|
"env": {
|
|
"DATABASE_URL": "${workspace.env.DATABASE_URL}"
|
|
},
|
|
"port": {
|
|
"type": "auto"
|
|
},
|
|
"readiness": {
|
|
"type": "http",
|
|
"urlTemplate": "http://127.0.0.1:${port}/api/health"
|
|
},
|
|
"expose": {
|
|
"type": "url",
|
|
"urlTemplate": "http://127.0.0.1:${port}"
|
|
},
|
|
"reuseScope": "project_workspace",
|
|
"lifecycle": "shared",
|
|
"stopPolicy": {
|
|
"type": "idle_timeout",
|
|
"idleSeconds": 1800
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
This contract is intentionally generic:
|
|
|
|
- `command` can start any workspace-attached process, not just a web server
|
|
- database reuse is handled through env/config injection, not a product-specific special case
|
|
- local and remote adapters can realize the same service intent differently
|
|
|
|
### Service intent vs service realization
|
|
|
|
Paperclip should distinguish between:
|
|
|
|
- **service intent**: what kind of companion runtime the workspace wants
|
|
- **service realization**: how a local or remote adapter actually starts and exposes it
|
|
|
|
Examples:
|
|
|
|
- local adapter:
|
|
- starts `pnpm dev`
|
|
- allocates a free host port
|
|
- health-checks a localhost URL
|
|
- reports `{ pid, port, url }`
|
|
- cloud sandbox adapter:
|
|
- starts a preview process inside the sandbox
|
|
- receives a provider preview URL
|
|
- reports `{ sandboxId, previewUrl }`
|
|
- hosted remote coding agent:
|
|
- may ask the provider to create a preview environment
|
|
- reports provider-native workspace/service metadata
|
|
|
|
Paperclip should normalize the reported metadata without requiring every adapter to look like a host-local process.
|
|
|
|
Keep issue-level overrides possible through the existing `assigneeAdapterOverrides` shape in `packages/shared/src/types/issue.ts`.
|
|
|
|
## Responsibilities by Layer
|
|
|
|
### Paperclip Core
|
|
|
|
Paperclip core should:
|
|
|
|
- resolve the base project workspace for the issue
|
|
- resolve or request an execution workspace
|
|
- resolve or request workspace runtime services when configured
|
|
- inject execution workspace metadata into run context
|
|
- persist enough metadata for board visibility and cleanup
|
|
- manage lifecycle hooks around run start/finish where needed
|
|
|
|
Paperclip core should not:
|
|
|
|
- require worktrees for all agents
|
|
- assume every adapter is local and git-backed
|
|
- assume every runtime service is a localhost process with a PID
|
|
- encode tool-specific worktree prompts as core product behavior
|
|
|
|
### Shared Local Runtime Helper
|
|
|
|
A shared server-side helper should handle local git mechanics:
|
|
|
|
- validate repo root
|
|
- create/select branch
|
|
- create/select git worktree
|
|
- allocate a free port
|
|
- optionally start and track a dev server
|
|
- return `{ cwd, branchName, url }`
|
|
|
|
This helper can be reused by:
|
|
|
|
- `codex_local`
|
|
- `claude_local`
|
|
- future local adapters like Cursor/OpenCode equivalents
|
|
|
|
This helper is intentionally for local adapters only. Remote adapters should not be forced through a host-local git helper.
|
|
|
|
### Shared Runtime Service Manager
|
|
|
|
In addition to the local git helper, Paperclip should define a generic runtime service manager contract.
|
|
|
|
Its job is to:
|
|
|
|
- decide whether a configured service should be reused or started fresh
|
|
- allocate local ports when needed
|
|
- start and monitor local processes when the adapter/runtime realization is host-local
|
|
- record normalized service metadata for remote realizations
|
|
- run readiness checks
|
|
- surface service URLs and state to the board
|
|
- apply shutdown policy
|
|
|
|
This manager should not be hard-coded to "dev servers". It should work for any long-lived workspace companion process.
|
|
|
|
### Adapter
|
|
|
|
The adapter should:
|
|
|
|
- accept the resolved execution cwd
|
|
- or accept structured execution workspace intent when no host cwd is available
|
|
- accept structured workspace runtime service intent when service orchestration is delegated to the adapter
|
|
- launch its tool with adapter-specific flags
|
|
- keep its own session continuity semantics
|
|
|
|
For example:
|
|
|
|
- `codex_local`: run inside cwd, likely with `--cd` or process cwd
|
|
- `claude_local`: run inside cwd, optionally use `--worktree` when it helps
|
|
- remote sandbox adapter: create its own isolated workspace from repo/ref/branch intent and report the realized remote workspace metadata back to Paperclip
|
|
|
|
For runtime services:
|
|
|
|
- local adapter or shared host manager: start the local process and return host-local metadata
|
|
- remote adapter: create or reuse the remote preview/service and return normalized remote metadata
|
|
|
|
## Minimal Data Model Additions
|
|
|
|
Do not create a fully first-class `worktrees` table yet.
|
|
|
|
Start smaller by recording derived execution workspace metadata on runs, issues, or both.
|
|
|
|
Suggested fields to introduce:
|
|
|
|
- `executionWorkspaceStrategy`
|
|
- `executionWorkspaceCwd`
|
|
- `executionBranchName`
|
|
- `executionWorkspaceStatus`
|
|
- `executionServiceRefs`
|
|
- `executionCleanupStatus`
|
|
|
|
These can live first on `heartbeat_runs.context_snapshot` or adjacent run metadata, with an optional later move into a dedicated table if the UI and cleanup workflows justify it.
|
|
|
|
For runtime services specifically, Paperclip should eventually track normalized fields such as:
|
|
|
|
- `serviceName`
|
|
- `serviceKind`
|
|
- `scopeType`
|
|
- `scopeId`
|
|
- `status`
|
|
- `command`
|
|
- `cwd`
|
|
- `envFingerprint`
|
|
- `port`
|
|
- `url`
|
|
- `provider`
|
|
- `providerRef`
|
|
- `startedByRunId`
|
|
- `ownerAgentId`
|
|
- `lastUsedAt`
|
|
- `stopPolicy`
|
|
- `healthStatus`
|
|
|
|
The first implementation can keep this in run metadata if needed, but the long-term shape is a generic runtime service registry rather than one-off server URL fields.
|
|
|
|
## Concrete Implementation Plan
|
|
|
|
## Phase 1: Define Shared Contracts
|
|
|
|
1. Introduce a shared execution workspace strategy contract in `packages/shared`.
|
|
2. Add adapter-config schema support for:
|
|
- `workspaceStrategy.type`
|
|
- `baseRef`
|
|
- `branchTemplate`
|
|
- `worktreeParentDir`
|
|
- `cleanupPolicy`
|
|
- optional workspace runtime service settings
|
|
3. Keep the existing `useProjectWorkspace` flag working as a lower-level compatibility control.
|
|
4. Distinguish local realization fields from generic intent fields so remote adapters are not forced to consume host cwd values.
|
|
5. Define a generic `workspaceRuntime.services[]` contract with:
|
|
- service name
|
|
- command or provider-managed intent
|
|
- env overrides
|
|
- readiness checks
|
|
- exposure metadata
|
|
- reuse scope
|
|
- lifecycle
|
|
- stop policy
|
|
|
|
Acceptance:
|
|
|
|
- adapter config can express `project_primary` and `git_worktree`
|
|
- config remains optional and backwards-compatible
|
|
- runtime services are expressed generically, not as Paperclip-only dev-server flags
|
|
|
|
## Phase 2: Resolve Execution Workspace in Heartbeat
|
|
|
|
1. Extend heartbeat workspace resolution so it can return a richer execution workspace result.
|
|
2. Keep current fallback order, but distinguish:
|
|
- base project workspace
|
|
- derived execution workspace
|
|
3. Inject resolved execution workspace details into `context.paperclipWorkspace` for local adapters and into a generic execution-workspace intent payload for adapters that need structured remote realization.
|
|
4. Resolve configured runtime service intent alongside the execution workspace so the adapter or host manager receives a complete workspace runtime contract.
|
|
|
|
Primary touchpoints:
|
|
|
|
- `server/src/services/heartbeat.ts`
|
|
|
|
Acceptance:
|
|
|
|
- runs still work unchanged when no strategy is configured
|
|
- the resolved context clearly indicates which strategy produced the cwd
|
|
|
|
## Phase 3: Add Shared Local Git Workspace Helper
|
|
|
|
1. Create a server-side helper module for local repo checkout strategies.
|
|
2. Implement `git_worktree` strategy:
|
|
- validate git repo at base workspace cwd
|
|
- derive branch name from issue
|
|
- create or reuse a worktree path
|
|
- detect collisions cleanly
|
|
3. Return structured metadata:
|
|
- final cwd
|
|
- branch name
|
|
- worktree path
|
|
- repo root
|
|
|
|
Acceptance:
|
|
|
|
- helper is reusable outside a single adapter
|
|
- worktree creation is deterministic for a given issue/config
|
|
- remote adapters remain unaffected by this helper
|
|
|
|
## Phase 4: Optional Dev Server Lifecycle
|
|
|
|
Rename this phase conceptually to **workspace runtime service lifecycle**.
|
|
|
|
1. Add optional runtime service startup on execution workspace creation.
|
|
2. Support both:
|
|
- host-managed local services
|
|
- adapter-managed remote services
|
|
3. For local services:
|
|
- allocate a free port before launch when required
|
|
- start the configured command in the correct cwd
|
|
- run readiness checks
|
|
- register the realized metadata
|
|
4. For remote services:
|
|
- let the adapter return normalized service metadata after provisioning
|
|
- do not assume PID or localhost access
|
|
5. Post or update issue-visible metadata with the service URLs and labels.
|
|
|
|
Acceptance:
|
|
|
|
- runtime service startup remains opt-in
|
|
- failures produce actionable run logs and issue comments
|
|
- same embedded DB / Paperclip instance can be reused through env/config injection when appropriate
|
|
- remote service realizations are represented without pretending to be local processes
|
|
|
|
## Phase 5: Runtime Service Reuse, Tracking, and Shutdown
|
|
|
|
1. Introduce a generic runtime service registry.
|
|
2. Each service should be tracked with:
|
|
- `scopeType`: `project_workspace | execution_workspace | run | agent`
|
|
- `scopeId`
|
|
- `serviceName`
|
|
- `status`
|
|
- `command` or provider metadata
|
|
- `cwd` if local
|
|
- `envFingerprint`
|
|
- `port`
|
|
- `url`
|
|
- `provider` / `providerRef`
|
|
- `ownerAgentId`
|
|
- `startedByRunId`
|
|
- `lastUsedAt`
|
|
- `stopPolicy`
|
|
3. Introduce a deterministic `reuseKey`, for example:
|
|
- `projectWorkspaceId + serviceName + envFingerprint`
|
|
4. Reuse policy:
|
|
- if a healthy service with the same reuse key exists, attach to it
|
|
- otherwise start a new service
|
|
5. Distinguish lifecycle classes:
|
|
- `shared`: reusable across runs, usually scoped to `project_workspace`
|
|
- `ephemeral`: tied to `execution_workspace` or `run`
|
|
6. Shutdown policy:
|
|
- `run` scope: stop when run ends
|
|
- `execution_workspace` scope: stop when workspace is cleaned up
|
|
- `project_workspace` scope: stop on idle timeout, explicit stop, or workspace removal
|
|
- `agent` scope: stop when ownership is transferred or agent policy requires it
|
|
7. Health policy:
|
|
- readiness check at startup
|
|
- periodic or on-demand liveness checks
|
|
- mark unhealthy before killing when possible
|
|
|
|
Acceptance:
|
|
|
|
- Paperclip can decide whether to reuse or start a fresh service deterministically
|
|
- local and remote services share a normalized tracking model
|
|
- shutdown is policy-driven instead of implicit
|
|
- board can understand why a service was kept, reused, or stopped
|
|
|
|
## Phase 6: Adapter Integration
|
|
|
|
1. Update `codex_local` to consume resolved execution workspace cwd.
|
|
2. Update `claude_local` to consume resolved execution workspace cwd.
|
|
3. Define a normalized adapter contract for remote adapters that receive execution workspace intent instead of a host-local cwd.
|
|
4. Optionally allow Claude-specific optimization paths using native `--worktree`, but keep the shared server-side checkout strategy as canonical for local adapters.
|
|
5. Define how adapters return runtime service realizations:
|
|
- local host-managed service reference
|
|
- remote provider-managed service reference
|
|
|
|
Acceptance:
|
|
|
|
- adapter behavior remains unchanged when strategy is absent
|
|
- session resume remains cwd-safe
|
|
- no adapter is forced into git behavior
|
|
- remote adapters can implement equivalent isolation without pretending to be local worktrees
|
|
- adapters can report service URLs and lifecycle metadata in a normalized shape
|
|
|
|
## Phase 7: Visibility and Issue Comments
|
|
|
|
1. Expose execution workspace metadata in run details and optionally issue detail UI:
|
|
- strategy
|
|
- cwd
|
|
- branch
|
|
- runtime service refs
|
|
2. Expose runtime services with:
|
|
- service name
|
|
- status
|
|
- URL
|
|
- scope
|
|
- owner
|
|
- health
|
|
3. Add standard issue comment output when a worktree-backed or remotely isolated run starts:
|
|
- branch
|
|
- worktree path
|
|
- service URLs if present
|
|
|
|
Acceptance:
|
|
|
|
- board can see where the agent is working
|
|
- board can see what runtime services exist for that workspace
|
|
- issue thread becomes the handoff surface for branch names and reachable URLs
|
|
|
|
## Phase 8: Cleanup Policies
|
|
|
|
1. Implement cleanup policies:
|
|
- `manual`
|
|
- `on_done`
|
|
- `on_merged`
|
|
2. For worktree cleanup:
|
|
- stop tracked runtime services if owned by the workspace lifecycle
|
|
- remove worktree
|
|
- optionally delete local branch after merge
|
|
3. Start with conservative defaults:
|
|
- do not auto-delete anything unless explicitly configured
|
|
|
|
Acceptance:
|
|
|
|
- cleanup is safe and reversible by default
|
|
- merge-based cleanup can be introduced after basic lifecycle is stable
|
|
|
|
## Phase 9: Auth Ergonomics Follow-Up
|
|
|
|
This is related, but should be tracked separately from the workspace strategy work.
|
|
|
|
Needed improvement:
|
|
|
|
- make manual local agent bootstrap in authenticated/private mode easier, so operators can become `codexcoder` or `claudecoder` locally without depending on an already-established browser-auth CLI context
|
|
|
|
This should likely take the form of a local operator bootstrap flow, not a weakening of runtime auth boundaries.
|
|
|
|
## Rollout Strategy
|
|
|
|
1. Ship the shared config contract and no-op-compatible heartbeat changes first.
|
|
2. Pilot with `codexcoder` and `claudecoder` only.
|
|
3. Test against Paperclip-on-Paperclip workflows first.
|
|
4. Keep `project_primary` as the default for all existing agents.
|
|
5. Add UI exposure and cleanup only after the core runtime path is stable.
|
|
|
|
## Acceptance Criteria
|
|
|
|
1. Worktree behavior is optional, not a global requirement.
|
|
2. Project workspaces remain the canonical repo anchor.
|
|
3. Local coding agents can opt into isolated issue-scoped execution workspaces.
|
|
4. The same model works for both `codex_local` and `claude_local` without forcing a tool-specific abstraction into core.
|
|
5. Remote adapters can consume the same execution workspace intent without requiring host-local filesystem access.
|
|
6. Session continuity remains correct because each adapter resumes relative to its realized execution workspace.
|
|
7. Workspace runtime services are modeled generically, not as Paperclip-specific dev-server toggles.
|
|
8. Board users can see branch/path/URL information for worktree-backed or remotely isolated runs.
|
|
9. Service reuse and shutdown are deterministic and policy-driven.
|
|
10. Cleanup is conservative by default.
|
|
|
|
## Recommended Initial Scope
|
|
|
|
To keep this tractable, the first implementation should:
|
|
|
|
- support only local coding adapters
|
|
- support only `project_primary` and `git_worktree`
|
|
- avoid a new dedicated database table for worktrees
|
|
- start with a single host-managed runtime service implementation path
|
|
- postpone merge-driven cleanup automation until after basic start/run/visibility is proven
|
|
|
|
That is enough to validate the local product shape without prematurely freezing the wrong abstraction.
|
|
|
|
Follow-up expansion after that validation:
|
|
|
|
- define the remote adapter contract for adapter-managed isolated checkouts
|
|
- add one cloud/sandbox adapter implementation path
|
|
- normalize realized metadata so local and remote execution workspaces appear similarly in the UI
|
|
- expand the runtime service registry from local host-managed services to remote adapter-managed services
|