Designing a Package Manager
lpm is the Lateralus package manager. Content-addressed, SHA-256 verified, reproducible builds.
The manifest
Every Lateralus project starts with lateralus.toml:
[package]
name = "my-app"
version = "1.0.0"
edition = "2025"
[dependencies]
ltl-http = "0.8"
ltl-json = "1.2"
ltl-cli = "0.5"
[dev-dependencies]
ltl-test = "1.0"
ltl-bench = "0.3"
[build]
target = "native"
optimize = "release"
Dependency resolution
lpm uses a SAT solver for version resolution. It finds the newest compatible set of packages that satisfies all constraints. Conflicts produce clear error messages showing the dependency chain.
Content-addressed storage
Every package version is stored by its SHA-256 hash. If two projects depend on the same version, it's stored once. The global cache lives at ~/.lpm/cache/.
Lockfiles
lateralus.lock records the exact resolved versions and hashes. Checking it into version control guarantees reproducible builds across machines.
Commands
lpm new my-project # Create project scaffold
lpm add ltl-http # Add dependency
lpm install # Install all dependencies
lpm build # Compile the project
lpm test # Run tests
lpm publish # Publish to registry
Registry architecture
The Lateralus package registry is a simple, transparent system. Every package is a tarball of source code plus a lateralus.toml manifest. The registry stores:
- Metadata index — a JSON file per package listing all versions, dependencies, and checksums. The full index is ~2 MB and cached locally.
- Source tarballs — stored in a content-addressed blob store, keyed by SHA-256. Immutable once published.
- Signatures — every package is signed with the author's GPG key.
lpmverifies signatures on install.
There's no binary distribution. Every install compiles from source, which means reproducible builds and no architecture-specific packages. The C99 backend compiles fast enough that this is practical.
Dependency resolution in depth
The SAT solver handles some tricky cases that simpler resolvers can't:
# Scenario: diamond dependency
# my-app depends on ltl-http 0.8 and ltl-auth 1.0
# ltl-http 0.8 depends on ltl-json 1.2
# ltl-auth 1.0 depends on ltl-json 1.1
$ lpm install
Resolving dependencies...
ltl-json: 1.2 satisfies both >=1.1 and >=1.2 ✓
Installing ltl-json 1.2.3
Installing ltl-http 0.8.1
Installing ltl-auth 1.0.2
Installing my-app 1.0.0
4 packages installed in 2.3s
When resolution fails, the error message shows the full dependency chain so you can see exactly why two requirements conflict:
$ lpm install
Error: version conflict for ltl-json
my-app 1.0.0 -> ltl-http 0.9.0 -> ltl-json >=2.0
my-app 1.0.0 -> ltl-auth 1.0.0 -> ltl-json <2.0
No version of ltl-json satisfies both constraints.
Suggestion: upgrade ltl-auth to >=1.1 which supports ltl-json 2.x
Workspaces
Large projects can use workspaces to manage multiple packages in a single repository:
# lateralus.toml (workspace root)
[workspace]
members = [
"core",
"cli",
"server",
"shared",
]
[workspace.dependencies]
ltl-json = "1.2" # Shared version across all members
ltl-log = "0.5"
Each member has its own lateralus.toml but can reference workspace-level dependency versions. This eliminates version drift between packages in the same repo.
Security features
After studying supply chain attacks on npm, PyPI, and crates.io, we built several defenses into lpm:
- Typosquatting detection — publishing a package with a name similar to an existing popular package triggers manual review
- Mandatory 2FA — package authors must enable two-factor authentication before publishing
- Immutable versions — once a version is published, it cannot be modified or deleted (only yanked with a warning)
- Audit log —
lpm auditchecks all dependencies against a vulnerability database and reports known CVEs - Build sandboxing — build scripts run in a restricted environment with no network access and limited filesystem access