Status: Implemented (2026-02-24)
Split the sandbox environment so the Clojure REPL runs separately from Claude Code. This allows daemonizing the infrastructure while running Claude interactively.
Single claude container runs both nREPL (background process) and Claude CLI (foreground). The entrypoint starts nREPL, waits for it, then execs into claude. Cannot daemonize without also daemonizing claude.
┌─────────────────────────────────────────────────────────────┐
│ orcha-sandbox-<feature> │
│ │
│ ┌──────────┐ ┌────────────┐ ┌──────────────────────────┐ │
│ │ postgres │ │ localstack │ │ repl │ │
│ │ :5432 │ │ :4566 │ │ JDK + Clojure + nREPL │ │
│ └──────────┘ └────────────┘ │ :7888 │ │
│ └──────────────────────────┘ │
│ ▲ │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ claude (ephemeral, docker-compose run) ││
│ │ Node + claude CLI + clj-nrepl-eval ││
│ │ connects to repl:7888 ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
Dockerfile.repl — JDK, Clojure, Babashka. Runs nREPL as main process (not backgrounded). Entrypoint initializes AWS resources then starts nREPL in foreground.
Dockerfile.claude — Node, Claude CLI, clj-nrepl-eval (MCP tool for REPL access). Minimal image, no JDK needed.
postgres — unchangedlocalstack — unchangedrepl — new service, depends on postgres/localstack health, exposes nREPL port to hostclaude — ephemeral (run via docker-compose run), no health dependencies, just needs network access| Command | Behavior |
|---|---|
sandbox:start <branch> |
Setup worktree, docker-compose up (foreground) |
sandbox:start <branch> -d |
Setup worktree, docker-compose up -d (daemon) |
sandbox:claude <branch> |
Setup worktree, docker-compose run --rm claude |
sandbox:stop <branch> |
docker-compose down |
sandbox:logs <branch> [service] |
docker-compose logs -f [service] |
Worktree setup (branch detection, confirmation, creation) is shared between start and claude.
Docker-compose creates network orcha-sandbox-<feature>_default. All services including ephemeral claude containers attach to it.
repl:7888postgres:5432 and localstack:4566${NREPL_HOST_PORT}:7888) on repl servicerepl service:
/workspace.m2 cacheclaude service:
/workspace~/.claude.json, ~/.claude/ (Claude config).claude-sandbox/projects (isolated conversation history)sandbox:expose/unexpose/exposed — reference repl container instead of claude container for port forwarding