
In a previous article we explored how to integrate Docker Sandbox, OpenCode and Venice to create a safe crypto aligned coding stack so for this article I’m going to assume that you already know how to install and manage Docker sandboxes and how to connect OpenCode to Venice.
The goal of this tutorial is to show the two modes that a Docker sandbox can operate (direct and clone) and then build upon that knowledge to create a multi agent setup that allows you to develop features in parallel and speed up development.
Project Setup
We will be working on a simple project called myapp so make sure to create a folder for it.
$ mkdir myapp
$ cd myappAdd a simple index.html to the project to have a starting code to showcase different workflows.
$ echo '<h1>My App</h1>' > index.htmlCreate a configuration file for OpenCode to automatically connect the coding agent to Venice using the API key created as a sandbox secret. If you don’t know what any of that mean please read the previous article where we go through this setup step by step.
opencode.json
{
"$schema": "https://opencode.ai/config.json",
"model": "venice/zai-org-glm-5-2",
"provider": {
"venice": {
"options": {
"apiKey": "{env:VENICE_API_KEY}"
}
}
}
}Direct Mode
The simplest way to use Docker sandbox is to use it in “direct” mode. In direct mode any changes made to the project from inside the sandbox automatically propagates to the code on the host.
To prove it, create a sandbox called sbx1. No special flags are needed because direct mode is the default mode of a newly created sandbox.
$ sbx run opencode --name sbx1This command will create the sandbox and launch OpenCode inside of it.
Note: From this point on I’ll prefix each command with
[host]if its supposed to be executed on the host OS or[<sandbox>|<mode>]if it’s supposed to be executed inside a sandbox in a particular agent mode (plan, build or shell). I’ll also specify the active git branch with(<branch>).For example, the prefix
[sbx2|shell](main)means that I’m inside thesbx2sandbox using OpenCode’sshellmode on git’smainbranch.
Instruct the coding agent to make a small change to index.html.
[sbx1|build] $ Add a paragraph to @index.html that says "hello world"Once the coding agent is done, check on the host the content of index.html.
[host] $ cat index.html
>>>
<h1>My App</h1>
<p>hello world</p>The code was updated because in direct mode a sandbox mounts the working directory in write mode which is the simplest setup to get started.
Clone Mode
When you launch a sandbox in “clone” mode the project directory is copied to the sandbox using git clone. For this reason, clone mode requires your project to be tracked with git in the first place so let’s start there.
[host] $ git init
host $ git add -A
host $ git commit -m "Initial commit"Now that out project is tracked with git we can create a sandbox that we’re going to call sbx2 in clone mode using the --clone flag.
[host] $ sbx run opencode --name sbx2 --cloneOnce OpenCode launches you can check that inside the sandbox there’s a remote called origin that was automatically created by Docker and points to the VM’s filesystem.
[sbx2|shell] $ git remote -v
>>>
origin /run/sandbox/source (fetch)
origin /run/sandbox/source (push)Let’s ask the agent to make a change to index.html.
[sbx2|build] $ Add a paragraph to @index.html that says "bye world".Once the agent finishes adding the new paragraph inside the sandbox go back to your host and check the content of index.html.
[host] $ cat index.html
>>>
<h1>My App</h1>
<p>hello world</p>The change didn’t propagate to the host as in direct mode. Furthermore, if you check the remotes of your project on the host you’ll notice a different one called sandbox-sbx2.
[host] $ git remote -v
>>>
sandbox-sbx2 git://127.0.0.1:49154/myapp (fetch)
sandbox-sbx2 git://127.0.0.1:49154/myapp (push)Docker creates a different remote on both ends to allow the coding agent to work in a completely isolated environment from the host but still allowing for coding synchronization using git pull or git fetch on either end. git push on the other hand is not allowed on these auto generated remotes to prevent a rogue agent from pushing malicious code to the host.
To see this in action let’s go back to the sandbox and ask the agent to commit the changes.
[sbx2|build] $ Commit the changes to a branch called "feat1".Get the latest version of all the branches of the sandbox-sbx2 remote in the host.
[host] $ git fetch sandbox-sbx2
>>>
...
* [new branch] feat1 -> sandbox-sbx2/feat1To see the changes the agent made in the sandbox from the host you can use git diff.
[host] $ git diff main..sandbox-sbx2/feat1
>>>
...
<h1>My App</h1>
<p>hello world</p>
+<p>bye world</p>To bring the changes in you can merge the remote branch into main.
[host] $ git merge sandbox-sbx2/feat1
>>>
...
1 file changed, 1 insertion(+)Multi Agent
Running a sandbox in clone mode it’s not very interesting on its own, if anything it adds more friction for coding. The real power comes when you want to manage multiple coding agents working in parallel without them stepping on each other’s toes.
Imagine we have three big features to implement and each one could take an agent 20 minutes to complete. Instead of developing the features in sequence using a single agent and consuming 60 minutes of our time, we could spin off three agents (three sandboxes) to work in parallel.
To do this we start by creating three sandboxes in clone mode, one for each feature.
[host] $ sbx create opencode --name feat1 --clone .
[host] $ sbx create opencode --name feat2 --clone .
[host] $ sbx create opencode --name feat3 --clone .And from this point on you’d repeat the steps described in the previous section by login into each sandbox with sbx run --name <sandbox>, ask the agent build the feature and commit the changes to a branch, and obtain the changes in the host with git fetch and git merge.
You have now 3 agents working in parallel able to modify the same files if needed as they all use copies of the codebase using git clone. To solve conflicts you can always fetch the latest version of main inside the sandbox and ask the agent to fix them for you.
Conclusion
A sandbox in direct mode gives you the easiest dev workflow but it exposes your project folder, including your git history, to a potential rogue agent. Clone modes gives you an additional layer of isolation between your host OS and the coding agent at the cost of the friction created by having to pull changes manually between both environments.
To have a multi agent workflow you could rely on git worktrees with one sandbox in direct mode for each folder / branch but this has the problem of hiding the git history from the coding agent along with the ability to create and switch branches for development. A better alternative is to use multiple sandboxes in clone mode so each coding agent can have access to the project’s git and the ability to manage branches with complete isolation from one another.
Cheat Sheet
// Create an OpenCode sandbox in clone mode
[host] $ sbx create opencode --name <sandbox> --clone .
// Attach the terminal to the sandbox to get into OpenCode
[host] $ sbx run --name <sandbox>
// Ask agent to develop feature
[sbx|build] $ Implement feature A and commit changes to git
// Pull changes from the sandbox
[host] $ git fetch <sandbox-remote>
// Inspect changes made by agent in branch
[host] $ git diff main..<sandbox-remote>/<branch>
// Merge back to main only if FF is possible
[host] $ git merge --ff-only <sandbox-remote>/<branch>
// If FF not possible resync, rebase and fix conflicts
[sbx|build] $ Fetch origin, rebase <branch> onto origin/main and fix conflicts