Configuration Reference
File location
Section titled “File location”pixi-sandbox.toml at the repository root is preferred. pixi-sandbox init falls back to an
existing .pixi-sandbox.toml for compatibility, and --config PATH selects any other location.
Validate the selected file with pixi-sandbox plan --config pixi-sandbox.toml.
Schema
Section titled “Schema”schema = 1branch_prefix = "sandbox" # optional, default "sandbox"cargo_vendor = true # optional, default true, top-level default for bundles
# Optional runner overrides — required for platforms without hosted default (e.g., linux-aarch64)[runners]linux-aarch64 = "self-hosted-arm64"osx-arm64 = "macos-14" # example: override default macos-14# win-64 = "windows-latest"
[[bundle]]name = "developer" # used in branch name: <prefix>/<name>-<platform>environments = ["dev", "docs"]platforms = ["linux-64", "osx-arm64", "win-64"]cargo_vendor = true # optional per-bundle override
[[bundle]]name = "minimal"environments = ["default"]platforms = ["linux-64"]cargo_vendor = falseTop-level fields
Section titled “Top-level fields”| Field | Type | Default | Description |
|---|---|---|---|
schema |
int | required 1 |
Config schema version. Readers refuse newer. |
branch_prefix |
string | "sandbox" |
Prefix for orphan branches: <prefix>/<bundle>-<platform> |
cargo_vendor |
bool | true |
Default for bundles if not set per-bundle |
runners |
table | {} |
Map platform → runner label override |
Runners
Section titled “Runners”| Platform | Default runner | Notes |
|---|---|---|
linux-64 |
ubuntu-latest |
Hosted |
linux-aarch64 |
none — must provide [runners] |
No safe hosted default, require self-hosted |
osx-64 |
macos-15-intel |
Hosted Intel |
osx-arm64 |
macos-14 |
Hosted Apple Silicon |
win-64 |
windows-latest |
Hosted |
Rules enforced by plan:
- Runner label cannot contain control chars or outer whitespace
- Every
[runners]entry must be used by at least one bundle (stale typo = error) - Platform must have embedded pins for
pixi,pixi-pack,pixi-unpack(compiled into binary fromtools.lock.json)
Bundle
Section titled “Bundle”| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Bundle name, used in branch: sandbox/<name>-<platform> |
environments |
string[] | yes | Explicit pixi envs — never inferred from pixi.toml |
platforms |
string[] | yes | Platforms to publish (e.g., linux-64, osx-arm64) |
cargo_vendor |
bool | no | Override top-level cargo_vendor |
Emitted branches for example:
sandbox/developer-linux-64sandbox/developer-osx-arm64sandbox/developer-win-64sandbox/minimal-linux-64[workflow] — generated-publisher CI policy
Section titled “[workflow] — generated-publisher CI policy”Optional, within schema 1. Every real repository wants to change a handful of the generated
publish-sandbox.yml’s defaults (the push trigger, token permissions, concurrency, job
timeouts, the pixi pin and its cache). Before this table existed, those were hand edits a
consumer re-applied by ritual every time init --force regenerated the file, with nothing
confirming the re-applied edit still matched what the current generator would have produced.
Carrying the same policy in config instead means init reproduces the consumer’s exact
workflow with no hand edits at all — run init again any time, including from the
scheduled upgrade job (see Staying current),
and the output never drifts from what the table describes.
No [workflow] table at all renders byte-identically to the historical, pre-policy template —
existing projects need no changes. Once the table is present at all, even empty, two fields
move to a safer default unless given an explicit value (decision D18 in
.knowledge/decisions.md): setup_pixi_cache defaults to false, and push_paths defaults to
a derivation instead of the unfiltered trigger. The other fields stay fully opt-in per key.
[workflow]push_paths = ["pixi-sandbox.toml", "pixi.toml", "pixi.lock"] # optional, see belowpermissions = true # optional, default falsepixi_version = "0.81.0" # optional, default unset (setup-pixi resolves its own default)setup_pixi_cache = true # optional, default false once [workflow] is present at all
[workflow.concurrency] # optionalgroup = "publish-sandbox"cancel_in_progress = false # optional, default false
[workflow.timeouts] # optionalplan = 15publish = 60| Field | Type | Default | Description |
|---|---|---|---|
push_paths |
string[] | derived (see below) once [workflow] is present; otherwise no filter |
on.push.paths: allowlist. A plain entry is a path; a !-prefixed entry is GitHub’s negation syntax. No .. component or leading /. |
permissions |
bool | false |
When true, the workflow-level permissions: becomes contents: read and only the publish job regains contents: write, scoped to the job that needs it. false keeps the historical unconditional top-level contents: write. |
concurrency.group |
string | unset | concurrency: { group: ... } for the whole workflow — prevents two publishes racing to force-push the same orphan branch. |
concurrency.cancel_in_progress |
bool | false |
Paired with concurrency.group. |
timeouts.plan |
int (minutes) | unset | timeout-minutes: on the plan job. |
timeouts.publish |
int (minutes) | unset | timeout-minutes: on the publish job — a hung pack should not hold a runner for the six-hour default. |
pixi_version |
string | unset | Pins setup-pixi’s own pixi-version: input on every setup-pixi step. |
setup_pixi_cache |
bool | false once [workflow] is present, otherwise unset (no cache: key at all) |
setup-pixi’s cache: input. pixi-sandbox owns the native pixi install while packing; a cache keyed on the consumer manifest can restore a solve the pack will not reuse — a correctness hazard, not mere staleness (decision D18). Set true explicitly to keep the old best-effort caching. |
push_paths derivation
Section titled “push_paths derivation”Unset, once [workflow] is present, init derives the allowlist from the transport inputs
plan already depends on: the sandbox config itself, pixi.toml, pixi.lock (always), plus
whichever of package.json, bun.lock, Cargo.toml, Cargo.lock actually exist in the
project. pixi-sandbox plan --config pixi-sandbox.toml --json surfaces the same derivation
under its push_paths key, so a consumer can diff what the next init would write before
running it. An explicit push_paths always overrides the derivation.
Validation
Section titled “Validation”pixi-sandbox plan --config .pixi-sandbox.tomlpixi-sandbox plan --config .pixi-sandbox.toml --json # GitHub Actions matrix
# Lint in CI (keeps release matrix valid against embedded catalogue)pixi run sandbox-plan --jsonErrors:
- Unknown platform
- Empty environments
- Runner override unused
- Platform without embedded tool pins
- Invalid runner label
Examples
Section titled “Examples”Minimal (conda only, no cargo)
Section titled “Minimal (conda only, no cargo)”schema = 1cargo_vendor = false
[[bundle]]name = "python"environments = ["dev", "test"]platforms = ["linux-64", "win-64"]Full (multi-env, multi-platform, cargo)
Section titled “Full (multi-env, multi-platform, cargo)”schema = 1branch_prefix = "sandbox"cargo_vendor = true
[runners]linux-aarch64 = "self-hosted-arm64"
[[bundle]]name = "developer"environments = ["dev", "docs"]platforms = ["linux-64", "linux-aarch64", "osx-arm64", "win-64"]
[[bundle]]name = "ci"environments = ["default"]platforms = ["linux-64"]cargo_vendor = falseSelf-hosted override
Section titled “Self-hosted override”schema = 1
[runners]linux-64 = "my-large-runner"osx-arm64 = "self-hosted-mac"
[[bundle]]name = "prod"environments = ["prod"]platforms = ["linux-64", "osx-arm64"]Related
Section titled “Related”The project Pixi manifest is not modified
Section titled “The project Pixi manifest is not modified”pixi-sandbox init does not parse or edit pixi.toml; it only requires the manifest to exist —
run init from a Pixi project. The CLI is installed globally with explicit channels
(https://prefix.dev/archont561/archont561, the namespace’s ecosystem channel), and a project’s
channel list never needs to know where the CLI came from. A 0.4.3-era
https://prefix.dev/archont561 entry in your channels serves no repodata — remove it; nothing
needs to replace it.