Sandbox
Coderrr has no tool that runs commands against your working tree. Commands run in a sandbox, and the agent reads the real exit code and output.
Why the agent needs to run anything
An agent that writes code but cannot run it is guessing. The point of run_in_sandbox is that the agent gets the actual exit code, the actual stderr, and the actual traceback — so it can fix its own mistakes before marking a task done, instead of declaring success on unexecuted code.
The tradeoff is obvious: running model-authored commands is exactly the thing you do not want happening in your checkout. Hence two tiers, and hence the CLI always telling you which one is active.
The two tiers
| Tier | What it is | Isolation |
|---|---|---|
| scratch | A throwaway copy of the project plus a subprocess | Filesystem: your working tree is untouched. Network: none — the command has your network access. |
| docker | A container, used automatically when Docker is available | Filesystem and network both isolated |
scratch limits blast radius; it is not a security boundary
The scratch tier means a bad build cannot wreck your checkout. It does not contain deliberately hostile code — there is no namespace or network isolation, and the command runs as you. Install Docker if that distinction matters for what you are running.
Coderrr surfaces this rather than hiding behind the word "sandbox": coderrr doctor and the planning header both name the active tier and its limits.
Which tier am I on?
coderrr doctor Check Value
coderrr 2.0.0
python 3.12.3
sandbox docker (docker available)
specs 3
◇ Scratch sandbox limits blast radius but does not contain hostile
code. Install Docker for full isolation.Every run prints it too, at the top of the planning phase:
─────────────── Planning ───────────────
◇ sandbox: docker — container; filesystem and network isolatedThe scratch tier
A copy of your project is made into a temporary directory created mode 0700, and commands run there. The copy is made lazily on the first command and discarded when the run ends.
These are excluded from the copy — large, and reproducible from your manifests:
.git .hg .svn .coderrr
node_modules .venv venv env
__pycache__ *.pyc .mypy_cache .pytest_cache .ruff_cache
target dist build .nextWhich means the agent may have to install dependencies before it can run anything. That is expected, and it is the price of not copying a node_modules on every run.
On POSIX systems the child process also gets:
- Its own process group, so a timeout kills the whole tree rather than just the shell
- A 2 GB address-space limit
CODERRR_SANDBOX=scratchin its environment, so scripts can detect it
The Docker tier
Used automatically when Docker is available and [sandbox].tier is auto. Coderrr shells out to the docker CLI rather than taking an SDK dependency.
| Flag | Effect |
|---|---|
| --network=none | No network at all, unless [sandbox].network = true |
| --cap-drop=ALL | Every Linux capability dropped |
| --memory=2048m | Memory ceiling |
| --pids-limit=512 | Fork-bomb ceiling, scoped to the container |
The image is python:3.12-slim by default. Point [sandbox].image at something else if your project needs a different toolchain:
[sandbox]
tier = "docker" # fail rather than silently fall back to scratch
image = "node:22-slim"
network = false
timeout = 600Timeouts
Commands are killed after [sandbox].timeout seconds (300 by default), and the whole process tree goes with them — a timeout on Windows cleans up the subprocess tree too. The agent sees status: TIMED OUT and whatever output was produced before the kill, so it can react rather than hang.
Separately, [agent].max_seconds caps one whole task attempt at 30 minutes.
Workspace containment
Independent of the sandbox, every path the agent touches is resolved and checked against the workspace root. Symlinks are resolved before the check, so a link pointing outside the project does not become an escape hatch. The root is the directory you ran Coderrr in, or whatever you passed to --dir.
See Configuration for every sandbox key.