Skip to content

nix: pin nixpkgs in flake.lock, and make every entry point read it - #3

Open
alycda wants to merge 2 commits into
developfrom
nix/flake
Open

alycda wants to merge 2 commits into
developfrom
nix/flake

Conversation

@alycda

@alycda alycda commented Sep 15, 2026

Copy link
Copy Markdown
Owner

shell.nix said import <nixpkgs> {}: the same tool set for everyone, whatever versions each machine's channel held. One afternoon of building three tracks showed what that costs — R 4.5.3 in the container and 4.6.1 on the flake registry, Godot 4.6.3 and 4.7.2, gfortran 15.2 and 15.3, all "current nixpkgs" on the same day — so every version a README cites was true on exactly one machine.

flake.lock now names one revision, nixos-26.05 at c3eea5b2 (2026-09-14), and the pin reaches every door that goes through shell.nix:

nix develop            the workshop shell (five required tools)
nix develop .#full     plus every library the default-off features link
nix-shell              the same derivation — shell.nix reads flake.lock
nix-shell --arg full true, direnv's `use nix`, shell.nix in a devcontainer, CI

What the pin does not reach: the devcontainers' home-manager profiles. .devcontainer/*/home.nix takes pkgs from the container's own channel, which the nix feature sets and setup.sh leaves alone. That is a second nixpkgs, and it is why the wasm variant reads its wasm-bindgen-cli version out of days/Cargo.lock instead of trusting either. Pointing home-manager at this lock is the natural next step, not this PR.

shell.nix stays the single definition; flake.nix is a thin door onto it, and shell.nix's default nixpkgs is a fetchTarball of the locked revision with the lock's own narHash. Nothing that runs shell.nix had to change, and nothing needs flakes enabled — the devcontainer's nix has nix-command off and stays that way. .envrc watches the lock so nix flake update reaches direnv.

A release branch rather than unstable, on purpose: bumps become a diff someone reads. 26.05 carries what the tracks need — rustc past gdext's 1.94 floor, Godot 4.6 (the api-4-6 floor), R, gfortran, LAPACK.

Not taken: the earlier attempt on claude/flake-pinned-environment (six shells, nix/shells.nix, per-track floors by construction). Right shape, five weeks stale, and it moved the definition out of shell.nix. Per-track shells are the natural next commit on top of this one.

Verified

  • nix-instantiate shell.nix and nix eval .#devShells.<system>.default.drvPath name the same .drv; same for --arg full true against .#full.
  • nix flake check --no-build --all-systems passes, both darwin systems included.
  • nix develop opens the pinned shell (rustc 1.95.0, cargo 1.95.0, cbindgen 0.29.4, just 1.51.0); nix-shell --arg full true answers the ffi job's full pkg-config roll call with lapack, R 4.5.3 present.
  • CI on this branch: Rust and Verify both green, including the ffi job on macOS at the pin and the Fortran cell on macOS, previously unobserved.

🤖 Generated with Claude Code

shell.nix said `import <nixpkgs> {}`: the same tool set for everyone,
whatever versions each machine's channel held. The README owned it —
"versions are on you" — and one afternoon of building three tracks showed
what it costs: R 4.5.3 in this container and 4.6.1 on the flake registry,
Godot 4.6.3 and 4.7.2, gfortran 15.2 and 15.3, all "current nixpkgs" on the
same day, so every version a README cites was true on exactly one machine.

flake.lock now names one revision — nixos-26.05 at c3eea5b2 (2026-09-14) —
and the pin reaches every door:

    nix develop            the workshop shell (five required tools)
    nix develop .#full     plus every library the default-off features link
    nix-shell              the same derivation — shell.nix reads flake.lock
    nix-shell --arg full true, direnv's `use nix`, the devcontainers, CI

shell.nix stays the single definition; flake.nix is a thin door onto it,
and shell.nix's default `nixpkgs` is a fetchTarball of the locked revision
with the lock's own narHash. So nothing that runs shell.nix had to change,
and nothing needs flakes enabled — the devcontainer's nix has nix-command
off, and stays that way. `--arg nixpkgs` still overrides, and `nix flake
update` moves every path together. .envrc watches the lock so that bump
reaches direnv without touching shell.nix.

A release branch rather than unstable, on purpose: bumps become a diff
someone reads, and stable keeps them to fixes. 26.05 carries what the
tracks need — rustc past gdext's 1.94 floor, Godot 4.6 (the `api-4-6`
floor), R, gfortran, LAPACK.

Not taken: the earlier attempt on claude/flake-pinned-environment (six
shells, nix/shells.nix, per-track floors by construction). Right shape,
five weeks stale against a shell.nix that has since grown lapack and R,
and it moved the definition out of shell.nix — more to review than the
pin itself deserves. Per-track shells are the natural next commit on top
of this one; docs/flake-handoff.md on that branch still lists the seams.

Verified here (aarch64-linux): `nix-instantiate shell.nix` and `nix eval
.#devShells.<system>.default.drvPath` name the same .drv, and the same for
`--arg full true` against `.#full`; `nix flake check --no-build
--all-systems` passes, both darwin systems included; `nix develop` opens
the default shell at the pin (rustc 1.95.0, cargo 1.95.0, cbindgen 0.29.4,
just 1.51.0) and `nix-shell --arg full true` answers the ffi job's full
pkg-config roll call with lapack, and R 4.5.3, present. CI not run; its
ffi job will fetch the 26.05 closure instead of the unstable one, roughly
the same size.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@alycda
alycda marked this pull request as ready for review September 15, 2026 19:13
@alycda alycda self-assigned this Sep 15, 2026
The flake commit's comments and its PR read as if flake.lock governed the
devcontainers. It governs shell.nix inside them, and not the home-manager
profiles: .devcontainer/*/home.nix takes `pkgs` from the container's own
channel, which the nix feature sets and setup.sh leaves alone. That is a
second nixpkgs, and it is the whole lesson of the wasm variant's
wasm-bindgen-cli mismatch — which is why that variant reads its CLI version
out of days/Cargo.lock rather than trusting either.

shell.nix's header and flake.nix's now say so, and name the natural next
step (pointing home-manager at this lock) without taking it. A separate
commit rather than an amendment so the pushed commit under PR #3 stays the
commit CI verified, timestamps included.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant