Skip to content

Documentation

Fresh nixpkgs change candidates, 2026-10-04

This is a source-mining report, not a claim that all these changes happened after June 2026. The tree provides strong behavioral repair tasks, but only a small subset has dated post-cutoff evidence. Do not label the whole shortlist a post-training holdout without introduction-commit dates.

Maintained in docs/research/fresh-nixpkgs-changes-2026-10.md

Documentation

This is a source-mining report, not a claim that all these changes happened after June 2026. The tree provides strong behavioral repair tasks, but only a small subset has dated post-cutoff evidence. Do not label the whole shortlist a post-training holdout without introduction-commit dates.

Pin and benchmark context

  • Requested revision: 774debe7a0d1b496e35677ad955a1011c6ff74f3, supplied date 2026-10-02.
  • Read-only source: /nix/store/3zvg83mg9aavm9bgh26ydljchply7i25-source.
  • Store NAR hash, queried locally: sha256-nQyFkMR78WP6PiXKkDW2SjqzLf/spQqjRuxRGSbcV8k=; NAR size 206657464 bytes.
  • .version is 26.05; evaluated config.system.nixos.version is 26.05pre-git. The revision/date above identify the user-supplied pin; the unpacked tree has no Git history with which to independently authenticate that association or date individual changes.
  • Tool: Nix 2.34.8, x86_64-linux. Evaluations used --offline --impure --option allow-import-from-derivation false. No builds, downloads, service starts, or live-data migrations were performed.

The README describes the current real-lib/fake-builder evaluators. The October calibration reports 24/30 saturated tasks and a false failure caused by a fake coreutils package. These candidates use the actual pinned module/package graph and inspect resolved values, generated text, and derivation attributes.

Freshness findings

Both requested release-note files were read in full: 26.05 and 26.11. The 26.05 heading says 2026.05/30, yet the file also describes Home Assistant 2026.8. Release membership therefore does not date an individual change. The 26.11 file has placeholders in both incompatibilities and notable changes; its only migration notice concerns a future tarball retirement.

The most useful post-cutoff anchors are:

  • **P01:** alias comment Added 2026-07-09 for openmpCheckPhaseHook becoming checkPhaseThreadLimitHook.
  • **P09:** alias comment Added 2026-07-24 for removal of omxplayer.
  • **P10:** four Stardust XR removals have Added 2026-07-04. Their implementation accidentally throws an empty string, and there is no direct replacement supplied.
  • **N09:** code and notes explicitly name Home Assistant 2026.8. This is a post-cutoff upstream-version anchor, not proof of the nixpkgs commit date.

Most other rows have unknown introduction dates. Some are positively unsuitable as fresh material: the Rust vendoring guard says 25.05; Xorg scope removal is dated 2026-01-29; hardened-kernel, realtime-kernel, MySQL 8.0, eCryptfs, and several module removals predate June. An October checkout does not make these new changes.

How to read the tables

E means both forms were evaluated against the real tree. E/block means the attempted repair hit a separate documented blocker. S means implementing source was inspected but the candidate was not dynamically verified. R means the decisive change is at runtime/build time; no evaluation error is claimed. Error text in the tables is abbreviated; the probe ledger below records the actual diagnostic and reproducible inputs.

Ranks are task-design ranks, conditional on dating the change: 1 through 12 are the requested sketches; B is a reserve; C needs another constraint; X should not be used for this offline/fresh pool. Scores are (memory trap, deterministic evaluator, repair substance), each 1 to 3. They are judgment calls, not measured model performance. Freshness is a separate gate.

The ledger contains 86 final paired evaluations across 32 NixOS and 11 package/lib candidates, plus the supplemental hardened-profile import probe. All twelve shortlisted repaired probes reach successful evaluation.

Evaluated candidates

IDArea and implementing sourceOld formNew formObserved error or resolved valueVerificationRank; scores
N01initrd N01 sourceboot.initrd.postDeviceCommands with implicit scripted initrdboot.initrd.systemd.services.<name> with explicit orderingAssertion: systemd stage 1 does not support ...; repaired system evaluates with systemd initrd enabledE3; 3,3,3
N02Yggdrasil credentials N02 sourceservices.yggdrasil.settings.PrivateKeyservices.yggdrasil.settings.PrivateKeyPathPrivateKey assertion; new LoadCredential = [ "private-key:/run/secrets/ygg.pem" ]E4; 3,3,3
N03Stalwart identity/state N03 sourceservices.stalwart-mail.enable = true without module state versionservices.stalwart.enable; explicit services.stalwart.stateVersionMissing stateVersion; 25.11 preserves user/group stalwart-mail, /var/lib/stalwart-mail, stdout tracerE2; 3,3,3
N04cgit export policy N04 sourceImplicit export-all via services.cgit.<vhost>Explicit gitHttpBackend.checkExportOkFiles; matching settings.strict-exportMissing required value; new backend remains enabled with export checks trueE6; 3,3,3
N05Grafana key N05 sourceOmit services.grafana.settings.security.secret_keyExplicit key, preferably $__file{/run/secrets/grafana}Assertion says key no longer has a default; new file-provider string preservedEB; 3,3,2
N06OAuth2 Proxy secrets N06 sourceservices.oauth2-proxy.clientSecret, .cookie.secret.clientSecretFile, .cookie.secretFileTwo removed-option assertions; new runtime paths evaluateE10; 3,3,3
N07angrr policies N07 sourceservices.angrr.period, .ownedOnly, .removeRoot.settings.owned-only, .settings.temporary-root-policies, .settings.profile-policies, or .configFileRemoved since angrr 0.2.0; new named result policy resolves with period="7d"E8; 2,3,3
N08wireless hardening N08 sourcenetworking.wireless.userControlled = { enable=true; group="wheel"; }Boolean .userControlled; users join wpa_supplicant; files under /etc/wpa_supplicantOld coerces to true and traces rename, ignores wheel; daemon User is wpa_supplicant in bothE7; 3,3,3
N09Home Assistant 2026.8 N09 sourceservices.home-assistant.config.lovelace.mode.config.lovelace.dashboards, .resource_mode, retain .lovelaceConfigOld evaluates with deprecation warning and obsolete mode still present; repaired config has dashboard and no mode/warningE1; 3,3,3
N10PowerDNS Recursor N10 sourceservices.pdns-recursor.old-settings; former .yaml-settings.settings with YAML schema, e.g. incoming.allow_from, incoming.portRemoved old-settings assertion; new nested settings preserve ACL/port; yaml-settings remains a warning aliasE9; 3,3,3
N11frp instances N11 sourceservices.frp.enable/role/settings singletonservices.frp.instances.<name>.enable/role/settingsOld warning aliases target instance "", unit frp; new units frp-edge, frp-ingressEB; 3,3,3
N12resolv.conf ownership N12 sourceSet environment.etc."resolv.conf" and omit resolver toggleAlso set networking.resolvconf.enable = falseAssertion reports both enabled; explicit false passesEC; 3,3,1
N13OpenSSH merging N13 sourceservices.openssh.settings.AcceptEnv = "LANG LC_*"[ "LANG" "LC_*" ]Expected null or (list of string); new list resolves exactlyEC; 3,3,1
N14coredump settings N14 sourcesystemd.coredump.extraConfigsystemd.coredump.settings.CoredumpRemoved-option assertion; generated text has [Coredump], Storage=journal, ProcessSizeMax=1GEC; 3,3,2
N15filesystem type N15 sourceOmit fileSystems.<mount>.fsTypeSet correct filesystem type; explicit "auto" remains acceptedfileSystems."/data".fsType has no value; explicit ext4 passesEC; 3,3,1
N16captive DNS N16 sourceEnable captive-browser without a supported network manager or .dhcp-dnsSet .dhcp-dns or enable NetworkManager, dhcpcd, or networking.useNetworkdprograms.captive-browser.dhcp-dns must be set; explicit command passesEB; 3,3,2
N17Homepage environment N17 sourceservices.homepage-dashboard.environmentFile string.environmentFiles listmkChangedOptionModule wraps old string into singleton; new two-file systemd EnvironmentFile list resolvesEC; 3,3,1
N18X11 driver validation N18 sourceUnrecognized member of services.xserver.videoDriversKnown driver name such as modesettingUnknown X11 driver ‘not-a-driver’ ...; valid driver passesEC; 2,3,1
N19Mattermost PostgreSQL N19 sourceservices.mattermost.database.driver = "mysql"Remove driver; configure PostgreSQL connection through remaining database optionsRemoved driver assertion; repaired projection has database mattermost, PostgreSQL enabledEB; 3,3,3
N20Yggdrasil note correction N20 sourceservices.yggdrasil.persistentKeys = trueStill supported; external settings.PrivateKeyPath is an alternativeNo removal error! Old credentials use /var/lib/yggdrasil/private.pem; source includes old keys.json migrationEX; 2,3,2
N21Yggdrasil external config N21 sourceservices.yggdrasil.configFileStructured .settings, with separate key managementOption does not exist; new Peers list preservedEB, combine N02; 3,3,2
N22sleep settings N22 sourcesystemd.sleep.extraConfigsystemd.sleep.settings.SleepRemoved-option assertion; generated text contains AllowHibernation=falseEC; 3,3,1
N23resolved schema N23 source.fallbackDns, .domains, .llmnr, .dnssec, .dnsovertls, .extraConfig under services.resolved.settings.Resolve.{FallbackDNS,Domains,LLMNR,DNSSEC,DNSOverTLS}; structured settings replace extraConfigdnssec alias warns; old/new produce same drvPath and DNSSEC value; extraConfig removal source-inspectedE/SC; 3,3,1
N24Kanidm namespaces N24 source.enableServer/serverSettings, .enableClient/clientSettings, .enablePam/unixSettings.server.enable/settings, .client.enable/settings, .unix.enable/settingsAliases warn; same resulting client settings/derivation with explicit package=pkgs.kanidm_1_9EC; 3,3,1
N25Seerr state path N25 sourceservices.jellyseerr; old unit/data pathservices.seerr; unit seerr; version-gated .configDirBoth names at stateVersion 26.05 resolve /var/lib/seerr/; old versions retain /var/lib/jellyseerr/config by sourceE/SB; 3,3,2
N26Immich VectorChord N26 sourceservices.immich.database.enableVectors, .enableVectorChordRemove both; module always uses VectorChordOld removal assertions; repaired toplevel blocked by insecure immich-2.7.5E/blockX until fixture isolates blocker; 3,2,2
N27CoreDNS image type N27 sourceservices.kubernetes.addons.dns.coredns raw pullImage attrs.corednsImage package, default built image or pkgs.dockerTools.pullImage { ... }Alias forwards old attrs then fails not of type package; default image drvPath evaluatesEB; 3,3,2
N28Mosquitto plugins N28 sourceOverride services.mosquitto.package to 2.0; expect password_file/acl_filePackage >=2.1; generated acl-file/password-file pluginsVersion assertion with synthetic 2.0.99 override; current 2.1.2 passesEB; 2,3,2
N29vsftpd authentication N29 sourceservices.vsftpd.localUsers=true implicitly supplies PAMExplicit virtual users with .userDbPath, or consciously configured PAMOld evaluates with no security.pam.services.vsftpd; virtual-user fixture supplies itEB; 3,3,3
N30TaskChampion identity N30 sourceStatic user by default.dynamicUser defaults true at stateVersion >=26.05Explicit false yields DynamicUser=false; omitted at 26.05 yields true; data migration is runtimeEC; 2,3,2
N31SSH banner semantics N31 sourceservices.openssh.banner text.settings.Banner file path plus managed fileRemoved-option assertion; new path /etc/ssh/banner passesEC; 3,3,2
N32Dovecot structured configuration N32 sourceservices.dovecot2.enableImap/enablePop3/sslServerCert/sslServerKey/mailLocation/extraConfig.settings.protocols, version-specific TLS/mail settings; explicit dovecot_config_version, dovecot_storage_version for 2.4Multiple removed options plus two required-version assertions; new 2.4.5 config evaluatesE5; 3,3,3
P01check-phase thread limits P01 sourcepkgs.openmpCheckPhaseHookpkgs.checkPhaseThreadLimitHookWarning names replacement; identical hook drvPath; hook now covers seven thread variablesE12; 3,3,2
P02pnpm fetcher contract P02 sourceOmit fetcherVersion; singular pnpmWorkspace; versions 1/2Explicit fetcherVersion=4, plural pnpmWorkspaces; regenerate hash when format changesMissing-version error; v4 package evaluates. Source: singular rejected; warning applies to versions <3, not 3E/S11; 3,3,3
P03stdenv dependency lists P03 sourcebuildInputs = [ [ pkgs.zlib ] ]Flat dependency listWarning: nested list deprecated as of 26.05; still evaluates, different drvPath from flat formEB; 3,3,2
P04Python backend selection P04 sourcebuildPythonPackage without format/pyprojectpyproject=true; build-system=[setuptools]; or appropriate backenddoes not configure a format; explicit backend evaluatesEC, familiar/undated; 3,3,2
P05Python test selection P05 sourceNonempty pytestFlagsArraypytestFlags, enabledTests/disabledTests, enabledTestPaths/disabledTestPaths, or test-mark optionsFrom a real file: Deprecated flag pytestFlagsArray found ...; new form evaluatesEB, undated; 3,3,2
P06Rust vendoring P06 sourceuseFetchCargoVendor=falseRemove flag, use current cargoHash/cargoLock/cargoDeps/cargoVendorDir contractGuard says non-optional since 25.05; repaired package evaluatesEX, pre-cutoff; 3,3,2
P07fetchgit negative finding P07 sourceOmit both rev and tagPrefer explicit rev/tag for reproducibilityNo missing-revision error: source still defaults to HEAD. Only both rev and tag trigger quoted guardEX, not verified fresh change; 3,2,1
P08lib nested type introspection P08 source(lib.types.listOf lib.types.str).functor.wrapped.nestedTypes.elemTypeWarning: deprecated functor.wrapped; both name projections yield "str"EC, undated; 2,3,1
P09omxplayer removal P09 sourcepkgs.omxplayerpkgs.vlc is the suggested substitute; CLI migration separateThrow cites outdated upstream/FFmpeg, suggests vlc; vlc derivation evaluatesEC, dated July 24; 2,3,1
P10Stardust XR removals P10 sourcepkgs.stardust-xr-{kiara,magnetar,phobetor,sphereland}No direct replacement specifiedkiara throws empty message because source says throw "" "..."; hasAttr still true, not a repairE/SX, dated July 4; 1,2,1
P11Xorg scope removal P11 sourcepkgs.xorg.overrideScope, .callPackage, .newScope, .packagesTop-level packages and overlays; e.g. pkgs.libx11The xorg package set has been moved to the top level.; top-level overlay evaluatesEX, Jan 29; 3,3,3

