Skip to main content

Run and synchronise workspaces

Workspace transfer and repository authority are separate:
  • Workspace source is the exact local checkout or linked worktree transferred into the sandbox.
  • Repository authority is the server-verified GitHub repository against which brokered provider credentials and repository-scoped policy may be used.
You can upload and test a workspace without GitHub authorisation. Pushing a branch, creating a pull request, or using repository-scoped capabilities requires a verified repository binding.

aient sandbox run

Create a sandbox, optionally transfer a workspace or upload, run one command, and delete the sandbox:
With --environment, --workspace defaults to the current directory. With --workspace, the remote directory defaults to /workspace/repo, and the command runs there unless --workdir overrides it. Use exact argv after --:
Use an explicit shell only when shell syntax is required:
Or read the shell body from standard input:

Workspace and authority flags

Repository candidates are inferred from sanitised origin and upstream remotes when possible. Embedded remote credentials are not transmitted or displayed. If exactly one authorised repository matches, Aient binds it automatically. If none match, ordinary offload may continue without GitHub access. Use --repository when candidates are ambiguous. Changing a local remote cannot grant repository access. Every provider operation is re-authorised against the authenticated organisation, active GitHub App installation, and current repository permissions.

Git SSH trust bootstrap

By default, sandbox run selects SSH hosts only from the chosen repository’s origin, upstream, and root .gitmodules. It copies matching public records already present in the host user’s standard known_hosts files and atomically merges them into the sandbox user’s ~/.ssh/known_hosts. Existing unrelated sandbox entries are preserved. This never copies private keys, SSH configuration, an SSH agent/socket, credentials, or the complete host trust file. When github.com is selected, the sandbox user’s Git configuration also rewrites the common GitHub SSH URL forms to HTTPS, where an authorised repository-capability-bearing command can use Aient’s request-local scoped credential. Other SSH hosts receive trust only; they still need their own sandbox-available authentication. If local trust is absent or the sandbox runtime cannot install it, Aient prints a warning and continues creating the sandbox. Use --ssh-known-hosts=none when repository policy requires the image-provided trust state to remain unchanged.

Selected nested repositories

The default workspace policy rejects initialized submodules instead of silently transferring or omitting their checked-out bytes. If the command does not consume child repository content, use the explicit Gitlink-only policy:
If the command consumes a nested repository, select only that dependency:
The same flags work with sandbox sync:
Selected mode publishes one atomic /workspace/repo containing the exact root Git state and only the explicitly selected child snapshots. Every unselected Gitlink remains an empty ordinary boundary, even when its local checkout is initialized or dirty; those bytes are not transferred, preserved, or treated as implicit input. Each selected child must be an ordinary initialized repository, clean and at the exact final parent-index Gitlink OID, with complete local history and no replacement refs. To select a nested descendant, repeat --submodule for the complete ancestor closure, using canonical paths from the top-level repository. Aient does not recursively discover descendants. The first selected protocol generation accepts at most 64 selected repositories and 512 Gitlink boundaries across the selected tree. --submodule without --submodules=selected, selected mode without a path, unsafe or duplicate paths, incomplete ancestry, and a custom remote root all fail before publication. Selected mode is fixed to /workspace/repo. A retained sandbox whose reader predates selected-submodule support returns workspace_layout_selected_submodules_unavailable; recreate or upgrade it rather than retrying with a broader transfer policy.

Command and lifecycle flags

--upload PATH uploads a non-Git file or directory instead of synchronising Git state. It excludes .git and node_modules by default. Do not combine --upload and --workspace. --env and --metadata are non-secret inputs. Metadata is ordinary control-plane state: never put tokens, credentials, or sensitive values in it. It cannot override server-owned organisation, actor, environment, or repository identity. Environment and GitHub credentials are injected only into an authorised sandbox process. Raw credentials are not returned as OAuth, profile, operation-result, metadata, or workspace-revision fields, and generic file APIs do not project mounted secrets. The CLI does not retain normal command output. An authorised child can nevertheless deliberately print or copy a mounted secret; stdout and stderr are returned verbatim to the connected caller, child-created files can contain those bytes, and either may be captured by its terminal or agent transcript. Avoid env, printenv, shell tracing, or echoing GH_TOKEN.
sandbox run is buffered. It is convenient for bounded commands, but it does not provide durable detach or output replay. For long commands whose live progress matters, retain a sandbox and use sandbox exec.

aient sandbox sync

Synchronise exact local Git state into an existing sandbox without an environment binding:
The default remote workspace is /workspace/repo. In 0.10.0, sync cannot carry the environment and repository selectors needed to reopen an environment-bound customer sandbox created by run --keep. Start a fresh run --keep to transfer changed customer workspace state.
The synchronised state includes the selected worktree’s exact HEAD, index, tracked changes, and selected explicit extra files. Include and exclude globs use repository-relative / separators and support *, **, and ?. Excludes filter only the explicit non-Git layer and cannot remove tracked Git state. With one or more --include patterns, they subtract from those selected paths. With no --include, exclude-only mode starts from the complete ignored and untracked inventory, then subtracts every matching path. This broad mode has no implicit cache or secret exclusions, so explicitly exclude .env files, credentials, private keys, dependency caches, and other unwanted local content. Raw --upload and files put --exclude have their own file-transfer filters. Git activation atomically replaces the destination directory. --remote-dir must therefore name a replaceable child on the workspace filesystem, such as /workspace/repo or /workspace/alternate-repo, never the mounted /workspace root itself. Raw upload may target /workspace because it does not use Git-directory activation.

Atomic activation and the workspace fence

Aient constructs and verifies a candidate before activating it as /workspace/repo. V3 is selected only from a closed, exactly attested capability, publishes one immutable full-snapshot or retained-delta candidate, and never falls back after selection. Activation replaces the live child on the same filesystem while holding the exclusive workspace fence; the /workspace mount point itself is not replaced. sandbox exec, sandbox shell, and workspace reads hold the shared fence. A sync waits before activation rather than replacing the live tree under an admitted command. Direct file operations currently fail with a busy response instead of waiting. Do not start a second workspace mutation while a sync is active. Wait for the real terminal prefix:
When an explicit non-Git layer is present, the CLI prints a second Synchronized N explicit path(s) ... line. Partial transfer progress is not completion. If another program invokes the CLI, it must preserve the child process’s complete lifecycle result—including a running session handle, final exit status, and terminal output. Completion of an outer wrapper is not evidence that the CLI child has exited. Workspace archive uploads treat --timeout as an inactivity budget. The budget resets while source bytes continue to flow and when the server begins its response, so a healthy large transfer may exceed five minutes in total. A stalled upload or response still fails with a deadline-classified error. For a slow connection, increase the allowed inactivity gap:
--verbose prints safe request correlation and detailed progress; it does not print credentials. An interrupted upload is not byte-resumable. Re-running sync starts a new delta or snapshot attempt against the last successfully activated remote revision.

Recover an interrupted workspace publication

When a workspace-backed sandbox run or sandbox sync loses its foreground connection after Aient has started publication, the CLI keeps one immutable local receipt. Do not start a second sync to guess whether the first one completed. Inspect the recorded operation first:
Resume the exact candidate, revision, and retained artifacts when the operation remains incomplete:
If you no longer want an uncommitted publication, discard it explicitly:
Discard does not remove an activated or activation-pending workspace. On a transport failure or an unsupported helper, the CLI preserves the local receipt so you can retry safely. It removes the receipt only after the server proves that the exact operation was discarded or was already absent.