Crash Recovery & Journals
Relevant source files
The following files were used as context for generating this wiki page:
Numan utilizes a journal-based system to ensure robust crash recovery and maintain state integrity during multi-step mutations. Because Numan manages external state—such as Nushell's plugin registry and vendor autoload files—it employs journals to track in-flight operations. If a process is interrupted, these journals allow Numan to reconcile the system to a consistent state upon the next execution.
The journaling system covers several critical areas: plugin activation and deactivation, module autoloading, general package lifecycles (update, remove, import), and legacy system migrations. All journals are stored as atomic JSON files within the $NUMAN_ROOT/state/ directory.
Sources: AGENTS.md:129-145, src/cmd/doctor.rs:271-344
Journal Architecture and Core Principles
The journaling system is built on the principle of staged transactions. Before any filesystem or external state modification, Numan writes a "Prepared" stage to the relevant journal. As the operation progresses, the journal is updated to reflect the new state. Once the transaction is fully committed to the authoritative Lockfile, the journal is cleared.
Transaction Flow
The following diagram illustrates the typical lifecycle of a journaled transaction:
The logic for reconciliation depends on the specific journal but generally involves either completing the interrupted task or rolling back partial changes if the environment has drifted.
Sources: src/state/migration_journal.rs:16-30, AGENTS.md:129-136
Specific Journal Types
Plugin Activation & Deactivation Journals
Plugins require registration with the Nushell process. Numan tracks pending activations and deactivations to prevent stale or orphaned plugin entries.
- Activation Journal (
pending-activation.json): Records plugins intended for registration. It tracks the specific Nu executable hash and version to ensure compatibility. - Deactivation Journal (
pending-plugin-deactivate.json): Tracks plugins slated for removal from the Nushell registry.
| Field | Type | Description |
|---|---|---|
nu_executable_hash | String | SHA256 of the Nu binary the plugin is being registered for. |
nu_version | String | Version string of the active Nushell. |
entries | Vec<Entry> | List of packages and their specific registration paths. |
Sources: src/state/journal.rs:24-40, src/state/plugin_deactivate_journal.rs:23-38
Module Autoload Journal (pending-autoload.json)
The autoload journal manages the state of the Numan-managed vendor/autoload/numan.nu file. It uses two primary stages: Prepared and Replaced.
If a crash occurs in the Replaced stage, Numan knows the candidate file exists and can attempt to finalize the atomic move.
Sources: src/state/autoload_journal.rs:10-25, AGENTS.md:131-133
Lifecycle Journal (pending-lifecycle.json)
This journal tracks high-level package operations such as Install, Update, Remove, and NupmImport. It ensures that if a package payload is partially extracted or deleted, the system can identify the corruption.
Operation (op) | Stages |
|---|---|
Install | Prepared, Extracted |
Update | Prepared, Extracted |
Remove | Prepared, PayloadDeleted |
NupmImport | Prepared, Copied |
Sources: src/state/lifecycle_journal.rs:20-50
Migration Journal (migration-journal.json)
Used for transitioning legacy single-binary Nushell installations to the modern versioned layout. It ensures the transition between the legacy path and <root>/tools/nushell/<version>/ is atomic.
- Prepared: Journal written, directory created.
- Renamed: Legacy binary moved to the versioned directory.
- Active:
active-version.jsonupdated; transaction complete.
Sources: src/state/migration_journal.rs:36-60
Reconciliation and the Doctor Command
Reconciliation is the process of checking for and resolving pending journals. This happens automatically at the start of relevant commands (e.g., numan activate reconciles the autoload journal) and can be triggered manually via numan doctor --fix.
Reconciliation Logic in numan doctor
The doctor command scans for all journal types and evaluates their "health."
The doctor command distinguishes between "stale" journals (where the Nu binary or environment has changed since the journal was written) and "pending" journals (which simply need completion).
Sources: src/cmd/doctor.rs:271-344, src/state/migration_journal.rs:168-200
Data Structures
Migration Journal Structure
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PendingMigration {
pub schema_version: u32,
pub version: String,
pub stage: MigrationStage,
}
Sources: src/state/migration_journal.rs:65-71
Autoload Journal Structure
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PendingAutoload {
pub nu_executable_hash: String,
pub nu_version: String,
pub stage: AutoloadStage,
pub entries: Vec<AutoloadEntry>,
}
Sources: src/state/autoload_journal.rs:65-72
Summary
The journaling system provides the "fail-safe" layer for Numan. By decomposing complex operations into discrete, recorded stages, Numan ensures that even unexpected terminations do not lead to silent corruption of the Nushell environment. The numan doctor utility serves as the primary interface for users to inspect and repair these interrupted states, while the commands themselves perform self-healing where possible.
Sources: AGENTS.md:129-145, src/cmd/doctor.rs:12-25