nodwyn.

ADR 0033: Go 1.26 is the base

  • Status: accepted
  • Date: 2026-09-30

Context

go.mod said go 1.27.1 from the first commit (B0), because that was the newest release, not because anything needed it. The build machine runs Fedora 44, whose Go is 1.26.8 with GOTOOLCHAIN=local in its go.env, so every make target failed there until told GOTOOLCHAIN=go1.27.1, and a staticcheck built with the system Go could not analyze the code. Go 1.26 is also what more machines have.

Checked on 2026-09-30 with Go 1.26.8 and go 1.26.0:

  • go vet ./... (tests included) and go vet -tags webview ./cmd/nodwyn pass, so no 1.27 language feature or API is in use;
  • go test -race ./..., the exfil suite included, passes;
  • no dependency asks for more than Go 1.26.0 (golang.org/x/sys, golang.org/x/term);
  • the go line also picks GODEBUG defaults. Two differ between 1.26 and 1.27: tracebacklabels (goroutine labels in tracebacks; nodwyn sets none) and x509sslcertoverrideplatform (on macOS and Windows, SSL_CERT_FILE/SSL_CERT_DIR replace the platform verifier; nodwyn sets neither and never reads them).

Decision

go.mod says go 1.26.0, with no toolchain line, so a Go set to GOTOOLCHAIN=auto never downloads another toolchain to build nodwyn. CI installs the newest 1.26 patch (go-version: '1.26.x' in both workflows), so tests and govulncheck see a current standard library.

Raise the base when the build machine's distribution Go moves (Fedora 45, due 2026-10-20, ships Go 1.27) and a feature of the newer release is worth having. Change go.mod and both CI workflows together.

Consequences

  • make works with the system Go on Fedora 44, and so does the staticcheck built with it.
  • Code may use Go 1.26 and nothing newer; CI would fail on a 1.27 API.

Amendment 2026-10-12: the analyzer is a module tool

staticcheck v0.8.1, what go install honnef.co/go/tools/cmd/staticcheck@latest installs, reads unified export data up to version 4; Go 1.27.2 writes version 5 (the method-order field, go.dev/issue/81188). On a machine whose Go is 1.27.2, make accept and so every promotion stopped in staticcheck ./... with "export data version 5 is greater than maximum supported version 4", before a test ran. The base stays Go 1.26: nothing here needs 1.27.

go.mod declares tool honnef.co/go/tools/cmd/staticcheck, and make lint runs go tool staticcheck, so the analyzer is built from the module's pinned version rather than from what a machine has installed. The pin is staticcheck v0.8.1 with golang.org/x/tools raised to v0.51.0, whose pkgbits reads version 5; the same tool reads Go 1.26's version 4, so CI on 1.26.x and a 1.27 machine lint alike. CI no longer installs an analyzer. Raise the pin to a staticcheck release carrying the newer x/tools when one exists.