Skip to content
tonythethompson edited this page Jul 10, 2026 · 1 revision

Inert Installation

Inert Installation is a core architectural principle of the Numan package manager. It dictates that the install command must only write data to the designated $NUMAN_ROOT directory and must never modify the Nushell environment, register plugins, or write autoloads. By keeping installations inert, Numan ensures that the act of downloading and verifying a package does not impact the user's shell until an explicit Activation command is issued.

This design provides a clean boundary between package retrieval and environment integration. It allows for safe version pinning in a lockfile and artifact verification without the risk of breaking a running shell session during the installation transaction.

Core Transaction Logic

The installation process is handled primarily by the install_package function, which executes a multi-step transaction to move a package from a registry to the local filesystem. This transaction includes resolving the correct version, downloading artifacts to a temporary cache, verifying integrity via SHA256, and extracting files to an immutable, versioned path.

The Installation Lifecycle

The following diagram illustrates the sequence of events during an inert installation:

sequenceDiagram
    participant CLI as "CLI Handler"
    participant RM as "RegistryManager"
    participant RES as "Resolver"
    participant DL as "Downloader"
    participant EXT as "Extractor"
    participant LF as "Lockfile"

    CLI->>RM: load_verified(registry)
    RM-->>CLI: VerifiedIndex
    CLI->>RES: resolve(package, version)
    RES-->>CLI: ResolvedVersion (Artifact + Metadata)
    CLI->>DL: download_file(url, .part)
    Note over DL: Verification via SHA256
    DL-->>CLI: Cached Archive
    CLI->>EXT: extract_archive(tmp_dir)
    EXT-->>CLI: Extracted Files
    CLI->>LF: save(LockfileEntry)
    Note right of LF: Writes to $NUMAN_ROOT/lockfile
Loading

The sequence demonstrates that the transaction interacts only with the registry, the local cache, and the Numan root.

Immutable Payload Structure

Numan uses a content-addressed, immutable path structure for all installed packages. This prevents overwriting existing versions and allows multiple versions of the same package to coexist in the filesystem without conflict. The path is constructed using the package type, owner, name, and a combination of the version string and a SHA256 prefix of the artifact.

Path Component Description Example
Root The platform-specific Numan root ~/.local/share/numan
Category packages/ prefix packages/
Type The package type (plugin/module/etc) plugins
Owner The package owner/scope nushell
Name The package name nu_plugin_query
Version-Hash Version string and 8-char SHA prefix 1.0.0-a1b2c3d4

Data Persistence (Lockfile v2)

The Lockfile serves as the authoritative record of all inert installations. During the final stage of the transaction, a LockfileEntry is generated and persisted. This entry contains all metadata required for future activation without needing to re-consult the registry.

Key Lockfile Fields for Modules

For module packages, the installation transaction persists specific metadata to enable Phase 4 autoloading:

  • module_import_mode: Captures the registry's requested import style (e.g., Module or All).
  • locked_dependencies: A map of required packages at the time of installation.
  • payload_path: The relative path within the Numan root where the artifact was extracted.
  • revision_id: A deterministic hash of the extracted payload used for drift detection.

Staging and Atomic Promotion

To ensure the integrity of the $NUMAN_ROOT, the installation process uses a staging area for extraction and atomic filesystem operations for promotion.

  1. Staging: Artifacts are extracted into a temporary directory created via tempfile::tempdir_in within the Numan root. This ensures the temporary files are on the same filesystem volume as the final destination.
  2. Validation: Before promotion, Numan validates that required files (like the plugin executable or the module entry point) exist in the staging directory.
  3. Atomic Move: The temporary directory is renamed to the final immutable path using std::fs::rename.
flowchart TD
    A[Download Archive] --> B{Verify SHA256}
    B -- Fail --> C[Bail/Error]
    B -- Pass --> D[Create Staging Dir]
    D --> E[Extract Artifact]
    E --> F{Validate Entry Point}
    F -- Missing --> G[Delete Staging/Bail]
    F -- Found --> H[Atomic Rename to Final Path]
    H --> I[Update Lockfile]
Loading

This flow ensures that no partial or invalid installations are ever promoted to the active packages/ directory.

Safety Invariants

Rule Implementation Detail
No Nu Mutation The install command never calls plugin add or writes to Nu autoload files.
Mutation Locking All mutating operations, including install, must acquire a root-scoped advisory lock via acquire_mutation_lock.
Snapshotting A state snapshot is created using create_snapshot before the lockfile is modified.
Symlink Safety Numan avoids following symlinks that escape the payload directory or the Numan root during extraction.

Conclusion

Inert Installation is the foundation of Numan's reliability. By restricting the install transaction to local, immutable, and verified filesystem operations, the system guarantees that package management remains decoupled from the shell's runtime environment. This allows for safe updates, side-by-side versioning, and robust crash recovery through journaling and snapshots.

Clone this wiki locally