Skip to content

Snapshots and Rollback

tonythethompson edited this page Jul 10, 2026 · 1 revision

Snapshots & 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.

Snapshot Architecture

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.

Data Structures

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.

Snapshot Lifecycle

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]
Loading

The diagram shows the atomic creation process for snapshots, ensuring no partial snapshots are committed to the store.

Rollback Mechanism

Rollback is a journaled restoration of Numan-owned state. It follows a strict set of preconditions to ensure safety:

  1. Payload Verification: Every package revision referenced in the snapshot's lockfile must exist on disk with the correct SHA256 revision hash.
  2. Identity Verification: The current Nu executable hash and Numan root path must match the snapshot to prevent restoring incompatible activation graphs.
  3. Journaling: The process uses LifecycleStage to track progress, allowing recovery if interrupted.

Rollback Transaction Flow

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
Loading

The sequence illustrates how the system ensures that the lockfile and external managed files are restored in a specific, recoverable order.

Managed Autoload Projections

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 string content, its sha256, and the list of active_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.

Autoload Validation During Rollback

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.

Command Interface

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

Safety & Integrity

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_id in the journal to resume the atomic overwrite.

Conclusion

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.

See also

Clone this wiki locally