Guide
How do I try three approaches from the same starting point?
Set up one machine, freeze it, and copy it once per approach. With Sanbox, you get a Computer to the starting point you want, stop it, and run sanbox runs fork three times; each fork is an independent Computer with the same /workspace, installed packages and agent history, while the original stays untouched. Without forks, the general way is to clone a VM image by hand or to juggle three git branches on one machine.
Run this with your agent
Read https://sanbox.cloud/kb/parallel-work/fork-a-computer-to-try-several-approaches.md and follow it to fork my Computer three ways.
If the Sanbox CLI is missing, install it with `npm install -g @sanlabs/sanbox-cli@latest`
and sign in with `sanbox login`. Show me each command before you create, stop or delete a Computer.
What does a fork keep?
A fork copies the stopped Computer's saved disk into a new run with its own identity. It boots fresh.
| Kept in the fork | Not kept |
|---|---|
/workspace and everything in it | RAM |
| Installed packages and other writable system changes | Running processes, such as dev servers |
| Agent configuration and history | Open sockets and connections |
| The pinned base image | The original task (it isn't run again) |
| Model selection, resource limits, network rules and recorded environment settings | Old SSH sessions, filesystem shares and OpenCode connection tokens |
A few details matter when you compare forks:
- Files are copied as they are, including any credentials someone wrote into them.
- Template edits don't reach forks. A fork inherits the source's saved settings, not the template's current ones.
- Secret Proxy grants carry over only for proxies the source had that are still granted to the template when the fork boots. Sanbox issues fresh runtime credentials and access tokens.
Which Computers can I fork?
You can fork a stopped, writable OpenCode Computer, Docker Computer or Hermes Computer. A Docker Computer's fork keeps its images, build cache and volumes, because they live on its disk. You can't fork:
- an OpenCode task run, which returns
fork_harness_unsupported - a run with an email, Telegram or delegated Supabase binding
- a legacy run without a writable system disk, which returns
fork_requires_writable_system
Fork needs CLI 0.0.17 or later.
Steps
1. Prepare the starting point
Start a Computer and get it to the state all three attempts should share: the repository, its dependencies, test data. For example, copy a project in and install its packages:
sanbox cp ./app <run-id>:/workspace
sanbox exec <run-id> --cwd /workspace/app -- npm ci
npm ci needs registry.npmjs.org in the template's network policy. You can also work in the console terminal or over sanbox ssh <run-id>.
2. Stop it
sanbox runs stop <run-id> --wait --json
Stop saves the disk. Check that sanbox runs get <run-id> --json shows state as stopped.
3. Create three forks
Generate one UUID per fork (for example with uuidgen) and save them before you submit. Reusing a key with the same source after a lost response returns the same child instead of a fourth copy.
sanbox runs fork <stopped-run-id> --request-key <uuid-a> --wait --json
sanbox runs fork <stopped-run-id> --request-key <uuid-b> --wait --json
sanbox runs fork <stopped-run-id> --request-key <uuid-c> --wait --json
Each command returns a child run ID. A fork starts automatically when your organisation has a free run slot, and --wait waits until the child is running, including any wait for a slot. A timeout doesn't cancel the fork. The source stays stopped.
4. Give each fork its approach
Open each child in the console and give it its own instruction, for example "fix the race with a lock", "fix it with a queue" and "remove the shared state". To drive the forks from code, create an OpenCode SDK connection for each running child:
sanbox opencode connect <child-run-id> --expires 1h --json
A Docker Computer has no agent or chat, so run each approach in its fork with sanbox exec instead. Restart anything that was running before the stop, such as a dev server, because processes don't carry over.
5. Compare the results
If the project is a git checkout, compare what each fork changed:
sanbox exec <child-run-id> --cwd /workspace/app -- git diff --stat
Copy the results you want to keep to your machine. sanbox cp puts the copy inside the destination under its own name, so this creates ./fork-a/app:
mkdir -p fork-a
sanbox cp <child-run-id>:/workspace/app ./fork-a
6. Keep the winner, delete the rest
sanbox runs delete <child-run-id> --yes --json
Delete is permanent. Once a fork has finished copying, deleting it doesn't affect the source or the other forks.
What if a fork fails?
sanbox runs get <child-run-id> --json shows fork_status, fork_error and forked_from_run_id. Then:
# fork_status=failed: retry copying into the same child.
sanbox runs fork-retry <child-run-id> --wait --json
# fork_status=ready but startup failed: start the existing copy.
sanbox runs resume <child-run-id> --wait --json
While a fork is copying, the source can't be resumed, deleted or forked again. Sanbox may copy and verify the disk first, so the child's first boot can take longer.
Snapshot it
If you'll start from the same point many times, take a snapshot instead of forking every time. An organisation admin or owner captures it from the stopped Computer:
sanbox snapshots create --run <stopped-run-id> --name <name>
sanbox run --snapshot <name> --json
A warm pool can keep ready copies of the snapshot waiting. See how to make agent computers start instantly.
What this doesn't do
- No live state. Forks don't keep RAM or processes. Each one boots fresh from the saved disk.
- No merging. Sanbox doesn't combine the forks' changes. Pick one, or merge them yourself with git.
- No overrides. You can't change the model, resources or network rules when you fork.
- Each fork is a separate Computer with its own disk, and it starts only when your organisation has a free run slot.