Capture and restore `nu_state/paths.json` in snapshots

Merged
TO
3mo ago
+459-19

Summary

numan init --refresh rewrites nu_state/paths.json, but snapshots previously only stored lockfile / autoload / imports plus optional nu_identity (hash + version). Rollback restored the activation graph, not the path cache, so refresh-then-rollback with no active packages could leave paths on the post-refresh Nu.

This PR adds an additive paths sidecar to every new snapshot and restores it during rollback, including the empty-lockfile case.

Changes

  • Snapshot schema (src/state/snapshot.rs): optional SidecarDigests.paths_sha256 + SnapshotPaths::{Absent, Present(NuPaths)} sidecar written on every create_snapshot. Legacy snapshots without the file still load (paths: None).
  • Rollback (src/state/rollback.rs): journaled PathsCommitted step after imports. Present → NuPaths::save; Absent → delete paths.json; legacy None → leave live cache alone. Keeps the existing Nu-identity precondition for Present managed autoload (checked against the live cache before restore).
  • Init (src/cmd/init.rs): init --refresh takes a PreMutation / Init snapshot before rewriting lockfile identity or paths.json.
  • Docs: docs/snapshots-and-rollback.md + AGENTS.md (capture set, restore order, no-active-packages behavior, nu_identity vs paths sidecar).
  • Inspect: shows paths digest / captured Nu cache summary.

Non-goals

  • Does not move Nu binaries or rewrite shell PATH.
  • Absolute paths in the sidecar remain root-specific (same as autoload).
  • Additive optional fields only; no schema version bump.

Test plan

  • Snapshot with paths present → load verifies digest
  • New snapshot with paths absent records Absent
  • Legacy snapshot without paths sidecar still loads
  • Rollback with empty lockfile restores mutated paths.json
  • Rollback when snapshot had Absent deletes paths
  • Legacy rollback leaves live paths alone
  • Refresh-then-rollback round-trip restores pre-refresh paths
  • cargo fmt --check
  • cargo clippy -- -D warnings
  • cargo test (full suite green; one pre-existing flaky nu::paths PATH fall-through test observed under parallel load, passes on retry / isolation)
Open in Web Open in Cursor