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:

  1. Reads horus.toml (your dependency declarations)
  2. Reads horus.lock (pinned versions) — creates it if missing
  3. Checks toolchain versions (Rust, Python) and warns on mismatches
  4. Checks system dependencies via pkg-config and suggests install commands
  5. Installs language packages (crates.io, PyPI, registry)
  6. 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

SectionPurpose
versionSchema version (currently 4)
config_hashSHA-256 of horus.toml for staleness detection
[toolchain]Pinned Rust/Python/CMake versions
featuresActive 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.lock v3 files (packages only) are still readable
  • Missing sections ([toolchain], [[system]], features) default to empty
  • On the next horus lock or horus build, the file is upgraded to v4

Best Practices

  1. Commit horus.lock to git — this is the reproducibility mechanism
  2. Don't edit horus.lock manually — use horus lock to regenerate
  3. Run horus lock --check in CI — catch dependency drift early
  4. Update lockfile when adding depshorus add + horus build updates it automatically