-
-
Notifications
You must be signed in to change notification settings - Fork 0
Crash Recovery Journals
Crash Recovery Journals are a set of durable, JSON-based state files used by Numan to ensure transactional integrity across operations that span multiple filesystem locations. Because Numan cannot atomically commit changes to both its internal state (like the lockfile) and external Nushell locations (like the plugin.msgpackz or numan.nu autoload file), it uses these journals to make interrupted work detectable and safely recoverable.
The system employs three primary journals: the Plugin Activation Journal, the Module Autoload Journal, and the Lifecycle Journal. These journals allow the numan activate command or the numan doctor utility to reconcile the system's state if a process is killed, the filesystem fails, or the environment drifts between operations.
The journaling system follows a "Prepared-then-Replaced" protocol. Before any mutation to an external Nu-owned file occurs, Numan writes a journal at the Prepared stage. Once the external mutation is successful, the journal is updated to Replaced before internal Numan state (the lockfile) is updated.
The following diagram illustrates the standard flow for a journaled transaction, specifically for module autoloading.
flowchart TD
Start[Start Mutation] --> Lock[Acquire Mutation Lock]
Lock --> Snapshot[Create State Snapshot]
Snapshot --> PrepJournal[Write Prepared Journal]
PrepJournal --> External[Mutate External File]
External --> ReplaceJournal[Update Journal to Replaced]
ReplaceJournal --> Internal[Update Internal Lockfile]
Internal --> Clean[Delete Journal]
Clean --> Unlock[Release Mutation Lock]
The flow ensures that if the process fails at "Mutate External File", the journal remains in the Prepared state to signal an abort or retry.
Stored at $NUMAN_ROOT/state/pending-activation.json, this journal tracks the registration of Nushell plugins. It specifically records the Nu identity (executable hash and version) to ensure that recovery is only attempted in a matching environment.
| Field | Type | Description |
|---|---|---|
nu_executable_sha256 |
String |
SHA-256 of the Nu binary used for registration. |
nu_version |
String |
The version of Nushell detected. |
plugin_registry_path |
String |
Path to Nu's plugin registry (e.g., plugins.msgpackz). |
entries |
Vec<Entry> |
List of plugins being registered and their status. |
Each entry in the journal tracks a status:
- Prepared: The intent to register is recorded.
-
Registered: The
plugin addcommand succeeded, but the lockfile is not yet updated. - Failed: The registration failed, typically including an error message.
Stored at $NUMAN_ROOT/state/pending-autoload.json, this journal manages the generation and replacement of the numan.nu vendor autoload file. It is critical because module activation changes the future startup behavior of Nushell.
The PendingAutoload structure provides specific recovery methods based on the transaction stage:
- recover_prepared(): Verifies if the live managed file still matches the recorded previous state. If it does, the journal is cleared (safely abandoned).
-
recover_replaced(): Verifies that the managed file matches the
candidate_sha256. If successful, it allows the lockfile andautoload-state.jsonto be updated to match the external reality.
flowchart TD
Check[Inspect Journal] --> Stage{Stage?}
Stage -- Prepared --> VerPrev{Matches Previous?}
VerPrev -- Yes --> Abandon[Clear Journal/Safe]
VerPrev -- No --> Drift[Block/Drift Detected]
Stage -- Replaced --> VerCand{Matches Candidate?}
VerCand -- Yes --> Complete[Finish Lockfile Update]
VerCand -- No --> Drift
The Lifecycle Journal (pending-lifecycle.json) manages high-level package operations such as updates, removals, and nupm imports.
Operation (LifecycleOp) |
Stages (LifecycleStage) |
Description |
|---|---|---|
Update |
Prepared, PayloadsStaged, PayloadsPromoted, SelectionCommitted
|
Replaces a package with a newer version. |
Remove |
Prepared, SelectionCommitted
|
Removes a package from the lockfile and deletes payloads. |
NupmImport |
Prepared, PayloadsStaged, PayloadsPromoted, SelectionCommitted
|
Imports a local package from nupm into Numan. |
A key feature of Numan journals is the validation of the Nu identity. If the Nushell binary is updated (changing its hash or version), Numan considers the journal "stale."
pub fn matches_nu_identity(&self, nu_executable_sha256: &str, nu_version: &str) -> bool {
self.nu_executable_sha256 == nu_executable_sha256 && self.nu_version == nu_version
}In numan activate, the system performs a preflight check. If a stale journal is detected, it bails and directs the user to run numan init --refresh to reconcile the environment before attempting recovery.
Crash Recovery Journals provide the "transactional glue" for Numan's inert install model. By separating intent (Prepared) from execution (Replaced/Registered), Numan ensures that its authoritative lockfile remains synchronized with external Nushell integration points, even in the event of unexpected process termination. The numan doctor utility further leverages these journals to provide automated state repair.
Numan wiki for tonythethompson/numan · v0.1.4 · MIT