Last updated 2026-05-07

Sandboxed Execution

Each workflow run can execute in an isolated copy of your workspace. This stops concurrent runs from interfering with each other and protects your working directory from being modified by CI steps (linters that auto-fix, tests that overwrite generated files, etc.).

Strategies

StrategySpeedDiskMechanism
worktreeInstantMinimal (shared .git objects)git worktree add --detach
copy-on-writeNear-instant (macOS APFS only)Minimal until modifiedcp -c -R
copyProportional to repo sizeFull copyrsync -a with exclusions, fallback cp -R
noneN/AN/ARuns directly in workspace

Auto-detection (strategy: 'auto')

  1. If the workspace is a git repo, try worktree.
  2. On macOS, try copy-on-write via APFS cp -c.
  3. Fall back to regular copy via rsync, excluding .git, node_modules, .next, build, dist, .gradle, Pods, .dart_tool, .pub-cache.

Selecting a strategy

# Worktree
curl -X POST http://localhost:4800/api/runs \
-H 'Content-Type: application/json' \
-d '{"workflow": "ci", "sandbox": {"strategy": "worktree"}}'
# In-place (no isolation)
curl -X POST http://localhost:4800/api/runs \
-H 'Content-Type: application/json' \
-d '{"workflow": "ci", "sandbox": {"strategy": "none"}}'
# Worktree from a specific ref
curl -X POST http://localhost:4800/api/runs \
-H 'Content-Type: application/json' \
-d '{"workflow": "ci", "sandbox": {"strategy": "worktree", "ref": "feature-branch"}}'

From the CLI:

stax run ci # auto
stax run ci --no-sandbox # strategy: none

Sandbox location

Default: /tmp/runner-sandboxes/<run-id>/. Override with RUNNER_SANDBOX_DIR=/path/to/sandboxes.

Cleanup

  • Sandboxes are removed automatically when a run completes (success or failure).
  • On runner startup, sandboxes older than 1 hour are cleaned up.
  • Orphaned git worktrees are pruned automatically.

Tips

  • Worktree is the fastest and uses the least disk — but a dirty working tree elsewhere can cause it to fail. Run git worktree prune if you see "creating sandbox failed".
  • Copy-on-write only works on APFS (macOS); on Linux ZFS/Btrfs reflinks are not yet wired up.
  • Use strategy: 'none' when you want CI side-effects visible in your editor (rare, but useful when debugging a step that produces files you want to inspect).