chore(nix): bump the nixpkgs flake input — go_1_26 1.26.4 → 1.26.5 (GO-2026-4970, GO-2026-5856), lock is 4 weeks stale [schedule: Daily agent update check] #257

Closed
opened 2026-08-02 04:13:37 +02:00 by dominik.polakovics · 0 comments

Goal

Move the nixpkgs flake input forward. It has been locked since 2026-07-05 and the Go toolchain it ships (go_1_26) is one patch release behind, inside two stdlib security advisories. This is a nix flake update nixpkgs plus the two documentation lines that record the pin — no code changes expected.

docs/ops.md:86 states the process this issue is executing:

nixpkgs pin: the flake input must ship go_1_26. Currently github:NixOS/nixpkgs/nixos-unstable, locked at d407951447dcd00442e97087bf374aad70c04cea. Record pin changes here.

Evidence — what is behind

flake.lock, the single input:

"nixpkgs": {
  "lastModified": 1783224372,          // 2026-07-05T04:06:12Z
  "narHash": "sha256-8i/87eeoqiGE4yOTjwSA3Eh/ziJRQEmd/unYU+K27sk=",
  "owner": "NixOS", "repo": "nixpkgs", "type": "github",
  "rev": "d407951447dcd00442e97087bf374aad70c04cea"
}

nixos-unstable was at 148bab9c1c3c53136ecb44a6ea356a0ed5b39b06 (2026-08-01) when this was checked — take whatever the branch head is when you run it, the rev is not the point.

What actually moves, verified by reading the two trees directly:

nixpkgs attr d407951447dc (locked) nixos-unstable head Effect here
go_1_26 1.26.4 1.26.5 the toolchain nix/package.nix:21 builds lab + labctl with
golangci-lint 2.12.2 2.12.2 (unchanged) CI pin stays valid — see below
nodejs (nodejs_24) 24 24 (unchanged) CI pin stays valid — see below
pkgs/development/compilers/go/1.26.nix    @ d407951447dc → version = "1.26.4"
                                          @ master       → version = "1.26.5"
pkgs/by-name/go/golangci-lint/package.nix @ both         → version = "2.12.2"
pkgs/top-level/all-packages.nix           @ both         → nodejs = nodejs_24

Security — the reason this is worth doing now, stated honestly

Go 1.26.5 fixes two stdlib advisories that go_1_26 = 1.26.4 is inside. Both were checked against vuln.go.dev:

GO-2026-4970  Root escape via symlink plus trailing slash in os
  stdlib  affected: [1.26.0-0, 1.26.5)   fixed: 1.26.5   package: os

GO-2026-5856  Invoking Encrypted Client Hello privacy leak in crypto/tls
  stdlib  affected: [1.26.0-0, 1.26.5)   fixed: 1.26.5   package: crypto/tls

Every lab and labctl binary this flake builds — including the ones the deploy ships — currently carries a 1.26.4 stdlib.

Neither advisory appears reachable from this repo's own code, and that should be said plainly rather than dressed up:

  • GO-2026-4970 is in os.Root (the os.OpenRoot sandboxed-directory API). grep -rn 'os\.Root\|OpenRoot' --include=*.go internal/ cmd/ returns nothing — this repo does not use that API anywhere.
  • GO-2026-5856 requires the caller to invoke Encrypted Client Hello (an opt-in tls.Config.EncryptedClientHelloConfigList). grep -rn 'crypto/tls\|EncryptedClientHello\|ECHConfig' --include=*.go internal/ cmd/ returns nothing — nothing here imports crypto/tls directly, and nothing configures ECH.

So this is toolchain hygiene with an advisory attached, not an incident. It is still worth landing: the change is a one-line lock move, it keeps the toolchain on the current patch so the next stdlib advisory does not find us two releases behind, and govulncheck output stops carrying stdlib findings that have to be re-triaged by hand on every sweep.

What does NOT move — checked so you do not have to re-derive it

docs/ops.md:307 and .forgejo/workflows/ci.yml:15-19 pin the native gate's toolchain to "nixpkgs at the current flake.lock". Those pins are the usual reason a nixpkgs bump ripples into CI. Both are unchanged across this bump (table above), so:

  • .forgejo/workflows/ci.yml:49-53node-version: "24" stays.
  • .forgejo/workflows/ci.yml:80-89golangci-lint v2.12.2 stays (three places: the comment, the install-script URL, the -b … v2.12.2 argument).
  • docs/ops.md:307 — the "Node 24 …, golangci-lint 2.12.2" sentence stays.

If your flake.lock update lands on a rev where either has moved, update all of the above in the same commit and say so in the PR — do not leave the comments claiming a version nixpkgs no longer ships.

nix/package.nix's vendorHash is a function of go.mod/go.sum, not of nixpkgs, so it does not change here. importNpmLock derives per-package fetches from web/package-lock.json directly (nix/package.nix:67-75) — there is no npmDepsHash to refresh either.

Scope

Path Change
flake.lock the nixpkgs node, via nix flake update nixpkgsdo not hand-edit
docs/ops.md:86 the recorded rev in the nixpkgs pin paragraph, per its own "Record pin changes here" instruction
docs/ops.md:307, .forgejo/workflows/ci.yml only if golangci-lint or nodejs moved on the rev you land — expected: no change

Nothing under internal/, cmd/, or web/. flake.nix itself does not change: the input stays github:NixOS/nixpkgs/nixos-unstable.

Where this can actually break — check before assuming it is a one-liner

nix flake check is the whole gate and it is broader than the Go build. A nixpkgs bump moves everything the checks evaluate, not just the toolchain:

  • nixos-container-closure builds a container-enabled dummy NixOS system's full toplevel (flake.nix, checks). podman, crun, passt, and systemd all move with nixpkgs, and ADR-0058/0059/0060 make lab's cgroup and user@ manager layout sensitive to systemd behaviour. A closure that stops building, or a nixos-module check whose grepped unit text has shifted, is the realistic failure mode.
  • The lab derivation runs the full go test ./... as its checkPhase with real git/tmux/prlimit from nixpkgs in nativeCheckInputs. A moved git or tmux can surface as a test failure that is not about the toolchain at all.

If either breaks, report it here with the actual error rather than pinning around it or loosening a check. A nixpkgs bump that needs a code change is a finding, not a chore.

How to verify

nix flake update nixpkgs
git diff flake.lock                              # exactly one node changed: nixpkgs

nix eval --raw nixpkgs#go_1_26.version           # must be >= 1.26.5
nix eval --raw nixpkgs#golangci-lint.version     # expect 2.12.2 — if not, update ci.yml + ops.md
nix eval --raw nixpkgs#nodejs.version            # expect 24.x  — if not, update ci.yml + ops.md

nix flake check                                  # the authoritative gate: builds lab/labctl/web,
                                                 # runs the Go + vitest suites, golangci-lint,
                                                 # the nixos-module eval and the container closure
nix build .#lab .#labctl .#web

Optional but useful evidence for the PR body, if a Go toolchain is available:

go run golang.org/x/vuln/cmd/govulncheck@latest ./...   # should be clean either way (see Security)

Done means

  • flake.lock's nixpkgs node points at a nixos-unstable rev whose go_1_26 is 1.26.5 or newer — confirmed with nix eval --raw nixpkgs#go_1_26.version, and the value quoted in the PR body.
  • flake.lock was regenerated by nix flake update nixpkgs, not edited by hand; the diff touches only that node.
  • docs/ops.md:86 records the new rev (its own instruction).
  • nix flake check passes — including nixos-module and nixos-container-closure.
  • .forgejo/workflows/ci.yml's golangci-lint and Node pins either still match nixpkgs at the new rev (expected) or were updated in the same commit, with docs/ops.md:307 kept in step.
  • No changes under internal/, cmd/, or web/. If one was needed, it is explained on this issue.
  • PR body says Closes #<this issue> and names the old and new revs plus the go_1_26 version delta.

