-
-
Notifications
You must be signed in to change notification settings - Fork 0
Snapshots and Rollback
The Snapshots & Rollback system in Numan provides a robust mechanism for capturing and restoring the state of the package manager. It ensures that any mutation to the system—such as installations, updates, or activations—can be safely reverted to a known good state. Snapshots are immutable, content-addressed records of the authoritative lockfile, module autoload projections, and nupm-import provenance.
The system uses a journaled restoration process to guarantee atomicity. Rollback never re-solves dependencies or substitutes artifacts; it restores exactly the state captured in the snapshot. This architecture protects against configuration drift and failed mutations by providing a verifiable path back to a stable environment.
Numan snapshots are stored as immutable directories under <root>/state/snapshots/, keyed by UUIDv7 identifiers. Each snapshot consists of a central manifest and several sidecar files that store specific state projections.
The core of the system is the SnapshotManifest, which serves as the authoritative header. It contains metadata about why and when the snapshot was created, as well as SHA256 digests for all associated sidecar files.
| Structure | Description |
|---|---|
SnapshotManifest |
Contains schema version, UUIDv7 ID, creation timestamp, reason/trigger, and sidecar digests. |
SidecarDigests |
Stores SHA256 hashes for lockfile.json, autoload.json, and imports.json. |
SnapshotAutoload |
Captures the managed module-autoload projection, including the exact content of numan.nu. |
SnapshotNuIdentity |
Records the Nu version and executable hash to ensure activation compatibility. |
Snapshots are typically triggered by mutations in the system. The SnapshotTrigger enum tracks these events:
-
Mutation Triggers:
Install,Update,Remove,Activate,Deactivate,NupmImport. -
System Triggers:
Rollback(a snapshot is taken of the current state before restoring an old one).
flowchart TD
Start[Trigger Mutation] --> Lock[Acquire Mutation Lock]
Lock --> ID[Generate UUIDv7 ID]
ID --> Capture[Capture Current State]
Capture --> Sidecars[Write Sidecar JSONs to Staging]
Sidecars --> Manifest[Write snapshot.json to Staging]
Manifest --> Atomic[Rename Staging to Final Dir]
Atomic --> Finish[Proceed with Mutation]
The diagram shows the atomic creation process for snapshots, ensuring no partial snapshots are committed to the store.
Rollback is a journaled restoration of Numan-owned state. It follows a strict set of preconditions to ensure safety:
- Payload Verification: Every package revision referenced in the snapshot's lockfile must exist on disk with the correct SHA256 revision hash.
- Identity Verification: The current Nu executable hash and Numan root path must match the snapshot to prevent restoring incompatible activation graphs.
-
Journaling: The process uses
LifecycleStageto track progress, allowing recovery if interrupted.
The rollback process follows a multi-stage atomic commit sequence:
sequenceDiagram
participant R as Rollback Logic
participant J as Lifecycle Journal
participant F as Filesystem
participant L as Lockfile
R->>J: Set Stage: RollbackPrepared
R->>J: Set Stage: CurrentStateSnapshotted
R->>F: Stage & Validate candidate numan.nu
R->>J: Set Stage: CandidateValidated
R->>L: Overwrite lockfile.json
R->>F: Replace managed numan.nu
R->>J: Set Stage: AutoloadCommitted
R->>F: Restore nupm-imports.json
R->>J: Clear Journal
The sequence illustrates how the system ensures that the lockfile and external managed files are restored in a specific, recoverable order.
Snapshots capture the exact state of Numan's integration with Nushell through the ManagedAutoloadProjection enum. This ensures that the restored numan.nu file matches the validation state of the snapshot.
-
Present: Stores the
managed_file_path, the full stringcontent, itssha256, and the list ofactive_module_ids. - Absent: Indicates that the managed file was intentionally absent at snapshot time.
- NotConfigured: Indicates that the vendor autoload directory was not set up.
When restoring a Present projection, the system generates a candidate file and uses a CandidateRunner (typically NuCandidateRunner) to execute nu -n <file>. This verifies that the restored module paths are still syntactically valid before the live file is replaced.
The snapshot subcommand group provides the user interface for managing the snapshot store.
| Command | Action | Implementation |
|---|---|---|
list |
Displays all snapshots, reasons, and package counts. | list_snapshots |
inspect |
Shows diffs, payload verification, and metadata. |
load_snapshot + verify_payloads
|
delete |
Removes a snapshot directory (requires confirmation). | delete_snapshot |
rollback |
Executes the restoration process. | rollback_to_snapshot |
The system implements several layers of safety:
- Advisory Locks: Mutation commands (delete, rollback) must acquire a root mutation lock.
- Symlink Protection: Snapshot operations refuse to operate on paths that are symlinks or reparse points to prevent escape from the Numan root.
-
Journal Reconciliation: If a rollback is interrupted, re-running the same command uses the
target_snapshot_idin the journal to resume the atomic overwrite.
The Snapshots & Rollback system provides a critical safety net for Nushell environment management. By treating the lockfile and autoload files as a single atomic unit, Numan allows users to experiment with package versions while maintaining a guaranteed path to recovery. The use of UUIDv7 ensures snapshots remain chronologically sortable, while SHA256 digests across all sidecars guarantee the integrity of the restored state.
- Canonical spec: docs/snapshots-and-rollback.md
- Update, Remove, and GC
Numan wiki for tonythethompson/numan · v0.1.4 · MIT