diff --git a/nix/module-eval.nix b/nix/module-eval.nix index 2e9bfbb1..73b49a84 100644 --- a/nix/module-eval.nix +++ b/nix/module-eval.nix @@ -233,17 +233,32 @@ let # local mints certificates off-host — so this orders against nothing. # Eval cannot see that failure; only the empty list here stands in for it. name = "an off-host reader requires no unit the store's host would have provided"; - ok = baoRemoteReader.systemd.services.swarm-bao-matrix-token.requires == [ ]; + # Membership first, then the value: indexing a missing unit throws, and a + # table that reports which property broke must not be the thing that dies. + ok = + let + s = baoRemoteReader.systemd.services; + in + s ? swarm-bao-matrix-token && s.swarm-bao-matrix-token.requires == [ ]; } { # Presence control for the case above: the list is conditional, not gone. name = "a co-located reader still orders after the local pki unit"; - ok = baoWithMatrix.systemd.services.swarm-bao-matrix-token.requires == [ "swarm-bao-pki.service" ]; + ok = + let + s = baoWithMatrix.systemd.services; + in + s ? swarm-bao-matrix-token && s.swarm-bao-matrix-token.requires == [ "swarm-bao-pki.service" ]; } ]; bad = builtins.filter (c: !c.ok) cases; - report = lib.concatMapStringsSep "\n" (c: " echo 'FAILED: ${c.name}' >&2") bad; + # Escaped, because a name is prose and prose contains apostrophes. Hand-quoting + # broke the builder mid-report on the first such name that failed — and only + # ever on failure, so every green run agreed the reporter was fine. + report = lib.concatMapStringsSep "\n" ( + c: " echo ${lib.escapeShellArg "FAILED: ${c.name}"} >&2" + ) bad; in # The results are embedded in the builder text on purpose: that is what # makes this derivation's hash depend on them, so a nix-only change that