summaryrefslogtreecommitdiff
path: root/docs/adr/006-containerized-execution.md
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-03-18 23:56:34 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-03-18 23:56:34 +0000
commit599a26d556df52b364b5b540762a521d22eb5b7b (patch)
tree740c141c52764604fc8d4c036733e5f47368b26a /docs/adr/006-containerized-execution.md
parent0db05b0fa6de318f164a1d73ddc55db9c59f1fc3 (diff)
parent7df4f06ae0e3ae80bd967bf53cbec36e58b4a3bd (diff)
Merge feat/container-execution into master
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'docs/adr/006-containerized-execution.md')
-rw-r--r--docs/adr/006-containerized-execution.md51
1 files changed, 51 insertions, 0 deletions
diff --git a/docs/adr/006-containerized-execution.md b/docs/adr/006-containerized-execution.md
new file mode 100644
index 0000000..cdd1cc2
--- /dev/null
+++ b/docs/adr/006-containerized-execution.md
@@ -0,0 +1,51 @@
+# ADR-006: Containerized Repository-Based Execution Model
+
+## Status
+Accepted (Supersedes ADR-005)
+
+## Context
+ADR-005 introduced a sandbox execution model based on local git clones and pushes back to a local project directory. While this provided isolation, it had several flaws identified during early adoption:
+1. **Host pollution**: Build dependencies (Node, Go, etc.) had to be installed on the host and were subject to permission issues (e.g., `/root/.nvm` access for `www-data`).
+2. **Fragile Pushes**: Pushing to a checked-out local branch is non-standard and requires risky git configs.
+3. **Resume Divergence**: Resumed tasks bypassed the sandbox, reintroducing corruption risks.
+4. **Scale**: Local directory-based "project selection" is a hack that doesn't scale to multiple repos or environments.
+
+## Decision
+We will move to a containerized execution model where projects are defined by canonical repository URLs and executed in isolated containers.
+
+### 1. Repository-Based Projects
+- The `Task` model now uses `RepositoryURL` as the source of truth for the codebase.
+- This replaces the fragile reliance on local `ProjectDir` paths.
+
+### 2. Containerized Sandboxes
+- Each task execution runs in a fresh container (Docker/Podman).
+- The runner clones the repository into a host-side temporary workspace and mounts it into the container.
+- The container provides a "bare system" with the full build stack (Node, Go, etc.) pre-installed, isolating the host from build dependencies.
+
+### 3. Unified Workspace Management (including RESUME)
+- Unlike ADR-005, the containerized model is designed to handle **Resume** by re-attaching to or re-mounting the same host-side workspace.
+- This ensures that resumed tasks **do not** bypass the sandbox and never land directly in a production directory.
+
+### 4. Push to Actual Remotes
+- Agents commit changes within the sandbox.
+- The runner pushes these commits directly to the `RepositoryURL` (actual remote).
+- If the remote is missing or the push fails, the task is marked `FAILED` and the host-side workspace is preserved for inspection.
+
+## Rationale
+- **Isolation**: Containers prevent host pollution and ensure a consistent build environment.
+- **Safety**: Repository URLs provide a standard way to manage codebases across environments.
+- **Consistency**: Unified workspace management for initial runs and resumes eliminates the behavioral divergence found in ADR-005.
+
+## Consequences
+- Requires a container runtime (Docker) on the host.
+- Requires pre-built agent images (e.g., `claudomator-agent:latest`).
+- **Disk Space Risk**: Host-side clones still consume `/tmp` space. Mitigation requires periodic cleanup of old workspaces or disk-space monitoring.
+- **Git Config**: Repositories no longer require `receive.denyCurrentBranch = updateInstead` because we push to the remote, not a local worktree.
+
+## Relevant Code Locations
+| Concern | File |
+|---|---|
+| Container Lifecycle | `internal/executor/container.go` |
+| Runner Registration | `internal/cli/serve.go` |
+| Task Model | `internal/task/task.go` |
+| API Integration | `internal/api/server.go` |