User Guide¶
1. Who This Is For¶
| You… | The problem | What UDR does |
|---|---|---|
| Run a multi-language monorepo | pip + npm + cargo + go — each its own lock file, its own audit tool, its own version scheme. The same dep pinned to different versions across ecosystems? No tool catches it. | One udr.lock across all ecosystems. udr lock --check in CI catches cross-ecosystem version drift before prod. |
| Deploy ML models with GPU deps | torch + CUDA toolkit + nvidia-* wheels — wrong variant means silent CPU fallback or crash. | Auto-detects CUDA version, selects correct torch+cu121 variant. CUDA 11-vs-12 conflict rules prevent incompatible pairs. |
| Own supply chain compliance | Quarterly audits = run pip-audit + npm audit + cargo audit separately. |
udr check --cve against OSV across 18 ecosystems at once. udr sbom for SPDX/CycloneDX. Done. |
2. Introduction¶
Universal Dependency Resolver (UDR) is a cross-ecosystem dependency resolution tool. It resolves, locks, and exports dependencies across 25 package ecosystems (18 resolvable + 7 query-only) using SAT solvers (Z3 or PubGrub) that find compatible versions even across ecosystem boundaries.
Your project pulls in packages from everywhere — Python scripts call Node services, Docker images need both pip and apt packages. Existing tools only work within one ecosystem. Cross-ecosystem conflicts go undetected until something breaks at runtime.
UDR fixes that.
3. Quick Start¶
# Install
pip install ud-resolver
# Auto-detect manifests in current directory, lock everything
udr lock
# Check for CVEs
udr check --cve
# See the dependency tree
udr graph
# Generate SBOM
udr sbom
That's it. udr lock auto-detects your dependency files (requirements.txt, package.json, Cargo.toml, go.mod, etc.), resolves all constraints across ecosystems into a single udr.lock, and writes the result.
4. How It Works¶
flowchart LR
A["1. Manifest Detection<br/>46+ file patterns<br/>single rglob(*) pass"] --> B
B["2. Metadata Fetch<br/>async HTTP registries<br/>ETag cache + SHA256"] --> C
C["3. System Scan<br/>OS · CPU · GPU · CUDA<br/>runtimes · accelerators"] --> D
D["4. BFS Graph Building<br/>cross-ecosystem edges<br/>up to 10 levels deep"] --> E
E["5. SAT Resolution<br/>Z3 / PubGrub<br/>per-eco isolation"] --> F
F["6. Lock File<br/>udr.lock with versions<br/>hashes · deprecation · signature"]
style A fill:#1565c0,color:#fff
style B fill:#e65100,color:#fff
style C fill:#2e7d32,color:#fff
style D fill:#6a1b9a,color:#fff
style E fill:#c62828,color:#fff
style F fill:#00695c,color:#fff
The resolution pipeline¶
- Manifest detection — Recognizes 90+ file patterns (package.json, pyproject.toml, setup.py, Cargo.toml, go.mod, Gemfile, etc.). Scans directory tree efficiently with a single
rglob("*")pass. - Metadata fetch — Fetches versions and dependencies from registries (PyPI, npmjs.org, crates.io, etc.) using async HTTP with connection pooling. Cached locally (DictCache TTL 1h, ContentAddressedCache by SHA256).
- System scan — Detects OS/kernel, CPU model/cores, GPU model/VRAM, CUDA version, runtimes (Python, Node.js, Java, GCC), accelerators (TPU, NPU, Apple Neural Engine).
- BFS graph building — Builds the full transitive dependency graph across all ecosystems. Cross-ecosystem edges are tracked and resolved in a unified SAT model.
- SAT resolution — Z3 (default) or PubGrub (opt-in) solver finds a set of mutually compatible versions. If the graph is large, packages are grouped by ecosystem for independent resolution before cross-ecosystem unification.
- Lock file —
udr.lockcontains all resolved versions, system snapshot, integrity hashes, deprecation flags, and optional Ed25519 signature.
5. Key Concepts¶
Cross-ecosystem resolution¶
UDR is the only tool that resolves dependencies across ecosystem boundaries. A Python package depending on a Node.js package through a system call? UDR tracks that edge and ensures version compatibility across both ecosystems.
SAT solver (Z3 / PubGrub)¶
Finding compatible versions across multiple packages with overlapping constraints is a SAT problem. UDR supports two backends:
- Z3 (default) — Industrial-strength SMT solver. Handles CUDA XOR constraints, cross-eco variable encoding.
- PubGrub (opt-in via USE_PUBGRUB_SOLVER=true) — CDCL algorithm designed for dependency resolution. Can be faster on pure version-constraint graphs.
Both backends use the same input format and produce the same output. If the primary solver fails, the alternate solver runs for cross-validation.
GPU-aware resolution¶
For PyPI packages with CUDA-tagged variants (e.g. torch 2.1.2+cu121, torch 2.1.2+cu118), UDR auto-detects the system CUDA version and selects the best match. On CPU-only machines, use --cuda 12.1 to force CUDA-aware resolution.
Supply chain features¶
- CVE scanning: Queries OSV database for all packages in the lock file — 18 ecosystems supported.
- SBOM generation: SPDX 2.3 or CycloneDX 1.5 output.
- Lock file signing: Ed25519 signatures with auto-generated key pairs.
- SLSA provenance: Build metadata tracked in lock file.
- Policy engine: YAML-based rules (no-deprecated, no-gpl, max-vulnerabilities, etc.).
6. Workflows¶
Daily development¶
# Lock dependencies
udr lock
# Check for CVEs before committing
udr check --cve
# Update a package
udr update flask
# Bulk-update every direct package to its newest compatible version
udr update --all
# See why a specific version was chosen
udr why flask
# Render the dependency tree from the lock file (offline)
udr graph --from-lock
CI/CD¶
# Drift check — exits 1 if lock file is stale
udr lock --check
# Full CVE scan
udr check --cve
# Generate SBOM for artifact
udr sbom --format spdx --output sbom.json
Cross-compilation¶
# Resolve for a different target
udr lock --target linux --platform arm64
# With specific CUDA version
udr lock --cuda 12.1 --target linux --platform x86_64
Vulnerability fix¶
# Fix all vulnerable packages to minimum fixed versions
udr update --fix-cve
# Fix a specific package
udr update flask --fix-cve
7. Python Library Usage¶
import asyncio
from backend.core.data_aggregator import DataAggregator
from backend.orchestrator import create_solver
from backend.core.system_scanner import SystemScanner
async def main():
scanner = SystemScanner()
system_info = await scanner.scan_all()
aggregator = DataAggregator()
info = await aggregator.get_package_info(
"torch", ecosystem="pypi",
include_dependencies=True, include_versions=True,
)
resolver = create_solver()
result = resolver.resolve_dependencies(
packages=[{"name": "flask", "version": ">=2.0"}],
system_info=system_info,
)
asyncio.run(main())
See SDK Roadmap for upcoming Python SDK features (vulnerability checking, license checking, SBOM generation).
8. Where to Go Next¶
| Resource | What it covers |
|---|---|
| CLI Reference | All 26 commands with flags, examples, and exit codes |
| API Reference | 59 REST endpoints with request/response schemas |
| Architecture | Codebase structure, layers, design decisions |
| Components | CLI vs Desktop vs Library comparison |
| Development | Setup, testing, project structure |
| Deployment | Production deployment guide |
| Performance | SAT solver benchmarks, caching, optimization tips |
| Desktop | Desktop app build and usage (17 tabs) |
| Troubleshooting | Common issues and solutions (432 lines) |
| API Integration | Third-party integration guide |
| FAQ | Frequently asked questions (12 items) |
| SDK Roadmap | Python SDK and future plans |