Documentation/docs/volume/sync

#Volume Sync

Volume Sync keeps one Volume usable from your local workspace and from sandboxes at the same time.

Use it when you want to:

  • keep the same workspace in sync across macOS, Linux, and Windows
  • switch between local development and sandbox execution without copying files around
  • let AI agents work inside a sandbox while you continue editing locally

In practice, the same Volume can back:

  • a local workspace managed by s0 sync
  • one or more running sandboxes that mount that Volume
  • different machines and filesystems over time

For most users, s0 sync is the only interface you need. The HTTP endpoints at the end of this page are for advanced integrations and custom clients.

What Volume Sync Solves#

Without Volume Sync, moving a workspace between devices or between local and remote environments usually means pushing to Git, copying files manually, or rebuilding the same state in multiple places.

With Volume Sync, Sandbox0 gives you one shared workspace state:

  • your laptop can edit the files locally
  • a sandbox can mount the same files at /workspace
  • an AI agent running in that sandbox can read and modify the same project
  • when you switch to another machine, you can attach the same Volume again and continue working

Quickstart#

The normal workflow is:

  1. create or choose a Volume
  2. attach a local directory to that Volume
  3. mount the same Volume into a sandbox
  4. work locally, in the sandbox, or both

Attach a Local Workspace#

If you already have a local project and want to start syncing it to a Volume:

bash
s0 sync attach vol_abc123xyz ~/work/my-project

If you are on a new machine and want to pull the existing Volume contents into a local directory first:

bash
mkdir -p ~/work/my-project s0 sync attach vol_abc123xyz ~/work/my-project --init-from volume

s0 sync attach starts a background sync worker by default. If you want to keep it attached to the terminal and watch the sync logs directly:

bash
s0 sync attach vol_abc123xyz ~/work/my-project --foreground

--init-from volume is the safest choice when you are attaching a fresh directory on another machine and want the remote workspace state first.

Mount the Same Volume into a Sandbox#

Once the Volume is attached locally, mount the same Volume into a sandbox:

bash
s0 sandbox volume mount --volume-id vol_abc123xyz --path /workspace -s sb_abc123xyz

Now the same workspace is available in two places:

  • locally at ~/work/my-project
  • inside the sandbox at /workspace

This is the key workflow for remote execution and agent collaboration. You can edit locally, while the sandbox runs builds, tests, long-running jobs, or AI agent tasks against the same project tree.

Work Across Devices and Platforms#

Volume Sync is designed for moving the same workspace across machines and operating systems.

Typical examples:

  • start work on macOS, then continue on a Linux workstation
  • attach the same Volume on a Windows machine for review or edits
  • keep a sandbox mounted so remote jobs and agents always see the current workspace state

The practical flow is simple:

  1. on machine A, attach the workspace and work normally
  2. on machine B, attach the same Volume with --init-from volume
  3. mount that Volume into a sandbox whenever you need remote execution or agent help

Work with Sandboxes and AI Agents#

Volume Sync is especially useful when you want sandbox execution without losing your local development loop.

A common pattern is:

  1. attach your repo locally
  2. mount the same Volume into a sandbox at /workspace
  3. run an AI agent or command inside the sandbox against /workspace
  4. review the resulting file changes locally

That gives you a smooth loop:

  • local edits upload to the shared Volume
  • sandbox writes replay back into the local workspace
  • agents can modify the same files you are working on

You do not need to manually export, download, or re-copy the workspace between environments.

Daily Commands#

After a workspace has been attached, s0 sync can usually infer the workspace root from your current directory.

Useful commands:

bash
# Show current sync status s0 sync status # Read sync worker logs s0 sync logs -f # List all local sync attachments on this machine s0 sync list # List unresolved conflicts s0 sync conflicts list # Stop syncing this local workspace s0 sync detach

Cross-Platform Rules to Keep in Mind#

Volume Sync helps you move between filesystems safely, but some path patterns are not portable.