Remaining release-note change inventory

These rows complete the change census without turning runtime-only notices into invented Nix errors. Rows already covered by N01 through N32 are not repeated. Pure additions that do not change an existing contract are excluded: ordinary new service modules, optional Bluetooth/Atuin/Radicle/SSH-host-key/IPVLAN/Caddy/Slurm features, and the optional nspawn test backend. The parallel replacement modules and new configuration entry point are recorded because they can be mistaken for mandatory migrations.

For mkRemovedOptionModule, a definition produces the generic assertion The option definition '<path>' in '<file>' no longer has any effect; please remove it. followed by the source's reason. A read of the removed value instead throws The option '<path>' can no longer be used since it's been removed. A declared removal is not proof that merely importing a compatibility stub fails.

IDArea/sourceOld form or assumptionNew form or valueError/value and evidence statusRank
R01Kernel default R01 sourceImplicit boot.kernelPackages uses 6.12Default linuxPackages uses 6.18; explicit supported series still availableS: linux_default = packages.linux_6_18; no expected evaluation errorC
R02D-Bus default R02 sourceImplicit services.dbus.implementation = "dbus"Default is literal "broker"; "dbus" remains opt-outS: implementation participates in system.switch.inhibitors.dbus-implementation; reboot/switch refusal is runtimeB
R03Configuration entry point R03 sourceOnly configuration.nix/flake.nixOptional system.nix returning a system derivation or attrset of them; --attr selects memberS/R: additive entry point, no old-form evaluation errorX
R04Jenkins PATH R04 sourceRely on implicit tools in services.jenkins.packagesDefault []; explicitly provide tools needed by jobsS: no evaluation error, PATH is differentB
R05Avahi wide-area R05 sourceImplicit services.avahi.wideArea = trueDefault falseS: explicit true still works but warns about CVE-2024-52615C
R06Wine output/architecture R06 sourcewineWowPackages-based prefixes for opentrack, slushload, synthesia, vtfedit, winbox, wineasio, yabridgewineWow64Packages; regenerate incompatible prefixesS/R: no generic evaluation rejection of old prefixes; package dependencies changed, runtime data migrationX
R07Hardened profile R07 sourceImport (modulesPath + "/profiles/hardened.nix") and expect hardeningChoose explicit hardening settingsE/import only: importing the stub reaches the baseline toplevel drvPath with warnings=[]; it no longer supplies hardening. Do not claim a missing-file errorB, with concrete hardening requirements
R08OpenSnitch rules R08 sourceDefault services.opensnitch.settings.Rules.Path = "/etc/opensnitchd/rules"Default /var/lib/opensnitch/rulesS: value change, no evaluation error for explicit old pathC
R09sing-box 1.13 R09 sourceDeprecated upstream JSON settingsUpstream 1.13 schema; pin is 1.13.19S/R: notes do not enumerate removed keys; Nix package version proves update, not config validation. Needs upstream schema researchX
R10systemd user-installed units R10 sourceStart system units installed through nix-env -iDeclare NixOS units/packages explicitlyR: release-note claim; current systemd patch list in pkgs/os-specific/linux/systemd/default.nix inspected, but removal history is unavailable; no evaluation-time diagnosis for nix-env stateX
R11systemd unformatted dm-crypt devices R11 sourceDevice units for open but unformatted dm-crypt, including systemd-makefs orderingUse supported upstream device/filesystem lifecycleR: release-note claim; current systemd patch list inspected, removal history unavailable. No tested evaluation rejection; not an option renameX
R12Hardened kernel R12 sourcepkgs.linux_hardenedChoose maintained kernel plus explicit policyS: exact throw linux_hardened has been removed due to lack of maintenance; dated 2026-03-18X, pre-cutoff
R13Tandoor media directory R13 sourceMedia at /var/lib/tandoor-recipes; implicit extraConfig.MEDIA_ROOTAt stateVersion >=26.05, /var/lib/tandoor-recipes/media; explicit MEDIA_ROOT for migrated old systemsS: pre-26.05 unset value warns it is insecure; data move cannot be checked by evaluationB
R14Realtime kernels R14 sourcepkgs.linux-rt and related seriesA maintained supported kernelS: exact throw linux-rt has been removed due to lack of maintenance; dated 2026-03-24X, pre-cutoff
R15rustic CLI/config R15 sourcePre-0.11 CLI and config0.11.x; pin 0.11.2S/R: package expression does not validate arbitrary external rustic configuration; exact removed upstream keys not establishedX
R16Wireless command packages R16 sourceEnabling wireless implicitly installs iw and wirelesstoolsExplicit environment.systemPackages = [ pkgs.iw pkgs.wirelesstools ]; when neededS: package-list difference; no evaluation error for missing interactive commandsC
R17Resume unit ordering R17 sourceOrder against post-resume.targetOrder a service around sleep.target, using ExecStop for post-resume workR: stale unit-name strings can still evaluate; absence of actual target is the failureB, inspect units but no runtime proof
R18Lauti rebrand R18 sourceservices.eintopfservices.lautiS: rename alias; stateVersion <26.05 preserves eintopf user/group and /var/lib/eintopf, newer uses lauti and /var/lib/lautiC
R19ROCm package set R19 sourcepkgs.rocmPackages_6; old hipblas APIs/constant warp sizespkgs.rocmPackages 7.x and ported native sourcesS: rocmPackages_6 absent from top-level definitions/aliases; Nix missing-attribute error expected, C/C++ porting needs buildsX
R20MySQL 8.0 R20 sourcepkgs.mysql80pkgs.mysql84 or pkgs.mariadbS: exact throw: 'mysql80' reached end of life on 2026-04-30 and has been removed.; added 2026-04-08X, pre-cutoff
R21Rspamd exporter R21 sourceservices.prometheus.exporters.rspamdPrometheus scrape of Rspamd controller /metricsS: removed-option reason: The Rspamd exporter has been removed. You can use the Rspamd /metrics endpoint directly instead:B
R22nixos-rebuild implementation R22 sourcesystem.rebuild.enableNgRemove toggle; Python implementation is usedS: removed-option assertion: The Bash implementation of nixos-rebuild has been removed in favor of the new Python implementation.C
R23GNOME default applications R23 sourceGNOME installs Geary and favors itExplicit programs.geary.enable=true; default favorite is org.gnome.TextEditor.desktopS: no evaluation failure, package/favorite changeC
R24Walker backend R24 sourceWalker without Elephant backend and old action/keybind configWalker 2.x plus services.elephant.enable; new upstream configS/R: pin 2.16.2; arbitrary launch/config cannot be runtime-verified offlineB only for unit/package contract
R25Portunus validation R25 sourceExisting database contains malformed email addressesRepair addresses for Portunus 2.2.0S/R: upstream startup rejects data, no Nix evaluation errorX
R26ReiserFS R26 sourcepkgs.reiserfsprogs, ReiserFS filesystem supportMigrate filesystem to a maintained alternativeS: throw: 'reiserfsprogs' has been removed as ReiserFS has not been actively maintained for many years.; added 2025-11-13X, pre-cutoff/runtime migration
R27Tor Unix sockets R27 sourceAutomatic bind-mounting of onion-service Unix socketsExplicit systemd.services.tor.serviceConfig.BindPaths for parent directories, or shared /tmp via JoinsNamespaceOfS: module documents new wiring; old endpoint values need not fail evaluationB
R28eCryptfs R28 sourcepkgs.ecryptfs, programs.ecryptfs, security.pam.enableEcryptfsNo drop-in replacement; fscrypt/gocryptfs/cryfs suggested for packageS: package throw names alternatives; removed module paths in rename.nix; added 2026-01-14X, pre-cutoff
R29Ceph major version R29 sourceCeph Squid server stateCeph Tentacle v20; pin 20.2.4S/R: one-way storage upgrade; no evaluator proof of safe migrationX
R30UniFi JVM R30 sourceDefault services.unifi.jrePackage = pkgs.jdk17_headlessDefault pkgs.jdk25_headlessS: explicit old package can evaluate; runtime compatibility is separateC
R31Network service graph R31 sourceDepend on network-setup.service or synchronous configurationnetwork.target pulled into multi-user.target; device-specific jobs run as devices appearS/R: obsolete dependency strings still evaluate; inspect generated graphB
R32Resolver setup placement R32 sourceNameservers tied to old backend jobs; resolvconf-disabled/no-gateway could skip configurationNameservers in network-local-commands.service for scripted and networkdS: graph/setup-script change, no generic evaluation errorB
R33Vikunja 1.0 settings R33 sourceOmitted public URL, old OpenID/metrics/log keys, old SQLite relative-path assumptionsservices.vikunja.settings.service.publicurl; CORS enabled upstream; explicit root/path/provider configurationS/R: module supplies publicurl; arbitrary freeform wrong keys need not fail evaluation; upstream schema not fully established hereB for resolved settings only
R34ESPHome identity R34 sourceDynamicUser and private state directoryStatic esphome user/group, /var/lib/esphome persistenceS: User/Group and StateDirectory resolve in source; automatic state migration is runtimeB
R35BenchExec dependency R35 sourceprograms.benchexec.enable enables pqos-wrapperNo pqos-wrapper module/packageS: no failure for benchexec alone; pqos-wrapper explicit definitions are removedC
R36Activation restart API R36 sourceActivation writes /run/nixos/activation-{restart,reload}-listDeclarative unit restart/reload triggers; removed in future 26.11S/R: runtime stderr: WARN: restarting or reloading systemd units from the activation script is deprecated and will be removed in NixOS 26.11.X for eval-only grading
R37Switch inhibitors R37 sourceAssume every generation can be switched intosystem.switch.inhibitors controls pre-switch check; NIXOS_NO_CHECK bypass at runtimeS/R: configuration evaluates; comparing two live generations is not part of nix evalB for data contract only
R38ExecReload transition R38 sourceOnly ExecReload change causes restart; removal restarts tooChange reloads, removal takes no actionS/R: switch program comparison logic, not a Nix evaluator errorX
R39NVIDIA output layout R39 sourceAssume old nvidia-x11 paths/output layout and vendor EGL librariesUse .bin/.lib32 and source-built egl-gbm, egl-wayland, egl-wayland2, egl-x11 wiringS: module implements layout; wrong path strings can evaluate without existence checksB for dependency outputs
R40NVIDIA module parameters R40 sourceModule-provided parameters on global kernel command linehardware.nvidia.moduleParams; generated modprobe configS: optional new API plus changed generated placement; branch selection is additive, hardware.nvidia.package still overrides itB
R41ACME renewal default R41 sourceFixed security.acme.defaults.validMinDays defaultDefault null selects dynamic renewal; >=10-day certs at two-thirds elapsed, short certs halfwayS: command uses --dynamic; explicit validMinDays still yields --days; certificate behavior runtimeB
R42Embedded font bitmaps R42 sourceImplicit fonts.fontconfig.useEmbeddedBitmaps=falseDefault trueS: value difference, no errorC
R43Nextcloud version selection R43 sourceImplicit nextcloud31 on old stateVersion, or jump directly from 31 to latestExplicit nextcloud32 for staged upgrade; defaults 32 at >=25.11, 33 at >=26.05S: package selection/source guards; database upgrade sequencing cannot be proved by evalB
R44InvoicePlane Caddy HTTPS R44 sourceSite keyed services.caddy.virtualHosts."http://example.com"Site key "example.com"; set .hostName="http://example.com" only to retain HTTPS: default generated vhost now uses automatic HTTPS; old extra vhost can evaluate but not modify intended siteB
R45Firewall logging R45 sourceImplicit networking.firewall.logRefusedConnections=trueDefault falseS: value change, no evaluation errorC
R46Calibre-Web sandbox R46 sourceService assumes host/home filesystem accessAdditional ProtectSystem/ProtectHome/PrivateDevices/etc; arrange writable library paths explicitlyS/R: generated restrictions inspectable; access failures require runtimeB
R4726.11 tarball notice R47 sourceChannel nixexprs.tar.xznixexprs.tar.zst before discontinuation with 27.05 after 2027-12-31S/R: both generated now; no present offline failure of old URL provedX, future removal
R48knot-resolver parallel module R48 sourceservices.kresd for version 5New services.knot-resolver for version 6S: both module paths are registered; old module not removed by this noteX, additive
R49Varnish/Vinyl parallel module R49 sourceservices.varnishNew services.vinyl-cache; old module still availableS: not a mandatory rename; no old evaluation failure claimedX, additive

