-
-
Notifications
You must be signed in to change notification settings - Fork 0
nupm Drift Detection
nupm Drift Detection is a mechanism within Numan designed to identify discrepancies between an imported package's current state in the nupm source directory and its recorded state at the time of import into Numan's immutable revision store. Since Numan uses one-way imports (snapshots) rather than live links, drift detection allows users to monitor when local nupm modules have been modified, requiring an explicit re-import to synchronize changes.
The drift detection system operates by comparing live filesystem metadata and payload hashes against the provenance records stored in state/nupm-imports.json. The process ensures that Numan remains independent of nupm's mutable layouts while providing visibility into source changes.
The comparison logic follows a structured sequence to determine the specific nature of the drift:
-
Identity Verification: Confirms the package exists in the Numan lockfile and was originally an
nupm_import. - Provenance Retrieval: Loads the recorded nupm source path and metadata SHA256 from the Numan imports state.
- Classification: Re-scans the live source path to ensure it is still an "ImportableModule" and free of unsafe filesystem changes (e.g., symlink escapes).
-
Content Hashing: Computes live SHA256 hashes for both the
nupm.nuonmetadata and the actual module payload.
The following diagram illustrates the logical flow of the compare_import function:
flowchart TD
Start[Start Compare] --> LF[Load Lockfile]
LF --> IsNupm{Origin == nupm?}
IsNupm -- No --> CantCompare[Status: CannotCompare]
IsNupm -- Yes --> LoadProv[Load Provenance State]
LoadProv --> SrcExist{Source Path Exists?}
SrcExist -- No --> SrcMissing[Status: SourceMissing]
SrcExist -- Yes --> Classify[Classify Live Source]
Classify --> Valid{Is Eligible?}
Valid -- No --> Unsafe[Status: UnsafeSourceTreeChange]
Valid -- Yes --> HashMeta[Compute Metadata Hash]
HashMeta --> MetaDiff{Metadata Changed?}
MetaDiff -- Yes --> MetaChange[Status: MetadataChanged]
MetaDiff -- No --> HashPayload[Compute Payload Hash]
HashPayload --> PayDiff{Payload Changed?}
PayDiff -- Yes --> PayChange[Status: PayloadChanged]
PayDiff -- No --> Unchanged[Status: Unchanged]
The diagram shows how Numan prioritizes safety checks (classification) before performing expensive hashing operations.
Drift detection results are categorized into specific statuses to help the user understand what has changed.
| Status | Description |
|---|---|
Unchanged |
The source metadata and payload match the recorded import hashes. |
SourceMissing |
The recorded nupm source directory no longer exists on disk. |
MetadataChanged |
The nupm.nuon file has been modified since the last import. |
PayloadChanged |
The module's functional code (.nu files) has been modified. |
UnsafeSourceTreeChange |
The source is no longer eligible for import (e.g., build hooks added or unsafe symlinks). |
CannotCompare |
Comparison failed because the package is not a Numan-managed nupm import. |
The DriftReport struct encapsulates the full context of a drift check, facilitating both CLI output and the numan doctor health checks.
pub struct DriftReport {
pub package_id: String,
pub status: DriftStatus,
pub recorded_source: PathBuf,
pub installed_revision_id: Option<String>,
pub recorded_source_payload_sha256: String,
pub live_source_payload_sha256: Option<String>,
pub recorded_metadata_sha256: String,
pub live_metadata_sha256: Option<String>,
}Drift detection is integrated into several Numan commands to provide a comprehensive view of system health.
The numan doctor command includes a specific check for nupm drift. It uses the count_drifted_imports function to scan all imported packages. If drift is detected, it issues a Severity::Warn finding and suggests the numan nupm diff <owner/name> command as a fix hint.
The system provides specialized formatters in src/nupm_compat/report.rs to present drift data to the user, including the live vs. recorded SHA256 hashes for transparency.
sequenceDiagram
participant CLI as numan nupm diff
participant Drift as nupm_compat::drift
participant State as prov: nupm-imports.json
participant FS as Live Filesystem
CLI->>Drift: compare_import(root, pkg_id)
Drift->>State: Load recorded hashes
Drift->>FS: Read nupm.nuon & payload
FS-->>Drift: Bytes & Path status
Drift->>Drift: Compute live SHA256
Drift-->>CLI: DriftReport
CLI->>CLI: format_drift_report()
The sequence diagram demonstrates the interaction between the CLI, the immutable state, and the mutable nupm source files.
Numan does not automatically synchronize drifted packages to maintain the principle of immutable payloads. When drift is identified (e.g., through numan nupm diff), the user must manually trigger numan nupm import <path> --as owner/name --yes. This creates a new Numan revision while preserving the old revision for rollback purposes.
Numan wiki for tonythethompson/numan · v0.1.4 · MIT