Avoid:

  • two paths that differ only by case, such as Foo and foo
  • Unicode-equivalent names that look the same on some systems
  • Windows-incompatible names such as reserved device names or paths ending in dots or spaces

When Sandbox0 detects a namespace that is unsafe for one of your attached platforms, it reports a sync conflict instead of silently creating a broken checkout on another machine.

Supported Workspace Types#

Today, s0 sync supports only regular files and directories.

That means the synced workspace should not rely on:

  • symlinks
  • named pipes
  • sockets
  • device nodes
  • hard links coming from bootstrap archives

If the local workspace, a bootstrap archive, or a remote replay contains one of those entry types, s0 sync reports an explicit unsupported-type error instead of silently producing a partial checkout.

Conflicts and Recovery#

Most of the time, Volume Sync should feel automatic. When there is a problem, the operator flow is:

bash
s0 sync status s0 sync conflicts list s0 sync conflicts show <path>

After you repair the workspace locally, mark the conflict:

bash
s0 sync conflicts mark <path>

If you want to leave a conflict recorded but stop blocking on it, you can mark it as ignored:

bash
s0 sync conflicts mark <path> --ignore

A few practical notes:

  • while unresolved sync conflicts remain open, local uploads pause until you resolve or ignore them
  • s0 sync logs -f is the fastest way to see why a worker is blocked
  • if a local machine falls too far behind retained sync history, the worker can bootstrap from the Volume again automatically

Advanced: How It Works#

This section is for custom clients and operators who need to understand the underlying sync contract.

Volume Sync is built around four backend responsibilities:

  • register a replica and its filesystem capabilities
  • bootstrap a local workspace from the current Volume state
  • replay remote changes and upload local changes
  • persist conflicts and durable progress

Replica Registration#

Register or refresh a local replica identity for a Volume.

PUT

/api/v1/sandboxvolumes/{id}/sync/replicas/{replica_id}

Custom clients should register filesystem capabilities so Sandbox0 can reject path mutations that are not portable to that replica.

Bootstrap#

Create a bootstrap snapshot and replay anchor:

POST

/api/v1/sandboxvolumes/{id}/sync/bootstrap

Download the bootstrap archive:

GET

/api/v1/sandboxvolumes/{id}/sync/bootstrap/archive?snapshot_id=snap_123

This is the mechanism behind s0 sync attach --init-from volume.

Replay and Upload#

List journal entries after a known sequence:

GET

/api/v1/sandboxvolumes/{id}/sync/changes?after=42&limit=256

For regular-file writes that include content_ref, download the replay payload bytes separately:

GET

/api/v1/sandboxvolumes/{id}/sync/replay-payload?content_ref=sha256:...

Submit local replica changes:

POST

/api/v1/sandboxvolumes/{id}/sync/replicas/{replica_id}/changes

Persist the highest applied cursor:

PUT

/api/v1/sandboxvolumes/{id}/sync/replicas/{replica_id}/cursor

In steady-state replay:

  • sync/changes provides journal metadata such as event_type, entry_kind, mode, and content_ref
  • sync/replay-payload provides the immutable bytes for a regular-file write when content_ref is present
  • replicas persist their applied cursor separately through the replica cursor endpoint

The server retains sync history for a bounded window. If a replica falls behind that retained journal floor, it must bootstrap again from the current Volume state.

Conflict State#

List open conflicts:

GET

/api/v1/sandboxvolumes/{id}/sync/conflicts?status=open

Mark a conflict as resolved or ignored:

PUT

/api/v1/sandboxvolumes/{id}/sync/conflicts/{conflict_id}

Conflict records are durable, so custom tooling can inspect and resolve them consistently across local clients and sandboxes.


Next Steps#

Workspace Sync for AI Agents

See the local-to-cloud workflow for macOS, Linux, Windows, and sandboxes

Sandbox Files

Read and write synced workspace files inside sandboxes

Ports Exposure

Expose services running from your synced workspace

Sandbox Webhooks

Automate workflows with sandbox lifecycle events