Lockfile & Reproducibility
horus.lock is the single file that ensures every machine builds with identical dependencies. It pins exact versions for packages, toolchains, and system libraries.
horus.toml → what you WANT (version ranges, declarative)
horus.lock → what you GOT (exact pins, reproducible)
This is the same pattern as Cargo.lock, package-lock.json, or uv.lock.
How It Works
# First build: resolves dependencies, creates horus.lock
horus build
# Subsequent builds: uses pinned versions from horus.lock
horus build
# Teammate clones repo, gets identical deps
git clone <repo> && cd <repo> && horus build
horus build handles everything:
- Reads
horus.toml(your dependency declarations) - Reads
horus.lock(pinned versions) — creates it if missing - Checks toolchain versions (Rust, Python) and warns on mismatches
- Checks system dependencies via
pkg-configand suggests install commands - Installs language packages (crates.io, PyPI, registry)
- Compiles the project
The Lockfile Format (v4)
version = 4
config_hash = "sha256:a1b2c3..."
[toolchain]
rust = "1.78.0"
python = "3.12.3"
features = ["monitor"]
[[package]]
name = "horus_library"
version = "0.1.9"
source = "registry"
checksum = "sha256:abc..."
[[package]]
name = "serde"
version = "1.0.215"
source = "crates.io"
checksum = "sha256:def..."
[[package]]
name = "numpy"
version = "1.26.4"
source = "pypi"
[[system]]
name = "opencv"
version = "4.8.1"
pkg_config = "opencv4"
apt = "libopencv-dev"
brew = "opencv"
pacman = "opencv"
Sections
| Section | Purpose |
|---|---|
version | Schema version (currently 4) |
config_hash | SHA-256 of horus.toml for staleness detection |
[toolchain] | Pinned Rust/Python/CMake versions |
features | Active feature flags at lock time |
[[package]] | Pinned package versions (registry, crates.io, PyPI) |
[[system]] | System dependencies with cross-platform package names |
Cross-Platform System Dependencies
Each [[system]] entry includes package names for multiple platforms:
[[system]]
name = "opencv"
version = "4.8.1"
pkg_config = "opencv4" # How to detect (cross-platform)
apt = "libopencv-dev" # Debian/Ubuntu
brew = "opencv" # macOS (Homebrew)
pacman = "opencv" # Arch Linux
choco = "opencv" # Windows (Chocolatey)
When horus build detects a missing system dependency, it prints the correct install command for your platform:
# On Ubuntu:
✗ opencv — install with: sudo apt install -y libopencv-dev
# On macOS:
✗ opencv — install with: brew install opencv
# On Arch:
✗ opencv — install with: sudo pacman -S opencv
Commands
horus lock
Regenerate horus.lock from horus.toml:
horus lock
# [✓] Generated horus.lock v4 (12 packages)
horus lock --check
Verify the lockfile is valid and check system dependencies:
horus lock --check
# [✓] horus.lock v4 is valid (12 packages, 2 system deps)
# ⚠ Rust version mismatch: lockfile pins 1.78.0, you have 1.79.0
# ✗ opencv — install with: sudo apt install -y libopencv-dev
horus build
Build the project. Automatically verifies the lockfile first:
horus build
# Lockfile verification:
# ⚠ Python version mismatch: lockfile pins 3.12.3, you have 3.11.0
# [i] Building project in debug mode...
Workflows
Team Development
# Developer A: adds a dependency
horus add numpy --source pypi
horus build # updates horus.lock
git add horus.toml horus.lock
git commit -m "add numpy dependency"
git push
# Developer B: gets identical deps
git pull
horus build # reads horus.lock, installs exact versions
Robot Deployment
# On dev machine:
horus build --release
scp -r . robot@192.168.1.5:~/project/
# On robot:
cd ~/project
horus build --release # horus.lock ensures identical deps
CI/CD
steps:
- uses: actions/checkout@v4
- name: Install horus
run: curl -sSf https://horusrobotics.dev/install.sh | sh
- name: Build
run: horus build --release
- name: Test
run: horus test
The lockfile in the repo ensures CI builds match local builds exactly.
Version Checking
The [toolchain] section records which Rust/Python versions were used when the lockfile was generated. On horus build, version mismatches produce warnings (not errors):
- Same major.minor (e.g., 1.78.0 vs 1.78.5): no warning
- Different minor (e.g., 1.78.0 vs 1.79.0): warning printed
- Different major (e.g., 3.12 vs 2.7): warning printed
Warnings don't block the build — they inform you that behavior may differ.
Backward Compatibility
horus.lockv3 files (packages only) are still readable- Missing sections (
[toolchain],[[system]],features) default to empty - On the next
horus lockorhorus build, the file is upgraded to v4
Best Practices
- Commit
horus.lockto git — this is the reproducibility mechanism - Don't edit
horus.lockmanually — usehorus lockto regenerate - Run
horus lock --checkin CI — catch dependency drift early - Update lockfile when adding deps —
horus add+horus buildupdates it automatically