Nixpkgs Multiverse can now summon an old Linux package without downloading or evaluating the Nixpkgs source tree that produced it. Ask for Python 3.8.9 through the project’s fast interface and Nix receives a known /nix/store path, attaches dependency context to the string, then asks the public binary cache for the object and its closure.
The shortcut works because NixOS kept two layers of history that were never presented as one archive: Hydra’s published store-path listings for channel revisions, and the binary objects still served by cache.nixos.org. Farid Zakaria’s Multiverse fast-mode release joins those records to an index of package attributes and versions. The result makes software from 2013 onward addressable through one flake.
the address was hiding in the build manifest
A normal Nix request starts with an expression. Nix evaluates that expression to derive a build recipe and its output path. If the exact output already exists in a trusted binary cache, the client substitutes it instead of compiling locally. Evaluation still happens because the client needs to learn the path.
Historical package selection makes that cost obvious. Multiverse’s regular path can locate the Nixpkgs revision that shipped a requested version, fetch that roughly 378 MB source tree, and evaluate it. The fast path already knows the answer.
Every nixos-unstable channel bump published a compressed store-paths.xz inventory of the paths Hydra built. Older releases used MANIFEST files. Multiverse’s store-path design matches package attributes and versions against those inventories, then records a concrete store path for each successful match.
The project does not treat a cache index response as proof that bytes remain available. Its census fetches each narinfo record and checks the NAR payload behind it. Zakaria reports that all 271,187 matched paths in the August 14 census were still alive, representing 14.8 TB unpacked. The repository’s broader version index currently lists more package-version records than that matched-path count; unfree, broken, wrapper, and otherwise unmatched entries still require the evaluation route.
That distinction matters. “Every version” describes the index’s search surface. Zero-evaluation substitution covers the subset with a matched, live cache object on x86_64-linux.
three lines turn memory into an installable
A bare string containing /nix/store/... does not automatically carry the meaning Nix needs. Nix strings can hold hidden context that identifies store dependencies. Interpolating a real derivation adds that context naturally. The builtins.appendContext function can add it directly.
Multiverse uses the technique developed in Tom Bereknyei’s independent fastpkgs project. It marks a known path as a store dependency, then wraps the contextual string in an attribute set shaped enough like a derivation for nix build and nix shell to accept its output.
The object is deliberately fake. It has no .drv file and no recipe to execute. It can request an existing cache object. It cannot rebuild one after the cache loses it, apply an override, or provide the full metadata of the original package. Multiverse attaches a lazy .eval escape hatch that resolves the real historical derivation when those operations are required.
This is a clean separation of jobs. Discovery comes from the Multiverse index. Fast retrieval comes from the store-path manifest and binary cache. Mutation and recovery return to source evaluation. Pretending those paths are interchangeable would produce a preservation fairy tale. They have different failure modes and different claims to authenticity.
Exact-version fast selectors are bit-exact because they point at the stored build selected for that version. Revision-shaped selectors carry a subtler promise. Multiverse records one digest per version, choosing the newest build of that version found in the historical listings. A revision query can therefore be version-exact while using a later, patched build of the same version. The project calls this build-canonical behavior and documents it rather than laundering the difference.
the cache inherited archival authority
Nix store paths are content-addressed enough to make retention unusually useful. The path names a fixed output, references identify the closure, cache signatures establish which substituter vouched for it, and clients can verify the received object. Those properties remove much of the ambiguity that ruins ordinary download archives.
They do not provide institutional permanence. Multiverse’s fast path rests on objects financed and retained by the NixOS Foundation and its sponsors. The project documentation says the public cache has never been garbage-collected. That operational choice gave thirteen years of package history a second life. A future retention policy, signing-key transition, storage failure, or budget cut could narrow the archive without changing a line of Multiverse code.
Multiverse has started treating liveness as changing state rather than inherited truth. A weekly workflow repeats the payload census and removes dead entries from advertised artifacts. Data releases are pinned by hash. Old shards remain immutable by convention, while a rolling release carries cache-health data that consumers should not pin. This is package infrastructure behaving like an archive catalog with a circulation desk.
The arrangement also exposes the cost of convenience. The public cache is an append-only cultural asset because somebody keeps paying its storage and transfer bill. Users get a one-command route to vanished package versions. Maintainers inherit a growing preservation obligation that was absent from the original binary-distribution pitch.
software preservation needs executable addresses
Traditional preservation often saves source snapshots and declares victory. Source is essential, but old software lives inside a larger machine: compilers, dependencies, generated assets, patch sets, build flags, platform assumptions, and distribution metadata. Reconstructing that machine years later can become the entire project.
Nixpkgs Multiverse demonstrates another layer of custody. Keep the source history. Keep the derivations. Keep the exact built outputs. Keep the manifests that connect human package names and versions to immutable machine addresses. Then maintain an interface that can choose the honest route: direct substitution when the artifact survives, full evaluation when a real derivation is needed.
The clever code is tiny. The archive behind it took thirteen years of continuous build infrastructure, storage, signatures, and accidental restraint. That imbalance is the point. Software history becomes usable when preservation is embedded in distribution long before anybody calls it preservation.