The following removed-module entries each appear in the 26.05 notes. They are retained as separate candidates so the census does not silently drop removals. None is a good standalone benchmark consisting only of deleting enable = true.

IDRemoved pathReplacementExact source reason after the standard removed-option assertionStatus/rank
R50services.crabfitNo designated replacementR50 source: The corresponding packages were removed from nixpkgs because they are unmaintained upstream and insecure.S; C, or X without a replacement contract
R51services.statsdA separately designed supported metrics pipelineR51 source: The statsd module was removed because the packages it uses have been removed from nixpkgs.S; C, or X without a replacement contract
R52services.pyloadNo designated replacementR52 source: services.pyload has been removed since the pyload-ng package had vulnerabilities and was unmaintained in nixpkgs.S; C, or X without a replacement contract
R53services.uptimeNo designated replacementR53 source: The package for services.uptime has been removed from nixpkgs.S; C, or X without a replacement contract
R54services.promtailservices.alloy or services.fluent-bit with equivalent Loki labels/positionsR54 source: The promtail module has been removed, as promtail reached its end of life.S; C, or X without a replacement contract
R55services.ethercalcNo designated replacementR55 source: The ethercalc module has been removed from nixpkgs as the project was old, unmaintained, and could not be packaged well in nixpkgs.S; C, or X without a replacement contract
R56services.xserver.cmtChoose a supported input stackR56 source: services.xserver.cmt has been removed as it was broken and unmaintained upstreamS; C, or X without a replacement contract
R57programs.lightbrightnessctl package or hardware.acpilightR57 source: The corresponding package was removed from nixpkgs due to being unmaintained upstream. brightnessctl and hardware.acpilight offer replacements.S; C, or X without a replacement contract
R58services.pingvin-shareNo designated replacementR58 source: The pingvin-share.backend package was broken and the project was archived upstream, so it was removed from nixpkgs.S; C, or X without a replacement contract
R59services.xtreemfsNo designated replacementR59 source: services.xtreemfs has been removed as it was broken and unmaintained upstreamS; C, or X without a replacement contract
R60services.opengfwNo designated replacementR60 source: The opengfw package and services.opengfw module have been removed since the upstream (opening line; continued in source)S; C, or X without a replacement contract
R61programs.pqos-wrapperNo designated replacementR61 source: The corresponding package was removed from nixpkgs.S; C, or X without a replacement contract

Additional mapping details omitted by the short release prose:

  • Dovecot also removes services.dovecot2.modules in favor of environment.systemPackages; enableLmtp becomes settings.protocols.lmtp; sslCACert becomes settings.ssl_ca for 2.3 or settings.ssl_server_ca_file for 2.4. sieveScripts aliases sieve.scripts; mailUser/mailGroup alias settings.mail_uid/mail_gid; protocols aliases settings.protocols. sieve.plugins is removed in favor of settings.plugin.sieve_plugins. mailboxes, pluginSettings, enableQuota, quotaPort, quotaGlobalPerUser, and extraConfig are removed with Please use services.dovecot2.settings instead. enableDHE says Use ECDHE instead, or use recommended parameters from RFC7919. N32's source contains every mapping.
  • Wireless renamed .userControlled.enable is a coercion, not mkRenamedOptionModule. An attrset with enable and group takes the enable branch first, so the group-specific trace need not print. The group is nevertheless fixed. Config is generated at environment.etc."wpa_supplicant/nixos.conf"; imperative config is /etc/wpa_supplicant/imperative.conf. NetworkManager now relies on the shared wpa_supplicant service, so an explicit wireless disable can interfere. Evaluation proves generated wiring, not certificate readability on a running host.
  • Immich's real spelling is enableVectorChord, with capital C. The note's enableVectorchord spelling is inaccurate.
  • Yggdrasil configFile really is absent, but persistentKeys is not removed. With an external path and persistentKeys both selected, the source assertion says they are mutually exclusive. Use only one of them.
  • The CoreDNS rename uses mkRenamedOptionModuleWith { sinceRelease = 2605; ... }; it does not convert raw image attrs into a derivation.

Packaging and lib scan beyond release notes

The thread-limit hook is the implementation behind P01. The scan covered pkgs/stdenv, pkgs/build-support including fetchers, compiler/linker wrappers, Rust, pnpm, and the Python builder at pkgs/development/interpreters/python/mk-python-derivation.nix; it also covered lib warning sites and 2026-dated top-level aliases. P01 through P11 are the evaluated results. No post-June compiler-wrapper or linker-wrapper API change was established. Do not infer one from a warning-free grep.

IDSource/APIOld formReplacementSource diagnostic / limitStatus; rank
P12P12 sourcemkDerivation { env.X=...; X=...; }One unambiguous environment definitionThe diagnostic starts with `The env attribute set cannot contain any attributes passed to derivation.` with overlapping values listed. Also validates env types. Undated; backticks around env appear in source.S; B, undated
P13P13 sourcefetchzip.extraPostFetch; same forwarding in fetchFromGitHub/GitLabpostFetchuse 'postFetch' instead of 'extraPostFetch' with 'fetchzip' and 'fetchFromGitHub' or 'fetchFromGitLab'. Warning only, age not established.S; C
P14P14 sourceList-valued curlOptsPrefer curlOptsList for separated arguments, or scalar curlOptswarnIf list, diagnostic gives string/list alternatives; no introduction date.S; C
P15P15 sourcelib.mkAliasOptionModuleMDlib.mkAliasOptionModulemkAliasOptionModuleMD is deprecated and will be removed in 26.05; please use mkAliasOptionModule. Still a warn alias in this pin despite scheduled removal.S; X, not fresh evidence
P16P16 sourcePath values passed to normalizePath, hasPrefix/hasSuffix/hasInfix, removePrefix/removeSuffixStrings; explicit path-to-string conversion only when store-copy semantics are intendednormalizePath warns that only strings are supported and path coercion copies to the store. Other functions warn on path-valued prefix/suffix/infix arguments.S; B, undated
P17P17 sourceExternal low-level lib.modules.*; also lib.evalOptionValuePublic module API where sufficient; no universal replacementExternal use of ... is deprecated. This is a compatibility warning, not evidence of a new removal.S; X
P18P18 sourceoverrideAttrs discards passthru.overrideModAttrsPreserve builder-owned passthru when extendingbuildGoModule: ... passthru.overrideModAttrs missing after overrideAttrs. Last overridden at ... Warning fallback. Python analogous getFinalPassthru throws.S; B, undated

The alias date search used comments, not every appearance of 2026-06 in strings: for example eagle mentions a June support-end date but its removal comment is April 26. Of the post-June comment matches in this file, P01, P09 and the four P10 aliases are the entire set found. The many January through May aliases were inspected as negative freshness evidence, including xorg.overrideScope, yarn2nix/yarn2nix-moretea removal in favor of standard Yarn v1 hooks, kanidm, and the kernel/MySQL removals. These should not be sold as post-cutoff tasks.

Top 12 task sketches

These are proposed task fixtures, not implemented benchmark tasks. All twelve have an evaluated old/new probe below. Except P01 and N09's version anchor, they still need introduction-date verification before admission to a post-June-only pool. The rank favors changes that require reading resolved configuration and preserving behavior across files.

1. N09: Home Assistant dashboard and resource ownership

Proposed prompt: "After the pin update, nixos-rebuild reports services.home-assistant.config.lovelace.mode is deprecated. The checked-in Overview dashboard, a second operations dashboard, and our custom cards must remain declarative. Remove the warning without moving dashboard or card management into the UI. Keep the host's own integrations."

Fixture: configuration.nix imports services/home-assistant.nix, dashboards/overview.nix, dashboards/operations.nix, and hosts/lab.nix. The old module writes top-level mode; cards and extra dashboard settings come from different modules. Set config.default_config = {} so this is a declarative config rather than the module's null-config case.