Out of scope

  • Go module dependencies (go.mod/go.sum) — that is #250, which explicitly parks the flake input as "a separate, ops-facing decision". This issue is that decision; the two touch disjoint files (flake.lock here, go.mod/go.sum/vendorHash there) and can land in either order.
  • The go 1.26 language pin in go.mod. Go 1.27 is at rc2 and is not stable; the flake input must keep shipping go_1_26 (flake.nix:6-8, nix/package.nix:19-21). Do not touch either.
  • services.lab.agentPackages and the agent CLI versions in nixpkgs. pkgs.claude-code / pkgs.codex resolve against the deploying host's nixpkgs (Cloonar/nixos), not this flake's — this repo's nix flake check nulls both agent packages so no agent CLI ever enters its closures (flake.nix, containerDummy). Nothing about the agent-tools pins changes here; those live in containers/agent-tools/versions.env and move on #249.
  • Pinning the input to a release channel (nixos-25.11) instead of nixos-unstable. That is a real question — unstable is why this needs periodic bumping at all — but it is a maintainer decision, not this chore.

Filed by the Daily agent update check schedule, 2026-08-02. Toolchain versions read from pkgs/development/compilers/go/1.26.nix, pkgs/by-name/go/golangci-lint/package.nix, and pkgs/top-level/all-packages.nix at both revs; advisory data from vuln.go.dev/ID/GO-2026-4970.json and GO-2026-5856.json; reachability from grep over internal/ and cmd/. No nix, Go, or Node toolchain was available in the investigating environment, so nothing here was built — every claim is source-level and re-checkable.

