Resolution Algorithm
Relevant source files
The following files were used as context for generating this wiki page:
The Resolution Algorithm in cargo-cooldown is a multi-pass process designed to identify and replace "fresh" crate versions—those published within a specific cooldown window—with the newest compatible older versions that Cargo accepts. It operates as a wrapper around Cargo's native resolution, intercepting the dependency graph after Cargo resolves it, and then iteratively mutating the Cargo.lock file to achieve a "cooled" state.
Sources: src/executor.rs:1-12, README.md:1-5
Core Execution Loop
The algorithm follows a high-level "Main Execution Loop" that repeats until no more fresh packages can be resolved or a fixed point is reached. Each pass consists of capturing metadata, building a resolution state, and attempting various solver strategies.
The diagram shows the iterative nature of the resolution loop where each successful pin restarts the metadata scan.
Sources: src/executor.rs:81-182
Resolution State Building
The build_resolution_state function aggregates facts needed for a solver pass. It converts raw Metadata into a CargoSnapshot containing only reachable packages from the selected workspace roots. It then checks each package against configuration (e.g., cooldown_minutes, allow_rules) and registry metadata to determine if it is "fresh".
Sources: src/resolution_state.rs:188-212, src/resolution_state.rs:356-378
| Component | Description |
|---|---|
CargoSnapshot | A compact subset of Cargo metadata limited to the selected dependency closure. |
CrateState | Stores identity, version, and exemption reasons (skipped, allowed, or baseline exempt). |
RequirementOrigin | Tracks which parent package and manifest requirement constrained a specific dependency. |
ScanSummary | Aggregates counters for UI reporting (e.g., inspected, fresh, skipped). |
Sources: src/resolution_state.rs:36-54, src/resolution_state.rs:141-177
Solver Strategies
The algorithm employs two primary strategies to resolve fresh dependencies: the Cooldown Batch Solver and the Coordinated Bundle Resolution.
Cooldown Batch Solver
This is the primary strategy for cooling many fresh crates simultaneously. It builds optimistic pins based on registry metadata and applies a "baseline floor" if configured.
- Local Dependency Solving: Before involving Cargo, the solver expands root pins into locally consistent dependency components. This ensures that transitive dependencies that must move with the root are included in the same batch.
- Blocker Pruning: If Cargo rejects a batch rewritten to
Cargo.lock(checked viacargo metadata --locked), the algorithm uses Cargo's diagnostic output to identify "blocker" packages, removes them from the batch, and retries.
Sources: src/executor.rs:597-627, src/executor.rs:659-715
Coordinated Bundle Resolution
This strategy handles crates tied together by exact requirements (e.g., =x.y.z). These cannot be cooled individually. The algorithm groups connected components and performs a bounded backtrack search to find a compatible older version for the entire bundle.
Sources: src/executor.rs:1095-1143, src/executor.rs:1189-1250
Configuration and Policy Enforcement
The resolution behavior is heavily influenced by two key settings: lockfile_baseline and enforcement.
| Setting | Type | Description |
|---|---|---|
lockfile_baseline | floor | ignore | floor treats existing Cargo.lock versions as the minimum allowed; ignore allows downgrades below them. |
enforcement | strict | cargo_compatible | off | strict bails if any fresh version remains; cargo_compatible allows them as warnings if Cargo requires them. |
cooldown_minutes | u64 | The window of time (in minutes) a release must be older than to be considered "cool". |
Sources: src/config.rs:15-61, README.md:58-76
Policy Flow
Sources: src/executor.rs:717-775
Final Run Summary
After the resolution loop finishes, the algorithm compares the initial lockfile, the "cooldown start" lockfile (post-Cargo update), and the final "cooled" lockfile. It categorizes changes into actions: Adding, Cooling, Downgrading, Keeping, Removing, or Updating.
Sources: src/executor.rs:252-320, src/executor.rs:438-510
Dependency Confirmation
If enforcement = "cargo_compatible" is set and fresh versions remain that the solver could not replace, the algorithm prompts the user for confirmation (if stdin is a terminal) or bails if cargo_compatible_accept is not set to auto.
Sources: src/executor.rs:341-382, src/config.rs:40-54
The Resolution Algorithm ensures that while Cargo's resolution logic is respected, the resulting dependency graph is filtered through security and stability policies defined by the user. By combining local backtracking with Cargo's own validator, it avoids generating invalid lockfiles while aggressively pursuing older, more "cooled" crate versions.
Sources: src/executor.rs:1255-1271, README.md:78-83