Assertions: force the system toplevel; config.lovelace has no top-level mode; the generated dashboards.nixos-lovelace has YAML mode, correct filename and sidebar metadata; the second dashboard survives; custom-card resources preserve URL, type, and version; resource_mode is YAML when custom cards are present; unrelated integrations survive; no Lovelace deprecation warning. Test the no-cards variant too. Do not require a particular source-file arrangement or merely grep out the word "mode", which is valid inside each dashboard.

Evidence: old/new system derivations both evaluate. Old freeform mode survives alongside the newly generated dashboard and triggers a warning. New config removes only the obsolete field. Code explicitly refers to 2026.8; introduction commit still needs dating.

2. N03: Stalwart migration without changing on-disk identity

Proposed prompt: "After upgrading the pin, nixos-rebuild stops because a Stalwart state version has no value. This mail host has existing RocksDB data under /var/lib/stalwart-mail, owned by stalwart-mail. Restore evaluation without moving data, changing ownership, exposing extra ports, or resetting logging policy. The separately provisioned new host should use its own defaults."

Fixture: configuration.nix, mail/base.nix, mail/listeners.nix, hosts/legacy-mail.nix, hosts/new-mail.nix. Global host state versions and service installation ages are stated separately in fixtures. Credentials come from a host module; listeners and firewall policy come from another file.

Assertions: both hosts reach toplevel evaluation; legacy module state stays at its stated installation version, preserving user/group/dataDir/stdout tracer and RocksDB path; fresh host uses the intended current module state and journal tracer; system.stateVersion is unchanged on both; required listener and credential paths survive; firewall ports match only enabled listeners when requested. Check unit stalwart, not the old name. Reject raising the legacy module version merely to satisfy the missing-value error.

Evidence: explicit module stateVersion="25.11" with global 26.05 resolves /var/lib/stalwart-mail, stalwart-mail owner/group and stdout tracer. This proves module state is independent of global state. It does not perform a data migration.

3. N01: initrd hook migration with ordering

Proposed prompt: "nixos-rebuild now reports that systemd stage 1 does not support our post-device hook. The hook must run after the fixture's device-discovery unit and before the root mount, exactly once per boot. Keep systemd initrd enabled and preserve the separate stage-2 service."

Fixture: boot/initrd.nix, boot/storage.nix, hosts/appliance.nix, services/stage2.nix. A tiny fixture discovery unit gives the evaluator a concrete dependency rather than assuming that udev-settle alone guarantees storage readiness. The hook writes a marker with a declared dependency in its executable path.

Assertions: boot.initrd.systemd.enable=true; all unsupported scripted hook fields are empty; intended initrd oneshot has both activation and required before/after edges; marker command, path dependencies and lifetime are retained; root filesystem and LUKS mapper names stay correct; stage-2 unit remains. Assert against the resolved initrd unit graph. Evaluation cannot establish that a real disk unlocks, and a generated device dependency is not proof of boot success.

Evidence: postDeviceCommands fails at toplevel; a systemd initrd oneshot evaluates. Notes also describe /dev/root removal, cryptsetup-askpass replacement with systemctl default, TTY requirements for remote unlock, and native systemd kernel parameters. Those are runtime constraints, not additional evaluation errors.

4. N02: Yggdrasil configuration with one key owner

Proposed prompt: "nixos-rebuild rejects our Yggdrasil configuration because the private key would be stored world-readable. The service must retain its peer list, listener, interface name, and stable identity using the secret already provisioned on the host. The dev host should retain automatic key persistence."

Fixture: network/yggdrasil.nix, network/peers.nix, hosts/edge.nix, hosts/dev.nix; a runtime secret path is stated in the prompt. No actual private key material belongs in the repository. An optional older configFile fragment provides the second migration constraint.

Assertions: edge has no inline settings.PrivateKey, preserves settings, loads the specified runtime path using LoadCredential, and has matching BindReadOnlyPaths; it does not select conflicting automatic persistence. Dev still has persistentKeys and the migration/generation unit. Assert that serialized settings and derivation strings do not contain the fixture's dummy secret. Preserve all peer/firewall settings. Accept a correct credential-driven implementation with equivalent generated behavior.

Evidence: inline PrivateKey triggers a real assertion; external path resolves to private-key:/run/secrets/ygg.pem. PersistentKeys is still supported, contrary to the notes; deleting it unconditionally would be an invalid reference solution.

5. N32: Dovecot settings and format versions

Proposed prompt: "The mail host no longer evaluates: nixos-rebuild says several Dovecot option definitions no longer have any effect, then asks for configuration and storage versions. Keep IMAP enabled, POP3 disabled, the existing TLS files, and the declared maildir location. One host deliberately remains on the older Dovecot package."

Fixture: mail/dovecot.nix, mail/tls.nix, mail/users.nix, hosts/current.nix, hosts/legacy.nix. State the current host's intended storage compatibility floor and legacy package in the prompt. Give the old raw-config fragment actual settings to preserve rather than only comments.

Assertions: both host configurations evaluate; package selection is preserved; 2.4 settings include explicit config and storage versions appropriate to the fixture, 2.3 receives its supported TLS/mail keys; protocols retain IMAP/POP3 policy; certificate/key strings point to runtime paths; mail driver/path and user/group survive; no removed options are defined. Inspect services.dovecot2.configFile's derivation text input if testing rendered syntax; do not readFile an unbuilt writeText output.

Evidence: six old option definitions fail, plus the 2.4 module requires both settings.dovecot_config_version and settings.dovecot_storage_version. Adding structured settings alone still fails. A repaired 2.4.5 configuration evaluates with the requested certificate, mail path and protocol booleans. The module's internal _section attribute is serializer metadata; do not reject it as a user error.

6. N04: cgit UI and clone access agree

Proposed prompt: "nixos-rebuild says a cgit export-policy option has no value. Only repositories carrying the export marker may be browsed or cloned; private repositories share the same parent directory. Preserve smart HTTP for public repositories and the independent public-only virtual host."

Fixture: git/cgit.nix, git/nginx.nix, hosts/git.nix, and git/repos.nix. One vhost scans a mixed repository tree; the other is deliberately public. Keep access requirements explicit.

Assertions: both vhosts evaluate; protected vhost has matching cgit strict-export marker and git-http-backend export checks; its generated FastCGI params do not contain GIT_HTTP_EXPORT_ALL; smart HTTP location and project root are preserved; public host remains independently configured. Test partial fixes: setting checkExportOkFiles alone fails the module's agreement assertion, and disabling all backends violates the public-clone requirement.

Evidence: omitted checkExportOkFiles fails at evaluation. Setting it true with strict-export git-daemon-export-ok passes. Source generates GIT_HTTP_EXPORT_ALL only when checks are false.

7. N08: wireless access after daemon hardening

Proposed prompt: "nixos-rebuild traces an obsolete wireless option, and the generated service now runs as wpa_supplicant. Keep the daemon hardening. The named operator must retain control-socket access, and the declared client-certificate paths must remain usable inside the service's filesystem view. Preserve the host's network definitions."

Fixture: network/wireless.nix, users/operators.nix, secrets/wifi-paths.nix, hosts/laptop.nix. Certificate files are represented by runtime paths and tmpfiles/ownership declarations, never read during evaluation. Include a second host using NetworkManager to catch an unconditional wireless disable.

Assertions: userControlled is true; daemon User/Group and enableHardening retain defaults; designated users join wpa_supplicant without losing existing groups; generated config is wpa_supplicant/nixos.conf; generated and imperative file/credential paths align with bind mounts and ownership declarations; no conflicting manual ctrl_interface; SSIDs/EAP options survive; NetworkManager wiring remains enabled. Grade declared access policy only, not actual runtime file permissions.

Evidence: old enable/group attrset evaluates and ignores the requested wheel group. Both probes run the service as wpa_supplicant; only the repaired fixture grants the operator the correct group. This is a value-change task, not a hard-error task.

8. N07: angrr retention becomes named policies

Proposed prompt: "nixos-rebuild says our angrr period, ownership and root-removal definitions no longer have any effect. Preserve the stated retention rules: result links expire after seven days, direnv roots after fourteen, and system profiles retain the current and booted generations plus the newest five. User-scoped runs must not manage other users' roots."

Fixture: maintenance/angrr.nix, maintenance/retention.nix, hosts/workstation.nix, and a module contributing a second named policy. Include one disabled policy so the evaluator can reject flattening everything into a global retention period.

Assertions: correct settings.owned-only enum string; separate named temporary-root policies with exact regex/period/priority; system profile paths and keep-current-system/keep-booted-system/keep-latest-n; contributed and disabled policies preserved; service points to the generated TOML; timer survives. Source merges must retain host overrides. Evaluation checks policies and commands, not actual deletion.

Evidence: all three legacy options assert; new result policy evaluates with period seven days and default priority 100. There is no safe one-to-one rename from the old three global switches to the new policy model.

9. N10: Recursor schema migration without opening recursion

Proposed prompt: "nixos-rebuild rejects the old PowerDNS Recursor settings after the pin update. Preserve the loopback listener, client allow-list, forwarding zones, and nonstandard port. The lab and production hosts contribute different forwarders; neither may become an open resolver."

Fixture: dns/recursor.nix, dns/zones.nix, hosts/lab.nix, hosts/prod.nix. Old names and string lists are spread across modules; a second module already uses the YAML settings alias.

Assertions: toplevel evaluates; settings.incoming.allow_from/listen/port and settings.recursor.forward_zones[_recurse] contain intended structured values; DNSSEC policy and firewall remain; no stale flat keys are silently accepted through freeform settings; host values merge correctly. Evaluate serializer inputs, not only whether a derivation exists. Keep secrets and Lua configuration paths intact if present.

Evidence: old-settings removal asserts; new incoming allow_from list/port resolve correctly. Blindly copying old keys into the freeform new attrset can evaluate while configuring the wrong schema, so this requires semantic assertions.

10. N06: OAuth2 Proxy credentials across reusable instances

Proposed prompt: "nixos-rebuild refuses both OAuth2 Proxy secret definitions as world-readable. The host already provisions two runtime secret files. Preserve the client ID, callback URL, upstreams, cookie policy and provider-specific settings; the development host must keep its separate secret sources."

Fixture: auth/oauth2-proxy.nix, auth/provider.nix, hosts/prod.nix, hosts/dev.nix, and runtime-path declarations. Old client and cookie values arrive from different imported modules, forcing a complete migration.

Assertions: both toplevels evaluate; each has the correct client-secret and cookie-secret LoadCredential entries; command line uses credential-directory paths instead of secret contents; clientID/upstreams/redirect-url/provider/cookie settings survive; no dummy plaintext secret or Nix-store path masquerades as a runtime secret. Reject writeText/readFile-based secret laundering. Assert behavior on generated unit fields, not exact Nix syntax.

Evidence: two separate removed-option assertions. The source builds client-secret-file/cookie.secret-file arguments referencing %d and maps the new paths into LoadCredential.

11. P02: pnpm workspace fetcher metadata

Proposed prompt: "nix build stops during evaluation because our pnpm dependency fetcher has no version. Repair the packaging for the documented workspace while preserving the lockfile and offline dependency input. The repository includes dependency-hash metadata for the supported fetcher format; keep the application and CLI packages using the same dependency source."

Fixture: default.nix, pkgs/app.nix, pkgs/cli.nix, pkgs/pnpm-deps.nix, a fixed small workspace/lockfile, and dependency-hashes.nix carrying a previously established v4 hash. Include workspace selectors and a package override so the evaluator catches metadata dropped by a wrapper.

Assertions: real package drvPaths evaluate with IFD disabled; dependency fetcher version 4, plural workspace selection and intended lockfile/source; outputHash matches the supplied oracle; app/CLI point to the same intended dependency derivation; no fakeHash/empty hash; no unnecessary lockfile edits; host/build dependency placement remains correct. The evaluator cannot derive or validate a fresh network-content hash without fetching/building. A real precomputed v4 fixture hash is an authoring prerequisite; the research probe used fakeHash only to verify evaluation behavior.

