Diagnostics & Doctor
Relevant source files
The following files were used as context for generating this wiki page:
Diagnostics in Numan are primarily handled by the doctor command, which serves as a health-check and automated repair system for the package manager's environment. The system scans the Numan root directory, configuration, lockfiles, and Nushell integration state to identify inconsistencies, stale data, or corrupted journals. It classifies findings by severity and provides actionable hints or automated fixes to restore the system to a known good state.
The "Doctor" module is designed to be safe; it creates an immutable activation snapshot before applying any mutation and allows for a "scan-only" mode for reporting. It ensures that the ground truth—defined by the lockfile—is correctly projected into the Nushell environment, including plugin registrations and module autoloads. Sources: src/cmd/doctor.rs:43-52, README.md:144-147, AGENTS.md:94-96.
Architecture and Core Components
The diagnostic system is structured around a reporting pipeline that separates discovery (findings) from remediation (repairs).
Data Structures
The core of the diagnostic reporting is defined by several key structs that categorize the state of the system:
| Struct | Purpose |
|---|---|
DoctorReport | The top-level container for a diagnostic run, including findings and repair records. |
Finding | Represents a single issue detected, including a unique ID, severity, and a suggested fix hint. |
RepairRecord | Logs the result of a repair attempt (Applied, Skipped, or Failed). |
Summary | Provides a count of errors, warnings, and informational messages. |
Sources: src/cmd/doctor.rs:72-119
Diagnostic Flow
The execute function follows a logical progression: scanning, reporting, and (optionally) repairing.
This diagram illustrates the operational flow of the doctor command, emphasizing the safety gate provided by the mutation lock and snapshot system. Sources: src/cmd/doctor.rs:136-146, AGENTS.md:104-106.
Diagnostic Categories
The Doctor module organizes its checks into logical sections to cover all aspects of the Numan lifecycle.
1. Root and Layout Checks
Verifies that the Numan root directory exists, is writable, and contains the required directory structure (nu_state, state, packages, registries).
Sources: src/cmd/doctor.rs:197-248
2. Nushell Environment & Initialization
Validates the availability of the Nushell binary (on PATH or managed) and checks for "drift" in the cached nu_paths.json. Drift occurs if the Nushell executable hash or version has changed since the last numan init.
Sources: src/cmd/doctor.rs:277-360
3. Journal & Crash Recovery
Numan uses journals to track multi-step operations. The doctor identifies interrupted operations by checking for pending journals in the state/ directory:
- Activation Journals:
pending-activation.json(plugins) andautoload-journal(modules). - Deactivation Journals:
pending-plugin-deactivate.json. - Lifecycle Journals:
pending-lifecycle.jsonfor updates/removes. - Migration Journals:
migration-journal.jsonfor legacy layout transitions.
Sources: src/cmd/doctor.rs:407-505, AGENTS.md:113-119
4. Activation & Lockfile Integrity
Checks if the packages recorded in the lockfile match the current activation state. It detects "stale" activations where a plugin or module was activated for a different version of Nushell than the one currently in use. Sources: src/cmd/doctor.rs:555-635.
Sources: src/cmd/doctor.rs:600-618
Automated Repairs
When not in --scan mode, Numan attempts to fix issues classified under RepairTier::Auto or RepairTier::Confirm.
- Layout Repairs: Automatically creates missing directories (
mkdir -p). - Initialization: Re-runs
numan initif paths are missing ornuman init --refreshif drift is detected. - Journal Reconciliation: Re-runs activation or deactivation logic to complete interrupted tasks.
- Registry Config: Automatically adds the official registry if none are configured.
Sources: src/cmd/doctor.rs:822-940, tests/doctor_test.rs:130-150
Mutation Safety
Repairs that modify state require a MutationLock. The system also enforces a "fail-closed" policy for active plugin updates: if a plugin is currently active, it is "mutation gated" (Issue #22) to prevent corruption unless specific environment variables are set.
Sources: src/cmd/doctor.rs:587-598, src/util/hints.rs:142-160
Diagnostic Hints and User Guidance
The util::hints module provides canonical fix strings. These are used by the doctor and other commands to guide users toward resolution.
| Finding ID | Severity | Canonical Fix Hint |
|---|---|---|
nu_paths.missing | Error | numan init |
nu_paths.drift | Error | numan init --refresh |
journal.plugin_pending | Warn | numan activate |
registry.none | Warn | numan registry sync or numan init |
activation.plugin_mutation_gated | Info | numan deactivate <pkg>, then numan remove <pkg> |
Sources: src/util/hints.rs:4-40, src/cmd/doctor.rs:587-598
Code Snippet: Finding Generation
// src/cmd/doctor.rs:172-186
fn finding(
id: &str,
severity: Severity,
message: impl Into<String>,
fix: Option<&str>,
repair: RepairTier,
) -> Finding {
Finding {
id: id.to_string(),
severity,
message: message.into(),
fix: fix.map(str::to_string),
repair,
}
}
This helper function is used throughout the module to maintain a consistent structure for all diagnostic discoveries.
Conclusion
The Diagnostics & Doctor system is a critical stability layer in Numan. By providing transparent reporting and safe, automated recovery paths, it ensures that Nushell package management remains reliable even across shell upgrades and interrupted filesystem operations. The reliance on the lockfile as the single source of truth allows the Doctor to reconcile the environment effectively.