## Goal Move the `nixpkgs` flake input forward. It has been locked since **2026-07-05** and the Go toolchain it ships (`go_1_26`) is one patch release behind, inside two stdlib security advisories. This is a `nix flake update nixpkgs` plus the two documentation lines that record the pin — no code changes expected. `docs/ops.md:86` states the process this issue is executing: > **nixpkgs pin**: the flake input must ship `go_1_26`. Currently `github:NixOS/nixpkgs/nixos-unstable`, locked at `d407951447dcd00442e97087bf374aad70c04cea`. **Record pin changes here.** ## Evidence — what is behind `flake.lock`, the single input: ```json "nixpkgs": { "lastModified": 1783224372, // 2026-07-05T04:06:12Z "narHash": "sha256-8i/87eeoqiGE4yOTjwSA3Eh/ziJRQEmd/unYU+K27sk=", "owner": "NixOS", "repo": "nixpkgs", "type": "github", "rev": "d407951447dcd00442e97087bf374aad70c04cea" } ``` `nixos-unstable` was at `148bab9c1c3c53136ecb44a6ea356a0ed5b39b06` (2026-08-01) when this was checked — take whatever the branch head is when you run it, the rev is not the point. What actually moves, verified by reading the two trees directly: | nixpkgs attr | `d407951447dc` (locked) | `nixos-unstable` head | Effect here | |---|---|---|---| | `go_1_26` | **1.26.4** | **1.26.5** | the toolchain `nix/package.nix:21` builds `lab` + `labctl` with | | `golangci-lint` | 2.12.2 | **2.12.2 (unchanged)** | CI pin stays valid — see below | | `nodejs` (`nodejs_24`) | 24 | **24 (unchanged)** | CI pin stays valid — see below | ``` pkgs/development/compilers/go/1.26.nix @ d407951447dc → version = "1.26.4" @ master → version = "1.26.5" pkgs/by-name/go/golangci-lint/package.nix @ both → version = "2.12.2" pkgs/top-level/all-packages.nix @ both → nodejs = nodejs_24 ``` ## Security — the reason this is worth doing now, stated honestly Go 1.26.5 fixes two stdlib advisories that `go_1_26 = 1.26.4` is inside. Both were checked against `vuln.go.dev`: ``` GO-2026-4970 Root escape via symlink plus trailing slash in os stdlib affected: [1.26.0-0, 1.26.5) fixed: 1.26.5 package: os GO-2026-5856 Invoking Encrypted Client Hello privacy leak in crypto/tls stdlib affected: [1.26.0-0, 1.26.5) fixed: 1.26.5 package: crypto/tls ``` Every `lab` and `labctl` binary this flake builds — including the ones the deploy ships — currently carries a 1.26.4 stdlib. **Neither advisory appears reachable from this repo's own code, and that should be said plainly rather than dressed up:** - `GO-2026-4970` is in `os.Root` (the `os.OpenRoot` sandboxed-directory API). `grep -rn 'os\.Root\|OpenRoot' --include=*.go internal/ cmd/` returns **nothing** — this repo does not use that API anywhere. - `GO-2026-5856` requires the caller to *invoke* Encrypted Client Hello (an opt-in `tls.Config.EncryptedClientHelloConfigList`). `grep -rn 'crypto/tls\|EncryptedClientHello\|ECHConfig' --include=*.go internal/ cmd/` returns **nothing** — nothing here imports `crypto/tls` directly, and nothing configures ECH. So this is toolchain hygiene with an advisory attached, not an incident. It is still worth landing: the change is a one-line lock move, it keeps the toolchain on the current patch so the *next* stdlib advisory does not find us two releases behind, and `govulncheck` output stops carrying stdlib findings that have to be re-triaged by hand on every sweep. ## What does NOT move — checked so you do not have to re-derive it `docs/ops.md:307` and `.forgejo/workflows/ci.yml:15-19` pin the native gate's toolchain to *"nixpkgs at the current flake.lock"*. Those pins are the usual reason a nixpkgs bump ripples into CI. **Both are unchanged across this bump** (table above), so: - `.forgejo/workflows/ci.yml:49-53` — `node-version: "24"` stays. - `.forgejo/workflows/ci.yml:80-89` — `golangci-lint v2.12.2` stays (three places: the comment, the install-script URL, the `-b … v2.12.2` argument). - `docs/ops.md:307` — the "Node 24 …, golangci-lint 2.12.2" sentence stays. If your `flake.lock` update lands on a rev where either has moved, update all of the above in the same commit and say so in the PR — do not leave the comments claiming a version nixpkgs no longer ships. `nix/package.nix`'s `vendorHash` is a function of `go.mod`/`go.sum`, not of nixpkgs, so it does **not** change here. `importNpmLock` derives per-package fetches from `web/package-lock.json` directly (`nix/package.nix:67-75`) — there is no `npmDepsHash` to refresh either. ## Scope | Path | Change | |---|---| | `flake.lock` | the `nixpkgs` node, via `nix flake update nixpkgs` — **do not hand-edit** | | `docs/ops.md:86` | the recorded rev in the **nixpkgs pin** paragraph, per its own "Record pin changes here" instruction | | `docs/ops.md:307`, `.forgejo/workflows/ci.yml` | **only if** golangci-lint or nodejs moved on the rev you land — expected: no change | Nothing under `internal/`, `cmd/`, or `web/`. `flake.nix` itself does not change: the input stays `github:NixOS/nixpkgs/nixos-unstable`. ## Where this can actually break — check before assuming it is a one-liner `nix flake check` is the whole gate and it is broader than the Go build. A nixpkgs bump moves everything the checks evaluate, not just the toolchain: - `nixos-container-closure` builds a container-enabled dummy NixOS system's **full toplevel** (`flake.nix`, `checks`). podman, crun, passt, and systemd all move with nixpkgs, and ADR-0058/0059/0060 make lab's cgroup and `user@` manager layout sensitive to systemd behaviour. A closure that stops building, or a `nixos-module` check whose grepped unit text has shifted, is the realistic failure mode. - The `lab` derivation runs the full `go test ./...` as its `checkPhase` with real git/tmux/prlimit from nixpkgs in `nativeCheckInputs`. A moved `git` or `tmux` can surface as a test failure that is not about the toolchain at all. If either breaks, **report it here with the actual error** rather than pinning around it or loosening a check. A nixpkgs bump that needs a code change is a finding, not a chore. ## How to verify ```sh nix flake update nixpkgs git diff flake.lock # exactly one node changed: nixpkgs nix eval --raw nixpkgs#go_1_26.version # must be >= 1.26.5 nix eval --raw nixpkgs#golangci-lint.version # expect 2.12.2 — if not, update ci.yml + ops.md nix eval --raw nixpkgs#nodejs.version # expect 24.x — if not, update ci.yml + ops.md nix flake check # the authoritative gate: builds lab/labctl/web, # runs the Go + vitest suites, golangci-lint, # the nixos-module eval and the container closure nix build .#lab .#labctl .#web ``` Optional but useful evidence for the PR body, if a Go toolchain is available: ```sh go run golang.org/x/vuln/cmd/govulncheck@latest ./... # should be clean either way (see Security) ``` ## Done means - [ ] `flake.lock`'s `nixpkgs` node points at a `nixos-unstable` rev whose `go_1_26` is **1.26.5 or newer** — confirmed with `nix eval --raw nixpkgs#go_1_26.version`, and the value quoted in the PR body. - [ ] `flake.lock` was regenerated by `nix flake update nixpkgs`, not edited by hand; the diff touches only that node. - [ ] `docs/ops.md:86` records the new rev (its own instruction). - [ ] `nix flake check` passes — including `nixos-module` and `nixos-container-closure`. - [ ] `.forgejo/workflows/ci.yml`'s golangci-lint and Node pins either still match nixpkgs at the new rev (expected) or were updated in the same commit, with `docs/ops.md:307` kept in step. - [ ] No changes under `internal/`, `cmd/`, or `web/`. If one was needed, it is explained on this issue. - [ ] PR body says `Closes #<this issue>` and names the old and new revs plus the `go_1_26` version delta. ## Out of scope - **Go module dependencies** (`go.mod`/`go.sum`) — that is #250, which explicitly parks the flake input as "a separate, ops-facing decision". This issue is that decision; the two touch disjoint files (`flake.lock` here, `go.mod`/`go.sum`/`vendorHash` there) and can land in either order. - **The `go 1.26` language pin in `go.mod`.** Go 1.27 is at rc2 and is not stable; the flake input must keep shipping `go_1_26` (`flake.nix:6-8`, `nix/package.nix:19-21`). Do not touch either. - **`services.lab.agentPackages` and the agent CLI versions in nixpkgs.** `pkgs.claude-code` / `pkgs.codex` resolve against the *deploying host's* nixpkgs (`Cloonar/nixos`), not this flake's — this repo's `nix flake check` nulls both agent packages so no agent CLI ever enters its closures (`flake.nix`, `containerDummy`). Nothing about the agent-tools pins changes here; those live in `containers/agent-tools/versions.env` and move on #249. - Pinning the input to a release channel (`nixos-25.11`) instead of `nixos-unstable`. That is a real question — unstable is why this needs periodic bumping at all — but it is a maintainer decision, not this chore. --- *Filed by the Daily agent update check schedule, 2026-08-02. Toolchain versions read from `pkgs/development/compilers/go/1.26.nix`, `pkgs/by-name/go/golangci-lint/package.nix`, and `pkgs/top-level/all-packages.nix` at both revs; advisory data from `vuln.go.dev/ID/GO-2026-4970.json` and `GO-2026-5856.json`; reachability from `grep` over `internal/` and `cmd/`. No nix, Go, or Node toolchain was available in the investigating environment, so nothing here was built — every claim is source-level and re-checkable.*
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Cloonar/coding-lab#257
No description provided.