Conversation
modules here are minimally maintained by design and finix moves fast, so the question worth answering per module is "what finix commit did this last work with". nothing in the repository could answer it: `nix flake check` had no checks to run. tests live next to the module they cover, one file per test, and each is checked at up to two depths. `eval` imports the module into an otherwise minimal finix system, enables it and instantiates the closure - cheap, and it catches the option and api drift that actually breaks these modules. `vm` boots that same system and asserts the module does its job, using finix's own test driver so a test file here looks like a test file there. every module is covered. the ones that need a gpu, a seat or real hardware are eval-only and carry a note saying why, which the table quotes. a module with no tests/ directory fails `-A registration`, so nothing can quietly drop off. packages come from the nixpkgs finix pins rather than ours, so a result depends on the finix commit alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H5hyFo8fsCYDxrjArxyUuJ
runs the suite on every push, on every pull request and daily, against finix main rather than the pin in lon.lock, and merges the result into COMPATIBILITY.md: per module, the last finix commit it was known to work with. that last part is why there is a state file. a run can only see whether a module works *now*; the commit it last worked with is remembered from previous runs, so a module that falls behind keeps pointing at the commit where it was still fine instead of just going blank. module failures are recorded, not fatal - the table exists to say which modules have fallen behind. `nix flake check` is the gate that goes red, and it runs against the pinned finix. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H5hyFo8fsCYDxrjArxyUuJ
dinit's job on a finix host is the per-user session - finit is pid 1 - and the module writes `dinit.user.services` to /etc/dinit.d/user, which is one of the directories `dinit --user` searches. that is testable, so test it: boot a host, start dinit as an unprivileged user, and check it runs a scripted service, supervises a process service as that user, applies the env-file the module generated, and restarts the process when it is killed. the system half stays eval-only and says why in its own file: those land in /etc/dinit.d for a dinit running as system service manager, and nothing on a finix host picks them up. notes are now attributed per test rather than per module, since dinit has one of each; the table gained a "what is not booted, and why" section that names the test instead of implying the whole module is eval-only. also copy the generated table with `install -m 644` - copying a store path's mode along left it read-only, and the second run could not overwrite it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H5hyFo8fsCYDxrjArxyUuJ
the eleven modules that were eval-only each got a vm test, because in every case there was more to check than "it evaluates": - amnezia-vpn and v2rayn are gui clients, but the module ships a daemon in one case and a wrapper that links the xray/sing-box cores into the user's data directory in the other, and both run headless - dinit's system half is supervised under `dinit --container`, which is a system service manager that does not try to be pid 1 - gamescope and river both have headless backends; river's test also covers the rebuild against libudev-zero that picking mdevd forces - openrgb's sdk server does not need a controller to accept clients - pipewire runs with an empty graph when there is no sound card - preservation is checked where it actually acts: the initrd, with a volume mounted for boot and the declared paths bind-mounted onto it by the time the machine is up - soteria gets as far as a headless machine can: polkit up, the service loaded, and the agent started at the graphical runlevel it asks for - steam stops at its fhs environment and the 32-bit driver path, which is the expensive-but-bounded part - the laptop profile is booted and checked for the seat, device, network, power and firewall services it picks console waits are bounded now. without a timeout a machine that fails to boot holds the driver until its hour-long global timeout, which is a bad way to spend a ci run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H5hyFo8fsCYDxrjArxyUuJ
every one of these was the test being wrong about the environment, not the module: - three separate things broke on /tmp being mode 755 in the driver's tmpfs root - dinit's control socket, xwayland under river, home-manager's activation - so the tests that need it mount /tmp as its own tmpfs - tailscaled and openrgb do not run under the name their binary suggests: one goes through a generated script, the other is qt-wrapped. match on the command line - tailscale's unit waits for `net/route/default`, and the test network is a static /24 with no gateway. the test now asserts the daemon waits, adds a route, and asserts it starts - which covers the condition properly - gamescope needs vulkan even headless, so the host gets lavapipe, and the icd is globbed rather than named after an architecture - pipewire's generated config lands in /etc/pipewire - amnezia-vpn ships no dbus policy at all, so there was nothing to assert there; the test says what the module actually gets from dbus - nix-ld's loader name now follows the platform instead of hardcoding x86_64 home-manager cannot run activation in the test vm: it sets the generation profile with nix-env and /nix is a read-only 9p mount. the test checks the service the module wires in, the generation it points at, and the managed file built into it, and says so in the file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H5hyFo8fsCYDxrjArxyUuJ
efistubmgr and nh had no tests/ directory, which fails the compat suite's
registration check. nh gets full vm tests (cli install + NH_FLAKE wiring,
and the clean.enable scheduler task via the cron backend); efistubmgr is
eval-only, since finix's qemu test driver has no UEFI/OVMF support to give
its install hook real NVRAM to act on.
Also groups the generated COMPATIBILITY.md table by modules/{programs,
services,profiles} instead of one flat list, with an "other" catch-all so
nothing placed outside those directories silently drops off the table.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012chuWZeJQ9d4Hc9fNviG9m
river: riverctl/rivertile were split out of river 0.4 and nixpkgs packages neither, so the test's init script (and the subtest calling riverctl directly) could never work; drop both, the init script only needs to prove it ran. soteria: two real bugs surfaced by actually booting it (previously eval-only). The module's compiled-in polkit-agent-helper-1 path comes from whatever polkit soteria happened to be built against, which is not the (overridden) one `services.polkit` deploys here - point it at the real wrapper via /etc/soteria/config.toml. And soteria reads XDG_SESSION_ID from its own environment, so it can't run as a system finit service with no login session; it's now installed only, meant to be started from wherever a session already starts other session programs (documented in the option), and the vm test proves this end to end via a real autologin + elogind session with a headless river compositor giving its gtk4 UI a display to attach to. xinetd/steam test tweaks from local debugging carried along as-is. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012chuWZeJQ9d4Hc9fNviG9m
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.