This is the multi-page printable view of this section. Click here to print.
Migrations
1 -
Moving from v0 containers to v1 deployments
v1 deployment orchestration is opt-in. A v0 project remains a v0 container project until its aibox.toml explicitly enables [orchestration]; aibox apply, up, and down from the v0 lifecycle do not discover, modify, or remove a v1 deployment receipt.
Prepare the configuration
Preview first. This reads only aibox.toml, reports digests rather than printing configuration contents, and does not contact a container runtime or a cluster:
aibox config migrate-v1 --output json
The preview maps the safe, deterministic part of the old configuration:
container.name becomes the proposed fleet, first service, and deployment
name. It then returns an unresolvedDecisions array for facts that aibox must
not guess:
- immutable image reference and digest;
- target platform;
- Compose context/scope or Kubernetes context/namespace;
- stable deployment owner;
- connection transports;
- credential references for any v0 environment entries;
- a remove-or-redesign disposition for host bind mounts.
The report never includes environment values. readyToEnable remains false
until these operator decisions have explicit v1 values. This makes the command
a migration planner, rather than a textual marker that implies the v0
configuration was fully converted.
Create a reviewed TOML document containing only one complete
[orchestration] tree, then apply it with the migration:
aibox config migrate-v1 --apply --intent-file v1-intent.toml --output json
The intent file may say enabled = true for validation, but the migration
always writes it as enabled = false. Aibox validates the complete image,
fleet, target, deployment, connection, and credential-reference contract
offline before it creates the backup or changes aibox.toml. Extra top-level
tables, incomplete intent, symlinked files, and raw credential values are
rejected. The result reports readyToEnable: true; activation remains a
separate reviewed edit followed by aibox config compile and
aibox deploy plan.
Apply the narrow migration only after reviewing the preview:
aibox config migrate-v1 --apply
The command creates an exact original copy under .aibox/backups/v1-config/ before atomically replacing aibox.toml. The only new configuration is:
[orchestration]
enabled = false
That disabled boundary is intentional. Add the reported unresolved values
explicitly, run aibox config compile, review aibox deploy plan, and only
then set enabled = true.
Roll back configuration
The apply result prints the backup path. Restore it explicitly:
aibox config migrate-v1 --restore .aibox/backups/v1-config/v0-<stamp>-<digest>.toml
Restore accepts only regular backups inside the project backup directory and uses an atomic replacement. It restores the config alone: it deliberately does not read, alter, or delete .aibox/deployments/ records or any remote resource. Use aibox deploy destroy while the v1 configuration and ownership record are still available if you intend to remove an existing v1 deployment.
Coexistence boundary
Do not point v0 generated Compose files at v1 deployment artifacts. v1 Compose deployments use their own rendered artifacts and ownership labels; Kubernetes deployments use namespace-scoped labels and a durable DeploymentRecord. The v0 lifecycle has no authority to operate either form of v1 state.
This boundary makes rollback safe but not magical: reverting a config does not roll back a remote deployment. Treat deployment removal as a separate, guarded operation with its own record and evidence.
2 -
Lockfile schema bump v0.25.6 — what’s automatic, what to verify
aibox v0.25.6 extends aibox.lock with two new optional sections. The
bump is fully automatic — aibox apply backfills the new fields on first
run. No manual editing is required, and existing lockfiles remain valid
(the new fields use #[serde(default)], so they are absent from old locks
without causing parse errors).
What changed
cli/src/lock.rs adds:
AddonsLockSection::previous_selection(BTreeMap<String, BTreeSet<String>>) — records which tool names were enabled under each addon family at the time of the last apply. Written under[addons.previous_selection]inaibox.lock. Used on the next apply to compute a removal diff when a tool is disabled, so stale addon binaries baked into an earlier image layer can be purged cleanly.[harnesses]section (HarnessLockSection) — records the set of AI harness names that were active (previous_selection: BTreeSet<String>) and the timestamp when the record was taken (recorded_at). Used byaibox applyto detect harnesses that were active last time but are no longer configured, enabling targeted cleanup of harness-specific state files (gated on[apply].purge_disabled_harness_state, defaultfalse).
Both fields are populated automatically on the first aibox apply that
runs against an old v0.25.5 lockfile.
Troubleshooting
[addons.previous_selection] is absent after apply.
This is expected if no addon tools are enabled — the field serializes
only when non-empty (skip_serializing_if = "BTreeMap::is_empty"). Enable
at least one tool under [addons] in aibox.toml and re-run
aibox apply to see it populated.
aibox apply reports a lockfile parse error after upgrading from
v0.25.5.
A truncated or hand-edited aibox.lock may have a malformed [addons]
section. Check that [addons].resolved_at is present and is a valid
ISO 8601 timestamp. If the file is corrupt, delete aibox.lock and run
aibox apply — the CLI regenerates it from scratch.
3 -
Zellij end-of-life migration (v0.25.5 → v0.25.6)
TL;DR
aibox v0.25.6 removes Zellij entirely. tmux is now the only supported
terminal multiplexer. Any [customization.zellij_status] section in your
aibox.toml causes schema validation to hard-reject aibox apply — you
must remove it before upgrading. Stale Zellij directories and binaries are
purged automatically on the first aibox apply that runs against a
v0.25.6+ host CLI. No data from active work sessions is touched; only
Zellij runtime artifacts are removed.
What changed
The following items are removed or rejected in v0.25.6 (commit faa9a88,
decision DEC-20260508_1515-SilentAsh):
[customization.zellij_status]config key — the field is removed from theCustomizationstruct incli/src/config.rs. The TOML deserializer now hard-rejects anyaibox.tomlthat still contains this section, with a descriptive error pointing to this document.--forget-zellij-stateCLI flag — removed from the argument parser incli/src/cli.rs. Scripts or aliases that reference this flag will fail to parse.Unconditional purge on
aibox apply— the following paths under.aibox-home/are deleted on every apply regardless of config:.config/zellij/.cache/zellij/.local/share/zellij/.local/bin/aibox-status(the shell-backed Zellij helper; superseded by the tmux PowerKit plugin set)
The purge is performed by
cleanup_legacy_zellij_files()incli/src/seed.rs, which calls unconditionally viaLEGACY_MUX_RELPATHS.aibox doctorerrors — any surviving artifact from the list above triggers anERRORdiagnostic (check_legacy_zellij_artifactsincli/src/doctor.rs). The error is not advisory; it blocks a clean doctor run.
What you need to do
Complete these steps on the host before or immediately after upgrading to v0.25.6:
a. Remove [customization.zellij_status] from your aibox.toml.
Open the file and delete the entire section (header and all keys beneath
it). If you have no such section, skip this step.
b. Migrate any custom status configuration to tmux. If you previously
used Zellij status customizations, set the tmux equivalent in aibox.toml:
[customization.tmux.status]
mode = "extended" # or "minimal" for a compact single-line bar
The extended mode renders a two-line powerline bar with aibox metrics
(log/OOM/proc/AI/MCP/migration counters). The minimal mode renders a
single line. See docs-site/docs/customization/layouts.md for full
reference.
c. Run aibox apply from a v0.25.6+ host CLI. This purges the stale
Zellij artifacts listed above and records the new lockfile schema fields.
d. Verify with aibox doctor. After apply, run:
aibox doctor
A passing run reports no check_legacy_zellij_artifacts errors. If
artifacts survive (e.g., because a volume mount shadowed the purge),
the error output lists the exact paths to remove manually.
Why
Zellij was introduced as an aibox sidecar multiplexer, but the WASM plugin runtime, session-state model, and config schema diverged frequently from aibox’s tmux-native layout engine. The persistent vim-pane handoff through Zellij regressed every three to five releases, and the native Zellij status plugin required a WASM build step that added both CI complexity and binary supply-chain surface. tmux has been the canonical aibox multiplexer since v0.25.0; keeping a Zellij compatibility layer alongside it caused drift in every layout-generation codepath.
Decision DEC-20260508_1515-SilentAsh records the full rationale and the
choice of scorched-earth excision (Variant 1 hard-purge) over a softer
deprecation path.
Need help
Open an issue at https://github.com/projectious-work/aibox/issues and
tag it zellij-migration. Include the output of aibox doctor and the
relevant section of your aibox.toml.