Add a sandbox provider
Connect an execution environment that runs commands, transfers files and releases resources.
Write a minimal provider
Section titled “Write a minimal provider”Implement a SandboxProvider to open an execution environment. It returns a SandboxLease through which Outpost runs commands and transfers files. The example below outlines a virtual machine integration; vms represents that platform’s SDK.
Adapt these SDK contracts and command helpers to your VM platform.
Add transfers and idempotent release, then compose the provider in vm-provider.ts.
Pass vmSandboxProvider as sandboxProvider to dispatch() or createSandbox(). Outpost calls acquire() once per sandbox, runs the agent and your commands through invoke(), then calls release().
Implement the operations
Section titled “Implement the operations”API reference: SandboxLease, SandboxContext and FileTransfers.
invoke() also receives retain (bytes of output tail to keep), interactive and terminal streams for attach(), and input when the lease declares liveInput.
Choose repository access
Section titled “Choose repository access”Both helpers take name, optional variables and acquire, check the name and freeze the result. They differ in the placement they set, which decides who moves the repository.
createMountedSandboxProvider() | createRemoteSandboxProvider() | |
|---|---|---|
Your acquire() | Mounts context.directory at root and context.gitDirectories so git works | Starts an empty environment |
| Repository | The agent edits the host worktree directly | Outpost runs git init in root, uploads the history, then downloads and applies the new commits |
| Agent CLI | Comes from your image | Installed in home when missing, unless bootstrap: false |
| Branch | Any branch mode | named or integrate, integrate by default |
| Built-in examples | Docker and Podman (Docker and Podman) | Vercel, Daytona, Firecracker (Cloud sandboxes) |
Meet the obligations
Section titled “Meet the obligations”Outpost’s supervision, retries and recovery rely on these behaviours. Each one is observable by a user when it breaks.
- Exit status
invoke()resolves when the process exits, with its real status, even if stdout and stderr closed earlier. - Cancellation
signalanddeadlineMsstop the process group and its descendants; the sandbox stays usable. - Transfer limits
upload()anddownload()honoursignalanddeadlineMstoo. - Exact bytesTransfers copy binary data without text decoding and keep supported modes and symlinks.
- Safe stagingReject destinations that escape their target; remove temporary staging on success, failure and cancellation.
- Idempotent releaseA second
release()resolves without error.
Declare optional capabilities
Section titled “Declare optional capabilities”Outpost uses a capability only when the provider or lease declares it; it never infers one from the provider’s name.
API reference: SandboxLease.
Without liveInput, steering a resumable CLI agent stops its process once the conversation is known and resumes it in the same sandbox.
Prepare recovery after a crash
Section titled “Prepare recovery after a crash”A durable race registers each sandbox before it exists, so a restarted coordinator can remove it. In acquire(), await context.registerRecovery(resourceId) exactly once, before allocating. recover(resourceId, { signal, deadlineMs }) then removes that resource.
registerRecovery exists only during a durable race. If it rejects, do not allocate. recover() must succeed when called again and delete only the sandbox, never repository data on the host.
Test against the real environment
Section titled “Test against the real environment”diagnoseSandbox() probes a lease: Node.js, Git, separate output streams, a nonzero exit status, the home directory and, with transfers, a binary upload verified by a process in the sandbox.
The diagnosis leaves the lease to you: release it yourself. Then run a real dispatch() on a named branch; Diagnostics reads the report.
Limits
Section titled “Limits”- No
recoverin the helpers:createMountedSandboxProvider()andcreateRemoteSandboxProvider()acceptname,variablesandacquire; addrecoverby spreading the result, as above. - Remote needs Git: A remote sandbox needs
giton itsPATHand a writableroot. - Partial transfer probe:
transfers: truechecks one binary file. Symlinks, modes, directories and batch transfers stay unverified.
API: SandboxProvider · SandboxLease · SandboxContext · FileTransfers · createMountedSandboxProvider · createRemoteSandboxProvider · diagnoseSandbox.