# How Paperclip Execution Workspaces Manage Project Directories, Git Worktrees, and Runtime Services

> Learn how Paperclip execution workspaces streamline project directories, Git worktrees, and runtime services for efficient agent runs. Discover isolated, reproducible snapshots and coordinated services.

- Repository: [Paperclip/paperclip](https://github.com/paperclipai/paperclip)
- Tags: internals
- Published: 2026-08-18

---

**Paperclip execution workspaces isolate every agent run inside a dedicated, transient directory using Git worktrees to create cheap, reproducible snapshots of project directories, while launching coordinated runtime services—including a Vite HTML renderer, agent container, and task watchdog—within the same process group.**

Paperclip execution workspaces provide the foundational isolation layer that enables safe, concurrent AI agent runs against precise repository states. According to the `paperclipai/paperclip` source code, each workspace is initialized as a **Git worktree** pointing to a specific commit, ensuring that parallel agent executions never interfere with each other or the main repository checkout.

## Git Worktrees and Project Directory Isolation

Every Paperclip execution workspace begins as a unique directory under the configured `WORKSPACES_ROOT`, defined in [`server/src/worktree-config.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/worktree-config.ts). When an agent request arrives, the server performs three atomic steps to establish the project directory view:

1. **Creates a unique workspace folder** using a generated ID that includes timestamps and random suffixes for collision resistance.
2. **Initializes a Git worktree** pointing at the company's project repository URL (stored in the company-scoped `projects` table).
3. **Checks out the exact commit** referenced in the run payload, or defaults to the latest `origin/main` if no commit is specified.

The **Git worktree** mechanism is central to Paperclip's isolation strategy. Because worktrees share the same underlying Git object store while maintaining independent working directories, Paperclip can spin up dozens of workspaces for the same repository with minimal disk overhead. Only the checked-out files consume space—not the entire Git history.

```typescript
import { execSync } from 'child_process';
import { join } from 'path';
import { WORKSPACES_ROOT, REPO_PATH } from './worktree-config';

// 1️⃣  Generate a unique workspace folder
const workspaceId = `ws-${Date.now()}-${Math.random().toString(36).slice(2)}`;
const workspacePath = join(WORKSPACES_ROOT, workspaceId);
execSync(`mkdir -p ${workspacePath}`);

// 2️⃣  Add a git worktree pointing at the desired commit
const commitSha = payload.commitSha ?? 'origin/main';
execSync(
  `git -C ${REPO_PATH} worktree add --detach ${workspacePath} ${commitSha}`
);

```

## Runtime Services Architecture

Once the file tree is ready, Paperclip spins up four distinct **runtime services** that operate inside the workspace boundary. All services run within the same OS process group but remain logically separated through environment variable scoping and port isolation.

### Vite HTML Renderer

The **Vite HTML Renderer** ([`server/src/vite-html-renderer.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/vite-html-renderer.ts)) serves the web UI for each run, providing file browsers and live log streaming. It starts a dedicated Vite development server per workspace, binding to an available system port and serving static assets from `ui/public/` alongside the compiled UI bundle.

```typescript
import { createServer } from 'vite';
import { workspacePath } from './workspace-manager';

async function startRenderer() {
  const server = await createServer({
    root: workspacePath,
    server: { port: 0 }, // pick a free port
    // ...other Vite options
  });
  await server.listen();
  return server;
}

```

### Agent Runtime Container