Evidence: omitted version throws; explicit v4 evaluates. Versions 1/2 warn; version 3 is supported without that warning. Source throws on singular pnpmWorkspace. Do not claim v3 was removed.

12. P01: warning-free thread limits for package checks

Proposed prompt: "nix build emits the old OpenMP check-hook rename warning. The package family must use the supported helper without losing its check limits: default one thread, two for the heavy package, and a deliberate per-library override for one package. Keep limits out of the normal build phase."

Fixture: pkgs/common.nix, pkgs/numerics.nix, pkgs/heavy.nix, overlay.nix. One package uses checkPhase, another installCheckPhase; a host override sets OPENBLAS_NUM_THREADS independently. The migration is combined with an explicit shared packaging contract.

Assertions: evaluate derivations and collect stderr; no obsolete-alias warning; canonical hook derivation occurs in the relevant native check/build inputs; intended NIX_CHECK_PHASE_DEFAULT_NUM_THREADS and per-library override propagate to final derivation env; doCheck/doInstallCheck stay enabled. Read the pinned hook source to establish it registers preCheckHooks and preInstallCheckHooks, uses default 1, respects preexisting values, and can be disabled with dontLimitCheckPhaseThreads. Do not assert actual thread counts without running a process.

Evidence: alias and canonical name produce the identical drvPath. The alias alone is too trivial; the second contract supplies the repair substance. July 9 dates the alias, not necessarily the introduction of every behavior in hook.sh.

Too-trivial changes and combinations

N12, N13, N15, N17, N18, N22, N23, N24, P01, P08, P09 and most removals are likely to saturate if the only objective is to clear their first diagnostic. Helpful rename messages often tell the model exactly what to type. Several aliases deliberately preserve the old behavior, so a behavioral evaluator cannot distinguish their source spelling unless the public requirement includes eliminating the warning.

Use N13 with contributions from two modules and host-specific option priorities; N14/N22/N23 with generated-text and override requirements; N17 with multiple environment files and host ordering; N24 with independent server/client/unix behavior and its explicitly versioned package; N25 with the old state directory and changed unit name; N27 with a real image derivation and imageName/imageTag contract; N31 with preserving banner text while moving to a path-valued setting. Package removal alone should require retaining the needed function, not merely making the build stop mentioning it.

Good candidates for further work are N11's multiple frp units, N29's explicit PAM policy, N05's runtime Grafana secret source, and R54's Promtail-to-Alloy labels/position handling. R54 needs a pinned Alloy schema review before a trustworthy reference solution. Real storage, network, login and encryption behavior remains outside this evaluator's scope.

Verification method and probe ledger

Every N-series probe below imported the full pinned NixOS module list, set a minimal root filesystem and disabled GRUB, and forced config.system.build.toplevel.drvPath together with a focused value. These are not isolated fake evalModules tests. Defaults use system.stateVersion="26.05" unless a service-specific version is explicit. Neither a successful drvPath nor generated config is proof of boot or application runtime correctness.

Reproduce any N-series row by putting its body into this expression and its value expression into PROJECTION:

let
  s = import /nix/store/3zvg83mg9aavm9bgh26ydljchply7i25-source/nixos {
    system = "x86_64-linux";
    configuration = { lib, pkgs, ... }: {
      boot.loader.grub.enable = false;
      fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
      system.stateVersion = "26.05";
      # BODY
    };
  };
  c = s.config;
  lib = s.pkgs.lib;
in {
  drv = c.system.build.toplevel.drvPath;
  value = PROJECTION;
}

Run nix eval --offline --impure --option allow-import-from-derivation false --json --file probe.nix. Evaluation of package probes instead binds p = import PIN { system="x86_64-linux"; }; l=p.lib; and evaluates the listed expression. Future grading should also use a clean HOME and explicit package-set config/overlays, so host policy cannot change the result.

The ledger records final probes after fixture corrections, not every exploratory invocation. Home Assistant needed a non-null declarative config; Mattermost needed siteUrl and a projection excluding its removed driver; Kanidm needed an explicit versioned package. The Python deprecated-flag diagnostic assumes a source position: --expr first produced expected a set but found null, while evaluating the same expression from a real .nix file produced the intended error. These are fixture requirements, not fixes to nixpkgs.

Diagnostic blocks remove Nix stack frames and replace the long pinned path with <PIN>; the remaining text is captured output. Exit status is preserved. Successful drvPaths are deliberately recorded so each success proves derivation evaluation occurred. No repaired Immich success is claimed.

N01 probe

Old input, exit 1:

boot.initrd.postDeviceCommands = "echo ready";
error:
       Failed assertions:
       - systemd stage 1 does not support `boot.initrd.postDeviceCommands`. Instead, create systemd services using the `boot.initrd.systemd.services` options, which has an API matching the stage 2 `systemd.services` options. Refer to `bootup(7)`, specifically the sections on "Bootup in the Initrd" and "System Manager Bootup", for information about when various units happen, and order services accordingly.

           Definitions:
           - <PIN>/nixos/default.nix

New input, exit 0:

boot.initrd.systemd.services.ready = { wantedBy = [ "initrd.target" ]; after = [ "systemd-udev-settle.service" ]; serviceConfig.Type = "oneshot"; script = "echo ready"; };

Value expression: c.boot.initrd.systemd.enable.

{
  "drv": "/nix/store/hlcgc9isalvkcn4d4slpmsz6zmy2l693-nixos-system-nixos-26.05pre-git.drv",
  "value": true
}

N02 probe

Old input, exit 1:

services.yggdrasil.enable = true;services.yggdrasil.settings.PrivateKey = "not-a-real-key";
error:
       Failed assertions:
       - services.yggdrasil.settings.PrivateKey is not supported because it
       would be stored in the world-readable Nix store.
       Use services.yggdrasil.settings.PrivateKeyPath instead to securely load the private key from a file.

New input, exit 0:

services.yggdrasil.enable = true;services.yggdrasil.settings.PrivateKeyPath = "/run/secrets/ygg.pem";

Value expression: c.systemd.services.yggdrasil.serviceConfig.LoadCredential.

{
  "drv": "/nix/store/vsp9ppvkj95z8s4f7sgfgxkrsvqs75i4-nixos-system-nixos-26.05pre-git.drv",
  "value": [
    "private-key:/run/secrets/ygg.pem"
  ]
}

N03 probe

Old input, exit 1:

services.stalwart-mail.enable = true;
error: The option `services.stalwart.stateVersion' was accessed but has no value defined. Try setting the option.

New input, exit 0:

services.stalwart = { enable = true; stateVersion = "25.11"; };

Value expression: { inherit (c.services.stalwart) user group dataDir stateVersion; tracer = c.services.stalwart.settings.tracer; }.

{
  "drv": "/nix/store/g850ifxzi2x2hlnh3jq17n9cfshbcqi2-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "dataDir": "/var/lib/stalwart-mail",
    "group": "stalwart-mail",
    "stateVersion": "25.11",
    "tracer": {
      "stdout": {
        "ansi": false,
        "enable": true,
        "level": "info",
        "type": "stdout"
      }
    },
    "user": "stalwart-mail"
  }
}

N04 probe

Old input, exit 1:

services.cgit."git.test" = { enable = true; scanPath = "/srv/git"; };
error: The option `services.cgit."git.test".gitHttpBackend.checkExportOkFiles' was accessed but has no value defined. Try setting the option.

New input, exit 0:

services.cgit."git.test" = { enable = true; scanPath = "/srv/git"; };services.cgit."git.test" = { gitHttpBackend.checkExportOkFiles = true; settings.strict-export = "git-daemon-export-ok"; };

Value expression: c.services.cgit."git.test".gitHttpBackend.

{
  "drv": "/nix/store/jgib5mjvica3v7j99cbl3n9yr64wwmq0-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "checkExportOkFiles": true,
    "enable": true
  }
}

N05 probe

Old input, exit 1:

services.grafana.enable = true;
error:
       Failed assertions:
       - Grafana's secret key (services.grafana.settings.security.secret_key) doesn't have a default
       value anymore. Please generate your own and use a file-provider on this option! See also
       https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#secret_key
       for more information.

       See https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-database-encryption/#re-encrypt-secrets on how to re-encrypt.

       As stated in the NixOS changelog for 26.05, there's no official way to rotate.
       Either hard-code the old key ("SW2YcwTIb9zpOOhoPsMm") if your setup doesn't have any secrets in the DB that need
       special protection or perform a rotation with a 3rd-party tool
       (https://github.com/erooke/grafana-secretkey-rotation-tool/tree/d9dc788902fa5185e15cb15ce6129f7237ab6138).

New input, exit 0:

services.grafana.enable = true;services.grafana.settings.security.secret_key = "$__file{/run/secrets/grafana}";

Value expression: c.services.grafana.settings.security.secret_key.

{
  "drv": "/nix/store/r0qizhin1jf0i4671c1bx74qx1xhwxj3-nixos-system-nixos-26.05pre-git.drv",
  "value": "$__file{/run/secrets/grafana}"
}

N06 probe

Old input, exit 1:

services.oauth2-proxy = { enable = true; clientID = "demo"; };services.oauth2-proxy = { clientSecret = "dummy-client"; cookie.secret = "dummy-cookie"; };
error:
       Failed assertions:
       - The option definition `services.oauth2-proxy.cookie.secret' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       This option has been removed as it made the cookie secret world-readable.
       Use services.oauth2-proxy.cookie.secretFile instead.


       - The option definition `services.oauth2-proxy.clientSecret' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       This option has been removed as it made the client secret world-readable.
       Use services.oauth2-proxy.clientSecretFile instead.

New input, exit 0:

services.oauth2-proxy = { enable = true; clientID = "demo"; };services.oauth2-proxy = { clientSecretFile = "/run/secrets/client"; cookie.secretFile = "/run/secrets/cookie"; };

Value expression: { client = c.services.oauth2-proxy.clientSecretFile; cookie = c.services.oauth2-proxy.cookie.secretFile; }.

{
  "drv": "/nix/store/5b84jkn40pd5wj8kv3hbagjv730ag9d5-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "client": "/run/secrets/client",
    "cookie": "/run/secrets/cookie"
  }
}

N07 probe

Old input, exit 1:

