1 54 Flakes and Inputs
Nimmo edited this page 2026-09-13 13:03:59 +01:00

Flakes and Inputs

  • Type: Tutorial
  • Status: Current
  • Scope: Reading the root flake, lock file, host outputs, and input policy in nixos-config
  • Canonical sources: flake.nix; flake.lock; lib/auto-update-policy.nix; modules/services/redview.nix; modules/services/jellyfin.nix; Flakes on nix.dev; Adding Packages and Flake Inputs
  • Last verified: Source commit 556df88494686003b1c4f20c8e0b99b5afc16a6e (2026-09-12); source HEAD b2831d33132967b4c4fb69e6068b2b05fff8fdff changes only flake.lock. Root inputs/outputs, examples, and policy shape checked 2026-09-13; no input was updated.
  • Review triggers: Flake inputs/outputs, stable/unstable host selection, external package output shapes, lock/update policy, or linked upstream explanation

Learning goal and prerequisites

Explain where this repository obtains external code, which targets it exposes, and why a new input needs both a lock entry and update-policy classification. Read the Guided Repository Tour and Nix Language Essentials first. For general flake semantics, use the official nix.dev Flakes concept; this page teaches this repository's shape, not every flake feature.

Read flake.nix in four passes

First, inputs declares roots. nixpkgs tracks unstable; nixpkgs-stable tracks NixOS 26.05 for Cosmos and Chaos. Home Manager has matching unstable and stable inputs. Other roots supply hardware modules, Disko, SOPS, packages/services, the standalone updater, and formatting. flake.lock records the resolved graph and revisions. A URL in flake.nix alone is not an exact build record, while a lock file alone does not declare which output a host consumes. Do not hand-edit the lock file.

Second, follow inputs.<name>.inputs.nixpkgs.follows = "nixpkgs" where it exists. It asks that input to use this root's Nixpkgs dependency. It is not universal: the Redview input currently has no such follows declaration. bash-it and pi-ollama have flake = false, meaning their fetched source is consumed as a path, not as a flake with packages or nixosModules outputs. Do not copy an output expression without checking its real shape.

Third, inspect the outputs function. It binds named inputs and the entire set as inputs; makeNixosSystem then calls the chosen Nixpkgs lib.nixosSystem. Its host import is ./hosts/${configName}. The builder adds common external modules, passes inputs to NixOS modules via specialArgs, and separately configures Home Manager. The next tutorial explains module merging and the later one explains the two argument paths.

Fourth, inspect nixosConfigurations, checks, packages, and formatter. The six registered hosts are Electra, Lena, Vega, Lyra, Cosmos, and Chaos. Cosmos/Chaos pass the stable Nixpkgs and matching Home Manager inputs to the same builder; a selected package may still come from a different input. For example, Lyra's Jellyfin module explicitly chooses a stable Jellyfin package while Lyra itself remains an unstable host. The root flake also exports the deployment/remediation packages, formatting check, and pinned updater state-machine check. potential/nova is not a flake target, so it is not one of the host outputs.

Why update policy is part of the input story

lib/auto-update-policy.nix maps each root input to the hosts that actually consume it, or deliberately pins it. flake.nix derives the rootInputs inventory from its input argument set so an unclassified input can be rejected by the guarded update producer. A transitive shared input can affect several hosts even when only one module visibly mentions it. This is a validation map, not a statement that all hosts run the same channel or service. ADR-005 explains the producer/consumer design; Adding Packages and Flake Inputs gives the change procedure.

Guided check

Without changing the lock file, trace redview from its root input in flake.nix through modules/services/redview.nix to the Lyra host import. Identify the external nixosModules output, the package output keyed by pkgs.stdenv.hostPlatform.system, and the corresponding update-policy group. Then compare the nixpkgs-stable host-builder use with the narrow Jellyfin package use. The same input can play different roles; name the consumer rather than saying merely that the fleet "uses stable."

Common mistakes: assuming every input has packages.<system>.default, assuming flake = false produces flake outputs, changing a root input without policy/consumer builds, or claiming a registered host was deployed because its flake output evaluates. The authoritative engineering steps are in Adding Packages and Flake Inputs.