The **Agent Runtime Container** executes the actual AI agent code (Claude, Claude-3, and other adapters). Implementation details reside in `packages/adapter-utils/`, while the container itself launches via the internal Docker runner specified in [`doc/spec/agents-runtime.md`](https://github.com/paperclipai/paperclip/blob/main/doc/spec/agents-runtime.md). The agent runs as a child process with environment variables including `WORKSPACE_PATH` and `PROJECT_ID`, communicating with the server through a local WebSocket RPC channel for real-time log streaming.

```typescript
import { spawn } from 'child_process';
import { workspacePath } from './workspace-manager';

function runAgent(agentName: string, args: string[]) {
  const env = { ...process.env, WORKSPACE_PATH: workspacePath };
  const child = spawn('node', [`./agents/${agentName}.js`, ...args], { env });

  child.stdout.on('data', (data) => {
    // forward logs to the UI via WebSocket
    broadcastLog(data.toString());
  });

  child.on('close', (code) => {
    // cleanup after the run
    console.log(`Agent exited with code ${code}`);
  });
}

```

### Task Watchdog

The **Task Watchdog** ([`server/src/task-watchdog.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/task-watchdog.ts)) monitors run health, enforces budget caps, and writes structured activity logs as specified in [`doc/spec/agent-runs.md`](https://github.com/paperclipai/paperclip/blob/main/doc/spec/agent-runs.md). It operates as a supervisory process that can terminate the agent container if resource limits are exceeded.

### File-Browser Service

The **File-Browser Service** provides UI-driven read/write access to workspace files, anchored strictly to the worktree root. UI components for this service are defined in [`ui/storybook/stories/workspace-file-browser.stories.tsx`](https://github.com/paperclipai/paperclip/blob/main/ui/storybook/stories/workspace-file-browser.stories.tsx), ensuring users can navigate the isolated project directory without escaping the workspace boundary.

## Workspace Lifecycle and Cleanup

When an agent run completes, Paperclip executes a deterministic teardown sequence:

- **Collects logs and artifacts** from the workspace directory, including stdout captures, file outputs, and generated screenshots.
- **Archives the workspace** optionally compressing it for later inspection or rerun debugging.
- **Deletes the Git worktree** using `git worktree remove` followed by `git worktree prune` to reclaim disk space while keeping the shared object store intact.

This lifecycle ensures that **transient workspaces** never accumulate indefinitely, even when runs fail or hang.

## Concurrent Execution and Reproducibility

Because each run receives its own Git worktree, Paperclip can execute multiple agents against different commits of the same repository simultaneously. The shared Git object store means the overhead remains minimal—each workspace only stores the checked-out tree snapshot, not the full `.git` history.

The exact commit SHA is recorded in run metadata, enabling **bit-for-bit reproducibility** when retrying failed jobs. When a user reruns a specific job, Paperclip recreates the worktree at the identical commit, guaranteeing the agent operates on the same file states as the original execution.

## Summary

- **Paperclip execution workspaces** are transient directories created under `WORKSPACES_ROOT` for every agent run.
- **Git worktrees** provide isolated, cheap snapshots of project directories without duplicating repository history.
- **Four runtime services** operate inside each workspace: the Vite HTML Renderer ([`vite-html-renderer.ts`](https://github.com/paperclipai/paperclip/blob/main/vite-html-renderer.ts)), Agent Runtime Container (`adapter-utils/`), Task Watchdog ([`task-watchdog.ts`](https://github.com/paperclipai/paperclip/blob/main/task-watchdog.ts)), and File-Browser Service.
- **Process isolation** uses environment variables like `WORKSPACE_PATH` and WebSocket RPC channels to separate agent logic from UI services while maintaining real-time communication.
- **Automatic cleanup** archives artifacts and prunes worktrees after run completion, preventing disk exhaustion during high-concurrency scenarios.

## Frequently Asked Questions

### How does Paperclip isolate project directories for concurrent agent runs?

Paperclip creates a unique Git worktree for every agent run, configured in [`server/src/worktree-config.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/worktree-config.ts). Each worktree points to the shared Git object store but maintains an independent working directory, allowing dozens of runs to execute against different commits of the same repository without file conflicts.

### What runtime services execute inside a Paperclip workspace?

Each workspace runs four services: the **Vite HTML Renderer** for UI serving ([`server/src/vite-html-renderer.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/vite-html-renderer.ts)), the **Agent Runtime Container** for AI code execution (`packages/adapter-utils/`), the **Task Watchdog** for resource monitoring ([`server/src/task-watchdog.ts`](https://github.com/paperclipai/paperclip/blob/main/server/src/task-watchdog.ts)), and the **File-Browser Service** for workspace file navigation.

### How does Paperclip handle Git repository state management?

When initializing a workspace, Paperclip executes `git worktree add --detach` to create a detached HEAD at the specific commit SHA provided in the run payload. This ensures the workspace reflects an exact, immutable snapshot of the repository state, with the commit hash recorded in run metadata for reproducibility.

### What happens to workspace data after an agent run completes?

Paperclip collects logs and artifacts, optionally archives the workspace directory for debugging, then removes the Git worktree using `git worktree remove` and prunes the shared repository. This teardown occurs regardless of exit status, ensuring transient workspaces do not consume disk space indefinitely.