services.angrr.enable = true;services.angrr = { period = "7d"; ownedOnly = true; removeRoot = true; };
error:
       Failed assertions:
       - The option definition `services.angrr.ownedOnly' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       This option has been removed since angrr 0.2.0.
       Please use `services.angrr.settings` to configure retention policies through configuration file.

       See <https://github.com/linyinfeng/angrr/tree/main?tab=readme-ov-file#nixos-module-usage> for a configuration example.


       - The option definition `services.angrr.removeRoot' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       This option has been removed since angrr 0.2.0.
       Please use `services.angrr.settings` to configure retention policies through configuration file.

       See <https://github.com/linyinfeng/angrr/tree/main?tab=readme-ov-file#nixos-module-usage> for a configuration example.


       - The option definition `services.angrr.period' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       This option has been removed since angrr 0.2.0.
       Please use `services.angrr.settings` to configure retention policies through configuration file.

       See <https://github.com/linyinfeng/angrr/tree/main?tab=readme-ov-file#nixos-module-usage> for a configuration example.

New input, exit 0:

services.angrr.enable = true;services.angrr.settings = { owned-only = "true"; temporary-root-policies.result = { path-regex = "/result$"; period = "7d"; }; };

Value expression: c.services.angrr.settings.

{
  "drv": "/nix/store/d3ggvyzyln91qx1m1ryibl06v8sb5hc6-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "owned-only": "true",
    "profile-policies": {},
    "temporary-root-policies": {
      "result": {
        "enable": true,
        "filter": null,
        "ignore-prefixes": null,
        "ignore-prefixes-in-home": null,
        "path-regex": "/result$",
        "period": "7d",
        "priority": 100
      }
    },
    "touch": {
      "project-globs": [
        "!.git"
      ]
    }
  }
}

N08 probe

Old input, exit 0:

networking.wireless.enable = true;networking.wireless.userControlled = { enable = true; group = "wheel"; };
{
  "drv": "/nix/store/vdmm2r0qp38q6nqrkshhbrfmp41ny3aj-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "groups": [],
    "user": "wpa_supplicant",
    "userControlled": true
  }
}

Captured stderr:

trace: Obsolete option `networking.wireless.userControlled.enable' is used. It was renamed to networking.wireless.userControlled
trace: Obsolete option `networking.wireless.userControlled.enable' is used. It was renamed to networking.wireless.userControlled

New input, exit 0:

networking.wireless.enable = true;networking.wireless.userControlled = true; users.users.demo = { isNormalUser = true; extraGroups = [ "wpa_supplicant" ]; };

Value expression: { userControlled = c.networking.wireless.userControlled; user = c.systemd.services.wpa_supplicant.serviceConfig.User; groups = c.users.users.demo.extraGroups or []; }.

{
  "drv": "/nix/store/v1lpv1rfs8liiprrp8nn3n5sa9iaz414-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "groups": [
      "wpa_supplicant"
    ],
    "user": "wpa_supplicant",
    "userControlled": true
  }
}

N09 probe

Old input, exit 0:

services.home-assistant = { enable = true; lovelaceConfig = { views = []; }; };services.home-assistant.config.lovelace.mode = "yaml";services.home-assistant.config.default_config = {};
{
  "drv": "/nix/store/0hr8wlf6006hi4xhg04lwinaw5z6x5k0-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "lovelace": {
      "dashboards": {
        "nixos-lovelace": {
          "filename": "ui-lovelace.yaml",
          "icon": "mdi:view-dashboard",
          "mode": "yaml",
          "show_in_sidebar": true,
          "title": "Overview"
        }
      },
      "mode": "yaml",
      "resource_mode": null
    },
    "warnings": [
      "services.home-assistant.config.lovelace.mode is deprecated.\nHome Assistant 2026.8 renames the legacy top-level `lovelace.mode`\nsetting in favour of per-dashboard configuration.\n\nUse `services.home-assistant.config.lovelace.dashboards` and\n`services.home-assistant.config.lovelace.resource_mode` instead.\n\nSee https://www.home-assistant.io/dashboards/dashboards/ for details.\n"
    ]
  }
}

Captured stderr:

evaluation warning: services.home-assistant.config.lovelace.mode is deprecated.
                    Home Assistant 2026.8 renames the legacy top-level `lovelace.mode`
                    setting in favour of per-dashboard configuration.

                    Use `services.home-assistant.config.lovelace.dashboards` and
                    `services.home-assistant.config.lovelace.resource_mode` instead.

                    See https://www.home-assistant.io/dashboards/dashboards/ for details.

New input, exit 0:

services.home-assistant = { enable = true; lovelaceConfig = { views = []; }; };services.home-assistant.config.default_config = {};

Value expression: { lovelace = c.services.home-assistant.config.lovelace; warnings = c.warnings; }.

{
  "drv": "/nix/store/126zn4qg3a5ggpr5fpj4da20qvks61cx-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "lovelace": {
      "dashboards": {
        "nixos-lovelace": {
          "filename": "ui-lovelace.yaml",
          "icon": "mdi:view-dashboard",
          "mode": "yaml",
          "show_in_sidebar": true,
          "title": "Overview"
        }
      },
      "resource_mode": null
    },
    "warnings": []
  }
}

N10 probe

Old input, exit 1:

services.pdns-recursor.enable = true;services.pdns-recursor.old-settings = { allow-from = "127.0.0.0/8"; local-port = 5353; };
error:
       Failed assertions:
       - The option definition `services.pdns-recursor.old-settings' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       pdns-recursor has changed its configuration file format from pdns-recursor.conf
       (mapped to `services.pdns-recursor.old-settings`) to the newer pdns-recursor.yml
       (mapped to `services.pdns-recursor.settings`).

       Support for the older format has been removed, please migrate your settings over.
       See <https://doc.powerdns.com/recursor/yamlsettings.html>.

New input, exit 0:

services.pdns-recursor.enable = true;services.pdns-recursor.settings = { incoming = { allow_from = [ "127.0.0.0/8" ]; port = 5353; }; };

Value expression: c.services.pdns-recursor.settings.

{
  "drv": "/nix/store/sbz1qpxi5lsiham571b8i0rdjq26n18y-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "dnssec": {
      "validation": "validate"
    },
    "incoming": {
      "allow_from": [
        "127.0.0.0/8"
      ],
      "listen": [
        "::",
        "0.0.0.0"
      ],
      "port": 5353
    },
    "logging": {
      "disable_syslog": true,
      "timestamp": false
    },
    "recursor": {
      "daemon": false,
      "export_etc_hosts": false,
      "forward_zones": [],
      "forward_zones_recurse": [],
      "lua_config_file": "/nix/store/7g1v7wz5mwc93xd4yzrivfrmy7dnrgr9-recursor.lua",
      "serve_rfc1918": true,
      "write_pid": false
    },
    "webservice": {
      "address": "0.0.0.0",
      "allow_from": [
        "127.0.0.1",
        "::1"
      ],
      "port": 8082
    }
  }
}

N11 probe

Old input, exit 0:

services.frp = { enable = true; role = "client"; settings.serverAddr = "relay.test"; };
{
  "drv": "/nix/store/d3sz8ilhy8w43gm7a8ij51wv4wplhwcm-nixos-system-nixos-26.05pre-git.drv",
  "value": [
    "frp"
  ]
}

Captured stderr:

evaluation warning: The option `services.frp.settings' defined in `<PIN>/nixos/default.nix' has been renamed to `services.frp.instances."".settings'.
evaluation warning: The option `services.frp.role' defined in `<PIN>/nixos/default.nix' has been renamed to `services.frp.instances."".role'.
evaluation warning: The option `services.frp.enable' defined in `<PIN>/nixos/default.nix' has been renamed to `services.frp.instances."".enable'.

New input, exit 0:

services.frp.instances = { edge = { enable = true; role = "client"; settings.serverAddr = "relay.test"; }; ingress = { enable = true; role = "server"; settings.bindPort = 7000; }; };

Value expression: builtins.filter (n: lib.hasPrefix "frp" n) (builtins.attrNames c.systemd.services).

{
  "drv": "/nix/store/zrxdhqvyhfrqk49k82szs4mjb3s5blzv-nixos-system-nixos-26.05pre-git.drv",
  "value": [
    "frp-edge",
    "frp-ingress"
  ]
}

N12 probe

Old input, exit 1:

environment.etc."resolv.conf".text = "nameserver 192.0.2.53
";
error:
       Failed assertions:
       - networking.resolvconf.enable is true but environment.etc."resolv.conf"
       is also set. Set networking.resolvconf.enable = false if another
       service manages /etc/resolv.conf.

New input, exit 0:

environment.etc."resolv.conf".text = "nameserver 192.0.2.53
"; networking.resolvconf.enable = false;

Value expression: c.networking.resolvconf.enable.

{
  "drv": "/nix/store/r5fh0ixjkqn02wa868r490jk20cs9ns2-nixos-system-nixos-26.05pre-git.drv",
  "value": false
}

N13 probe

Old input, exit 1:

services.openssh.enable = true;services.openssh.settings.AcceptEnv = "LANG LC_*";
error: A definition for option `services.openssh.settings.AcceptEnv' is not of type `null or (list of string)'. Definition values:
       - In `<PIN>/nixos/default.nix': "LANG LC_*"

New input, exit 0:

services.openssh.enable = true;services.openssh.settings.AcceptEnv = [ "LANG" "LC_*" ];

Value expression: c.services.openssh.settings.AcceptEnv.

{
  "drv": "/nix/store/izkw322xdf6d4yzaalx07d2kj5mhj2qy-nixos-system-nixos-26.05pre-git.drv",
  "value": [
    "LANG",
    "LC_*"
  ]
}

N14 probe

Old input, exit 1:

systemd.coredump.extraConfig = "Storage=journal
ProcessSizeMax=1G";
error:
       Failed assertions:
       - The option definition `systemd.coredump.extraConfig' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       Use systemd.coredump.settings.Coredump instead.

New input, exit 0:

systemd.coredump.settings.Coredump = { Storage = "journal"; ProcessSizeMax = "1G"; };

Value expression: c.environment.etc."systemd/coredump.conf".text.

{
  "drv": "/nix/store/aycbnf20wdf508l67l84dqm08lv8s2lm-nixos-system-nixos-26.05pre-git.drv",
  "value": "[Coredump]\nProcessSizeMax=1G\nStorage=journal\n\n"
}

N15 probe

Old input, exit 1:

fileSystems."/data".device = "/dev/sdb1";
error: The option `fileSystems."/data".fsType' was accessed but has no value defined. Try setting the option.

New input, exit 0:

fileSystems."/data".device = "/dev/sdb1";fileSystems."/data".fsType = "ext4";

Value expression: c.fileSystems."/data".fsType.

{
  "drv": "/nix/store/0172gxxx8bw1wc0am0p24nswckf1abqw-nixos-system-nixos-26.05pre-git.drv",
  "value": "ext4"
}

N16 probe

Old input, exit 1:

programs.captive-browser = { enable = true; interface = "wlan0"; }; networking.useDHCP = false; networking.dhcpcd.enable = false;
error: programs.captive-browser.dhcp-dns must be set

New input, exit 0:

programs.captive-browser = { enable = true; interface = "wlan0"; }; networking.useDHCP = false; networking.dhcpcd.enable = false;programs.captive-browser.dhcp-dns = "printf 192.0.2.53";

Value expression: c.programs.captive-browser.dhcp-dns.

{
  "drv": "/nix/store/njqpck35jhk1xghdnq1vsyzsngvcyi27-nixos-system-nixos-26.05pre-git.drv",
  "value": "printf 192.0.2.53"
}

N17 probe

Old input, exit 0:

services.homepage-dashboard.enable = true;services.homepage-dashboard.environmentFile = "/run/secrets/homepage";
{
  "drv": "/nix/store/qj6xczdlfscdb0bwvbpv33v0ick4dvi4-nixos-system-nixos-26.05pre-git.drv",
  "value": [
    "/run/secrets/homepage"
  ]
}

Captured stderr:

evaluation warning: The option `services.homepage-dashboard.environmentFile' defined in `<PIN>/nixos/default.nix' has been changed to `services.homepage-dashboard.environmentFiles' that has a different type. Please read `services.homepage-dashboard.environmentFiles' documentation and update your configuration accordingly.

New input, exit 0:

services.homepage-dashboard.enable = true;services.homepage-dashboard.environmentFiles = [ "/run/secrets/homepage" "/run/secrets/site" ];

Value expression: c.systemd.services.homepage-dashboard.serviceConfig.EnvironmentFile.

{
  "drv": "/nix/store/rc14rpmk013sa928050bxdzlqzfgb4mv-nixos-system-nixos-26.05pre-git.drv",
  "value": [
    "/run/secrets/homepage",
    "/run/secrets/site"
  ]
}

N18 probe

Old input, exit 1:

services.xserver.enable = true;services.xserver.videoDrivers = [ "not-a-driver" ];
error:
       Failed assertions:
       - Unknown X11 driver ‘not-a-driver’ specified in `services.xserver.videoDrivers`.

New input, exit 0:

services.xserver.enable = true;services.xserver.videoDrivers = [ "modesetting" ];

