State and Snapshots
Current state layout and the supported snapshot command surface.
Runtime state is stack-scoped:
.devstack/stacks/<stack>/
manifest.json
projection.v3.json
runtime/
snapshots/projection.v3.json is the persisted operator read model used by devstack status, the TUI, and
plain renderer startup sweeps. If the file is missing, malformed, or from an unsupported shape,
devstack treats it as absent and rebuilds status from the next running stack rather than crashing.
The usual snapshot flow is a one-shot CLI capture when no attached devstack up session is running:
devstack snapshot save
devstack snapshot save before-migration
devstack snapshot list
devstack snapshot restore <name-or-id>
devstack snapshot delete <name-or-id>Snapshot names are the operator-facing handle. save before-migration records the name in metadata
and stores the artifact under a generated immutable id. If no name is supplied, devstack generates a
manual-... name. Names must be unique within a stack, so restore before-migration is
deterministic. The generated id is still shown by list and can always be used as an escape hatch.
To boot from a snapshot and then continue normal stack startup, use up --from-snapshot:
devstack up --from-snapshot before-migration
devstack up --from-snapshot before-migration --snapshot-stale block
devstack up --from-snapshot before-migration --snapshot-stale clean-start
devstack up --snapshot-cache dev-baseline--from-snapshot resolves the same name-or-id references as snapshot restore, restores before the
initial acquire, and then lets the supervisor converge the stack. The default stale policy is
warn: if the snapshot's graph input id differs from the current stack's graph input id, devstack
logs a warning and proceeds. Use block to refuse the restore on graph-input drift, or
clean-start to skip the restore and boot normally when the snapshot is stale.
--snapshot-cache <name> uses the same graph-input check as a startup cache: a current snapshot is
restored, while a missing or stale one is refreshed after a normal startup.
When you are already attached to devstack up --renderer tui, use the TUI shortcut instead of
starting a second snapshot command. Press s, type a snapshot name, and press Enter. Press Enter on
an empty prompt to use a generated manual-... name, or press Esc to cancel. The shortcut exists
only in TUI mode; plain and silent renderers do not handle keypress commands.
TUI capture runs in the background after the prompt submits. The bottom status row shows the active
phase and when the stack is paused for snapshot consistency. While capture is running, a second
submitted snapshot is skipped and q still enters graceful shutdown instead of waiting behind the
capture command.
Snapshot capture takes one stack-wide quiescence window for managed runtime state. Devstack validates the full capture set, pauses every running managed container, commits container writable layers, archives declared host subtrees, writes state/contribution metadata, then unpauses the containers. The TUI stays responsive during that window, but services behind the stack may briefly stop responding while Docker containers are paused.
One artifact lives under .devstack/stacks/<stack>/snapshots/<snapshotId>/ and uses this layout:
meta.json
state.json # present only when the stack state store exists
host-tree.tar
containers/images.tar
contributions/<encoded-plugin>.jsonSupported behavior:
- CLI save performs a one-shot stack boot and captures a snapshot of the selected stack.
up --from-snapshot <name-or-id>restores a selected snapshot before startup and supports--snapshot-stale warn|block|clean-startfor graph-input drift.up --snapshot-cache <name>restores that named snapshot when current and refreshes it after startup when it is missing or stale.- TUI save captures the currently attached stack and is intended for operator snapshots during
devstack up --renderer tui. - Restore resolves a name or id, refuses to run while
devstack upis live, then restores that artifact directly after--yesor an interactiveyconfirmation. - List reads snapshot metadata from the active stack root and tolerates corrupt entries by showing a fallback row.
- Delete removes the resolved artifact from the selected stack root after
--yesor an interactiveyconfirmation.
Important caveats:
- Do not rely on cross-stack restore. Snapshot metadata carries app, stack, network, and plugin
identity slices (including a Sui
modediscriminator); restore refuses identity drift with a fail-closedIdentityMismatchErrorbefore any destructive change, never a silent restore. - Snapshots also record a graph input id derived from the stack graph, selected options, devstack version, and plugin-authored input identity. A mismatch means the snapshot was captured for different inputs; restore warns by default because it may create inconsistent state.
- Product evidence for non-empty wallet, Seal, Walrus, and DeepBook roundtrips is still incomplete. These docs describe the supported CLI and artifact contract, not a claim that every service has full restore proof.
- The supported snapshot surface is the CLI and the on-disk artifact described above. Treat
meta.json,state.json,host-tree.tar, andcontainers/images.taras the artifact contract; everything else under the snapshot directory is implementation detail and not load-bearing for app or plugin-author code.
Use devstack wipe --yes --stack <name> to remove all state for a selected stack in non-interactive
shells. In a TTY, omitting --yes prompts for y before deleting state.