Workspace Management
Workspace managers provide filesystem isolation for parallel agent execution. Each agent operates in its own copy of the project, and changes are merged back when complete.
The WorkspaceManager Protocol
from pathlib import Path
from rigger import Task, MergeResult
class WorkspaceManager:
def create(self, main_root: Path, task: Task, branch_name: str) -> Path: ...
def merge(self, worktree: Path, main_root: Path) -> MergeResult: ...
def cleanup(self, worktree: Path) -> None: ...
GitWorktreeManager
Uses git worktree to create isolated branches. Best for git-based projects where you want branch-level isolation and merge integration.
How it works:
- create() — Runs
git worktree addto create a new branch and working directory - merge() — Runs
git merge --no-ffto integrate the branch into the main root - cleanup() — Removes the worktree and deletes the branch
Requirements:
- Git 2.17+ (for
git worktree remove) - Repository must have at least one commit
Worktree location: <parent>/.rigger-worktrees/<branch_name>
Priority coupling: Tasks are merged sequentially in batch order. Earlier tasks always succeed; later tasks may encounter merge conflicts.
IndependentDirManager
Copies the entire project directory to a temp location. Works with any project, git or not.
How it works:
- create() — Runs
shutil.copytree()to copy the project to a temp directory - merge() — Runs
shutil.copytree(dirs_exist_ok=True)to copy changes back - cleanup() — Removes the temp directory
When to use:
- Non-git projects
- CI environments without git
- When branch management overhead is unwanted
IndependentBranchManager
Creates isolated branches in the same repository without using git worktree. Useful when worktrees aren't available or when you want simpler branch-based isolation.
How it works:
- create() — Creates a new branch from HEAD and checks it out in a copied directory
- merge() — Merges the branch back into the original branch
- cleanup() — Removes the temporary directory and deletes the branch
When to use:
- Environments where
git worktreeis unavailable - Simpler branch management without worktree bookkeeping
Parallel Dispatch Integration
To use parallel dispatch, pass a WorkspaceManager to the Harness constructor and call dispatch_parallel():
from rigger import Harness, ClaudeCodeBackend, GitWorktreeManager
harness = Harness(
project_root=Path("my-project"),
backend=ClaudeCodeBackend(),
task_source=my_tasks,
workspace_manager=GitWorktreeManager(),
)
state = harness.load_state()
batch = harness.select_tasks(max_count=3)
provision_result = harness.provision()
results, halt_requested = await harness.dispatch_parallel(
batch=batch,
epoch_state=state,
provision_results=[provision_result],
)
What dispatch_parallel() does:
- Creates isolated workspaces (one per task)
- Copies provisioned content into each workspace
- Writes
.harness/files (task + state) per workspace - Dispatches all agents concurrently via
asyncio.gather(return_exceptions=True) - Verifies results per workspace
- Merges changes back sequentially
- Runs post-merge constraint checks
- Cleans up all workspaces
A failure in one agent does not cancel others — each agent runs independently.