Value expression: c.services.xserver.videoDrivers.

{
  "drv": "/nix/store/v9vwsimhlgqy6hjd0kafvr8racg7zsa2-nixos-system-nixos-26.05pre-git.drv",
  "value": [
    "modesetting"
  ]
}

N19 probe

Old input, exit 1:

services.mattermost.enable = true;services.mattermost.database.driver = "mysql";services.mattermost.siteUrl = "https://chat.test";
error:
       Failed assertions:
       - The option definition `services.mattermost.database.driver' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       services.mattermost.database.driver has been removed, as the only option is 'postgres' in v11+.
       If you were using MySQL, please migrate to Postgres:
       https://docs.mattermost.com/deployment-guide/manual-postgres-migration.html

New input, exit 0:

services.mattermost.enable = true;services.mattermost.siteUrl = "https://chat.test";

Value expression: { database = c.services.mattermost.database.name; postgres = c.services.postgresql.enable; }.

{
  "drv": "/nix/store/znv5ncqm9qiagzi64xdb96l73i9n8w13-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "database": "mattermost",
    "postgres": true
  }
}

N20 probe

Old input, exit 0:

services.yggdrasil.enable = true;services.yggdrasil.persistentKeys = true;
{
  "drv": "/nix/store/g6dp8cxl0qq801kd0f4ca97yk361iga9-nixos-system-nixos-26.05pre-git.drv",
  "value": [
    "private-key:/var/lib/yggdrasil/private.pem"
  ]
}

New input, exit 0:

services.yggdrasil.enable = true;services.yggdrasil.settings.PrivateKeyPath = "/run/secrets/ygg.pem";

Value expression: c.systemd.services.yggdrasil.serviceConfig.LoadCredential.

{
  "drv": "/nix/store/vsp9ppvkj95z8s4f7sgfgxkrsvqs75i4-nixos-system-nixos-26.05pre-git.drv",
  "value": [
    "private-key:/run/secrets/ygg.pem"
  ]
}

N21 probe

Old input, exit 1:

services.yggdrasil.enable = true;services.yggdrasil.configFile = "/run/ygg.conf";
error: The option `services.yggdrasil.configFile' does not exist. Definition values:
       - In `<PIN>/nixos/default.nix': "/run/ygg.conf"

       Did you mean `services.yggdrasil.config', `services.yggdrasil.enable' or `services.yggdrasil.package'?

New input, exit 0:

services.yggdrasil.enable = true;services.yggdrasil.settings.Peers = [ "tcp://192.0.2.1:1234" ];

Value expression: c.services.yggdrasil.settings.Peers.

{
  "drv": "/nix/store/3cmi3iplq4xfdyfm6f6849q5m43ynf36-nixos-system-nixos-26.05pre-git.drv",
  "value": [
    "tcp://192.0.2.1:1234"
  ]
}

N22 probe

Old input, exit 1:

systemd.sleep.extraConfig = "AllowHibernation=no";
error:
       Failed assertions:
       - The option definition `systemd.sleep.extraConfig' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       Use systemd.sleep.settings.Sleep instead.

New input, exit 0:

systemd.sleep.settings.Sleep.AllowHibernation = false;

Value expression: c.environment.etc."systemd/sleep.conf".text.

{
  "drv": "/nix/store/ivinpzah3m8y10p01jxl1wa39wqkv6g8-nixos-system-nixos-26.05pre-git.drv",
  "value": "[Sleep]\nAllowHibernation=false\n\n"
}

N23 probe

Old input, exit 0:

services.resolved.enable = true;services.resolved.dnssec = "true";
{
  "drv": "/nix/store/70i07ysz35diqw6zspxmsfq6pn29q6rp-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "Resolve": {
      "DNS": [],
      "DNSOverTLS": false,
      "DNSSEC": "true",
      "Domains": []
    }
  }
}

Captured stderr:

evaluation warning: The option `services.resolved.dnssec' defined in `<PIN>/nixos/default.nix' has been renamed to `services.resolved.settings.Resolve.DNSSEC'.

New input, exit 0:

services.resolved.enable = true;services.resolved.settings.Resolve.DNSSEC = "true";

Value expression: c.services.resolved.settings.

{
  "drv": "/nix/store/70i07ysz35diqw6zspxmsfq6pn29q6rp-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "Resolve": {
      "DNS": [],
      "DNSOverTLS": false,
      "DNSSEC": "true",
      "Domains": []
    }
  }
}

N24 probe

Old input, exit 0:

services.kanidm.enableClient = true; services.kanidm.clientSettings.uri = "https://id.test";services.kanidm.package = pkgs.kanidm_1_9;
{
  "drv": "/nix/store/3izg80yqy46sgnwk779i0vjhps9dc7rs-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "uri": "https://id.test"
  }
}

Captured stderr:

evaluation warning: The option `services.kanidm.clientSettings' defined in `<PIN>/nixos/default.nix' has been renamed to `services.kanidm.client.settings'.
evaluation warning: The option `services.kanidm.enableClient' defined in `<PIN>/nixos/default.nix' has been renamed to `services.kanidm.client.enable'.
evaluation warning: kanidm 1.9 is deprecated and will reach end-of-life on 2026-05-31

                    Please upgrade by verifying `kanidmd domain upgrade-check` and choosing the
                    next version with `services.kanidm.package = pkgs.kanidm_1_x;`

                    See upgrade guide at https://kanidm.github.io/kanidm/master/server_updates.html

New input, exit 0:

services.kanidm.client = { enable = true; settings.uri = "https://id.test"; };services.kanidm.package = pkgs.kanidm_1_9;

Value expression: c.services.kanidm.client.settings.

{
  "drv": "/nix/store/3izg80yqy46sgnwk779i0vjhps9dc7rs-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "uri": "https://id.test"
  }
}

Captured stderr:

evaluation warning: kanidm 1.9 is deprecated and will reach end-of-life on 2026-05-31

                    Please upgrade by verifying `kanidmd domain upgrade-check` and choosing the
                    next version with `services.kanidm.package = pkgs.kanidm_1_x;`

                    See upgrade guide at https://kanidm.github.io/kanidm/master/server_updates.html

N25 probe

Old input, exit 0:

services.jellyseerr.enable = true;
{
  "drv": "/nix/store/bz7iqd74c0s5c409cn1a13sd79iy64y9-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "dir": "/var/lib/seerr/",
    "state": "seerr"
  }
}

Captured stderr:

evaluation warning: The option `services.jellyseerr' defined in `<PIN>/nixos/default.nix' has been renamed to `services.seerr'.

New input, exit 0:

services.seerr.enable = true;

Value expression: { dir = c.services.seerr.configDir; state = c.systemd.services.seerr.serviceConfig.StateDirectory; }.

{
  "drv": "/nix/store/bz7iqd74c0s5c409cn1a13sd79iy64y9-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "dir": "/var/lib/seerr/",
    "state": "seerr"
  }
}

N26 probe

Old input, exit 1:

services.immich.enable = true;services.immich.database = { enableVectors = true; enableVectorChord = true; };
error:
       Failed assertions:
       - The option definition `services.immich.database.enableVectors' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       `database.enableVectors` has been deprecated as pgvecto.rs is no longer available.
       From now on, vectorchord is used instead.


       - The option definition `services.immich.database.enableVectorChord' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       `database.enableVectorChord` has been deprecated as the pgvecto.rs alternative
       is no longer available. From now on, vectorchord is always enabled.

New input, exit 1:

services.immich.enable = true;

Value expression: c.services.immich.database.enable.

error: Refusing to evaluate package 'immich-2.7.5' in <PIN>/pkgs/by-name/im/immich/package.nix:302 because it is marked as insecure

       Known issues:
        - Immich 2.x.x will not receive further updates. Immich 3.x.x is available in NixOS 26.11 (unstable at the time of writing)
        - CVE-2026-59258
        - CVE-2026-82272

       You can install it anyway by allowing this package, using the
       following methods:

       a) To temporarily allow all insecure packages, you can use an environment
          variable for a single invocation of the nix tools:

            $ export NIXPKGS_ALLOW_INSECURE=1

          Note: When using `nix shell`, `nix build`, `nix develop`, etc with a flake,
                then pass `--impure` in order to allow use of environment variables.

       b) for `nixos-rebuild` you can add ‘immich-2.7.5’ to
          `nixpkgs.config.permittedInsecurePackages` in the configuration.nix,
          like so:

            {
              nixpkgs.config.permittedInsecurePackages = [
                "immich-2.7.5"
              ];
            }

       c) For `nix-env`, `nix-build`, `nix-shell` or any other Nix command you can add
          ‘immich-2.7.5’ to `permittedInsecurePackages` in
          ~/.config/nixpkgs/config.nix, like so:

            {
              permittedInsecurePackages = [
                "immich-2.7.5"
              ];
            }

N27 probe

Old input, exit 1:

services.kubernetes.addons.dns.coredns = { imageName = "coredns/coredns"; imageDigest = "sha256:0000000000000000000000000000000000000000000000000000000000000000"; sha256 = lib.fakeHash; };
error: A definition for option `services.kubernetes.addons.dns.corednsImage' is not of type `package'. Definition values:
       - In `<PIN>/nixos/modules/services/cluster/kubernetes/addons/dns.nix':
           {
             imageDigest = "sha256:0000000000000000000000000000000000000000000000000000000000000000";
             imageName = "coredns/coredns";
             sha256 = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
           }

New input, exit 0:

Value expression: c.services.kubernetes.addons.dns.corednsImage.drvPath.

{
  "drv": "/nix/store/m4365isvd3ip1hvm738zin1l7gfbdfcy-nixos-system-nixos-26.05pre-git.drv",
  "value": "/nix/store/m939rnh5gq6pcidn5cx4l14y3hwasmhx-docker-image-coredns.tar.gz.drv"
}

N28 probe

Old input, exit 1:

services.mosquitto.enable = true;services.mosquitto.package = pkgs.mosquitto.overrideAttrs { version = "2.0.99"; };
error:
       Failed assertions:
       - services.mosquitto.package must be at least version 2.1, since the generated
       configuration relies on the acl-file and password-file plugins.

New input, exit 0:

services.mosquitto.enable = true;

Value expression: c.services.mosquitto.package.version.

{
  "drv": "/nix/store/d7w3zf1a7jm4xkhh6n2g4miz3iqi1hm0-nixos-system-nixos-26.05pre-git.drv",
  "value": "2.1.2"
}

N29 probe

Old input, exit 0:

services.vsftpd = { enable = true; localUsers = true; };
{
  "drv": "/nix/store/rjryrgs1zxr8h6h8cl8rcxn0izqk38fl-nixos-system-nixos-26.05pre-git.drv",
  "value": false
}

New input, exit 0:

services.vsftpd = { enable = true; localUsers = true; };services.vsftpd = { enableVirtualUsers = true; userDbPath = "/run/secrets/ftp-users"; };

Value expression: c.security.pam.services ? vsftpd.

{
  "drv": "/nix/store/s2irpbfqparafisd5gpgjqrb04vkpjjj-nixos-system-nixos-26.05pre-git.drv",
  "value": true
}

N30 probe

Old input, exit 0:

services.taskchampion-sync-server.enable = true;services.taskchampion-sync-server.dynamicUser = false;
{
  "drv": "/nix/store/q8q4gv8drl4ax8rx8r213w6ngvxlwzf4-nixos-system-nixos-26.05pre-git.drv",
  "value": false
}

New input, exit 0:

services.taskchampion-sync-server.enable = true;

Value expression: c.systemd.services.taskchampion-sync-server.serviceConfig.DynamicUser.

{
  "drv": "/nix/store/dhs11jacbma2v4i76rgs33z02ld0ra72-nixos-system-nixos-26.05pre-git.drv",
  "value": true
}

N31 probe

Old input, exit 1:

services.openssh.enable = true;services.openssh.banner = "Authorized users only";
error:
       Failed assertions:
       - The option definition `services.openssh.banner' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       Use services.openssh.settings.Banner instead.

New input, exit 0:

services.openssh.enable = true;services.openssh.settings.Banner = "/etc/ssh/banner"; environment.etc."ssh/banner".text = "Authorized users only";

Value expression: c.services.openssh.settings.Banner.

{
  "drv": "/nix/store/kp00263qmjvygiczhxrkvpjrrij0iw23-nixos-system-nixos-26.05pre-git.drv",
  "value": "/etc/ssh/banner"
}

N32 probe

Old input, exit 1:

services.dovecot2.enable = true;services.dovecot2 = { enableImap = true; enablePop3 = false; sslServerCert = "/run/secrets/mail.crt"; sslServerKey = "/run/secrets/mail.key"; mailLocation = "maildir:~/Maildir"; extraConfig = "auth_verbose = yes"; };
error:
       Failed assertions:
       - The option definition `services.dovecot2.extraConfig' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       Please use services.dovecot2.settings instead.

       - The option definition `services.dovecot2.mailLocation' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       Use `settings.mail_location` for Dovecot 2.3, `settings.mail_path` for 2.4.

       - The option definition `services.dovecot2.sslServerKey' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       Use `settings.ssl_key` for Dovecot 2.3, `settings.ssl_server_key_file` for 2.4.

       - The option definition `services.dovecot2.sslServerCert' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       Use `settings.ssl_cert` for Dovecot 2.3, `settings.ssl_server_cert_file` for 2.4.

       - The option definition `services.dovecot2.enableImap' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       Set 'services.dovecot2.settings.protocols.imap = true/false;' instead.

       - The option definition `services.dovecot2.enablePop3' in `<PIN>/nixos/default.nix' no longer has any effect; please remove it.
       Set 'services.dovecot2.settings.protocols.pop3 = true/false;' instead.

       - services.dovecot2: Since Dovecot 2.4, the option 'services.dovecot2.settings.dovecot_config_version' must be explicitly set.
        To retain compatibility with future updates, set the following and manually update as needed.

            services.dovecot2.settings.dovecot_config_version = "2.4.5";

        Alternatively, you can automatically update to newer versions of the configuration format, which might break compatibility with future updates.

            services.dovecot2.settings.dovecot_config_version = config.services.dovecot2.package.version;

        See <https://doc.dovecot.org/latest/installation/upgrade/2.3-to-2.4.html>.

       - services.dovecot2: Since Dovecot 2.4, the option 'services.dovecot2.settings.dovecot_storage_version' must be explicitly set.
        Set it to the oldest version the storage should stay compatible with, for example the following for the currently selected version.

            services.dovecot2.settings.dovecot_storage_version = "2.4.5";

        See <https://doc.dovecot.org/latest/installation/upgrade/2.3-to-2.4.html>.

New input, exit 0:

services.dovecot2.enable = true;services.dovecot2.settings = { protocols = { imap = true; pop3 = false; }; ssl_server_cert_file = "/run/secrets/mail.crt"; ssl_server_key_file = "/run/secrets/mail.key"; mail_driver = "maildir"; mail_path = "~/Maildir"; };services.dovecot2.settings = { dovecot_config_version = "2.4.5"; dovecot_storage_version = "2.4.5"; };

Value expression: { version = c.services.dovecot2.package.version; protocols = c.services.dovecot2.settings.protocols; cert = c.services.dovecot2.settings.ssl_server_cert_file; path = c.services.dovecot2.settings.mail_path; }.

{
  "drv": "/nix/store/f5h41izg63q5x68hv83m5fzjqnsxas10-nixos-system-nixos-26.05pre-git.drv",
  "value": {
    "cert": "/run/secrets/mail.crt",
    "path": "~/Maildir",
    "protocols": {
      "_section": {
        "name": null,
        "type": "protocols"
      },
      "imap": true,
      "pop3": false
    },
    "version": "2.4.5"
  }
}

P01 probe

Old input, exit 0:

p.openmpCheckPhaseHook.drvPath
"/nix/store/jqrzkx286swypmr7bfwmnddib0n7gg5v-check-phase-thread-limit-hook.drv"

Captured stderr:

evaluation warning: 'openmpCheckPhaseHook' has been renamed to 'checkPhaseThreadLimitHook' to reflect its handling of all known thread-limiting mechanisms during check phase

New input, exit 0:

p.checkPhaseThreadLimitHook.drvPath
"/nix/store/jqrzkx286swypmr7bfwmnddib0n7gg5v-check-phase-thread-limit-hook.drv"

P02 probe

Old input, exit 1:

(p.fetchPnpmDeps { pname = "probe"; src = p.path; hash = l.fakeHash; }).drvPath
error: fetchPnpmDeps: `fetcherVersion` is not set, see https://nixos.org/manual/nixpkgs/stable/#javascript-pnpm-fetcherVersion.

New input, exit 0:

(p.fetchPnpmDeps { pname = "probe"; src = p.path; hash = l.fakeHash; fetcherVersion = 4; pnpmWorkspaces = [ "app" ]; }).drvPath
"/nix/store/j6qr7vmzqkj9h4nh0hx30vgwmzj3nslm-probe-pnpm-deps.drv"

P03 probe

Old input, exit 0:

(p.stdenv.mkDerivation { name = "probe"; buildInputs = [ [ p.zlib ] ]; }).drvPath
"/nix/store/nmkgsf6vjqwpzfcmclq5sqa01hd5q24j-probe.drv"

Captured stderr:

evaluation warning: Dependency of package 'probe' uses a nested list in attribute 'buildInputs'.
                    This is deprecated as of Nixpkgs release 26.05, and support will
                    be removed in a future nixpkgs release.

New input, exit 0:

(p.stdenv.mkDerivation { name = "probe"; buildInputs = [ p.zlib ]; }).drvPath
"/nix/store/nly7cqql0qzycbrvik86pdhy77rhafbi-probe.drv"

P04 probe

Old input, exit 1:

(p.python3Packages.buildPythonPackage { pname = "probe"; version = "1"; src = p.path; }).drvPath
error: python3.13-probe-1 does not configure a `format`. To build with setuptools as before, set `pyproject = true` and `build-system = [ setuptools ]`.

New input, exit 0:

(p.python3Packages.buildPythonPackage { pname = "probe"; version = "1"; src = p.path; pyproject = true; build-system = [ p.python3Packages.setuptools ]; }).drvPath
"/nix/store/kxvggiw6n0a2g7rlsf53b0wvgjh8rpdz-python3.13-probe-1.drv"

P05 probe

Old input, exit 1:

(p.python3Packages.buildPythonPackage { pname = "probe"; version = "1"; src = p.path; pyproject = true; pytestFlagsArray = [ "-k" "offline" ]; }).drvPath
error: buildPythonPackage: Deprecated flag pytestFlagsArray found at /tmp/nixbench-pytest-old.nix:1
         Use pytestFlags or (enabled|disabled)(TestPaths|Tests|TestMarks) instead.

Executed from /tmp/nixbench-pytest-old.nix to supply a real source location.

New input, exit 0:

(p.python3Packages.buildPythonPackage { pname = "probe"; version = "1"; src = p.path; pyproject = true; pytestFlags = [ "-k" "offline" ]; }).drvPath
"/nix/store/wjvwpfyqv7flq7rs5py5xm4af6z6w1s6-python3.13-probe-1.drv"

P06 probe

Old input, exit 1:

(p.rustPlatform.buildRustPackage { pname = "probe"; version = "1"; src = p.path; cargoHash = l.fakeHash; useFetchCargoVendor = false; }).drvPath
error: buildRustPackage: `useFetchCargoVendor` is non‐optional and enabled by default as of 25.05, remove it

New input, exit 0:

(p.rustPlatform.buildRustPackage { pname = "probe"; version = "1"; src = p.path; cargoHash = l.fakeHash; }).drvPath
"/nix/store/rbx2c2vf0ykq9kd1rss0grg6s2lsp4m0-probe-1.drv"

P07 probe

Old input, exit 0:

(p.fetchgit { url = "https://invalid.test/repo"; hash = l.fakeHash; }).drvPath
"/nix/store/kqqznykvdclxzyw0irwb0cs2n7zjap5z-repo.drv"

New input, exit 0:

(p.fetchgit { url = "https://invalid.test/repo"; tag = "v1"; hash = l.fakeHash; }).drvPath
"/nix/store/iacsx67iqcsbjds8dgk1hj9fyv43q218-repo.drv"

P08 probe

Old input, exit 0:

(l.types.listOf l.types.str).functor.wrapped.name
"str"

Captured stderr:

evaluation warning: The deprecated `functor.wrapped` attribute is accessed, use `nestedTypes.elemType` instead.

New input, exit 0:

(l.types.listOf l.types.str).nestedTypes.elemType.name
"str"

P09 probe

Old input, exit 1:

p.omxplayer.drvPath
error: 'omxplayer' has been removed because it depends on a severely outdated upstream, a severely outdated FFmpeg, and the new upstream was deprecated since 2020. Please use 'vlc' instead.

New input, exit 0:

p.vlc.drvPath
"/nix/store/dfz0xhzw3nyks0avfbcw7r38j7zn8m56-vlc-3.0.23-2.drv"

P10 probe

Old input, exit 1:

p.stardust-xr-kiara.drvPath
error:

New input, exit 0:

builtins.hasAttr "stardust-xr-kiara" p
true

This hasAttr control only demonstrates that the throwing alias still exists. It is not a repaired package.

P11 probe

Old input, exit 1:

p.xorg.overrideScope (final: prev: {})
error: The xorg package set has been moved to the top level.

New input, exit 0:

(p.extend (final: prev: { libx11 = prev.libx11; })).libx11.drvPath
"/nix/store/8qzj1sq2clff9a50c0d65i6xnsbzis27-libx11-1.8.13.drv"

R07 supplemental import probe

The full NixOS baseline with imports = [ (modulesPath + "/profiles/hardened.nix") ]; evaluated successfully, exit 0. The projection was { drv = s.config.system.build.toplevel.drvPath; warnings = s.config.warnings; } and returned:

{"drv":"/nix/store/m4365isvd3ip1hvm738zin1l7gfbdfcy-nixos-system-nixos-26.05pre-git.drv","warnings":[]}

This is the same derivation as the baseline without the import. It establishes a silent loss of the old profile, not an import error. No replacement hardening policy was evaluated for R07.

Coverage and authoring limits

The 26.05 inventory covers all incompatibility entries, all changed defaults, all noted removals/renames/restructures, and relevant notable-change APIs. systemd.network.* gaining upstream networkd 259 options is an additive schema expansion, not a demonstrated old-form error. Optional xpadneo settings, SSH recommended-algorithm opt-out, Drupal installation settings and other new opt-in capabilities do not establish a memory trap; they were read and excluded. The 26.11 new service modules are likewise additions, not breaking migrations.

The following work is still required before building a genuinely fresh benchmark pool:

  1. Date the introduction commits, especially for the top NixOS migrations. The static pin cannot establish those dates. Keep dated-pre-June rows out regardless of difficulty.
  2. Build complete multi-file starter/reference fixtures and mutation tests. The probes here validate individual changes, not full task acceptance criteria.
  3. Supply real precomputed dependency hashes for packaging tasks. This research did not fetch dependencies or validate build outputs.
  4. For generated files, inspect the generating derivation's text/structured attributes or module settings without importing a build result. Avoid readFile on unbuilt store outputs, which would violate the no-build contract.
  5. Decide whether warnings are an explicit objective. An unchanged compatibility alias may be a valid solution to a purely behavioral prompt.