From 2efd95d0f57d78234472de520afe161781cc4eaf Mon Sep 17 00:00:00 2001 From: atlas Date: Thu, 18 Jun 2026 10:46:26 +0200 Subject: [PATCH] nix(ci): pin the runner readiness gate to --store daemon A bare `nix store ping` run as root with the daemon socket absent resolves to a local store (root writes /nix/store directly) and pings successfully, so the gate could false-pass at cold boot: nix-daemon.socket carries ConditionPathIsReadWrite=/nix/var/nix/daemon-socket and is condition-skipped until /nix/var goes read-write. systemd service units don't source the profile that sets NIX_REMOTE=daemon, so auto-store fallback to local is the real environment here. Pin --store daemon so the readiness poll verifies the actual daemon socket and the gate honours its wait-for-daemon contract instead of passing against a local fallback while the daemon is still down. --- nix/modules/hive-ci.nix | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/nix/modules/hive-ci.nix b/nix/modules/hive-ci.nix index 19e892fd..a4168136 100644 --- a/nix/modules/hive-ci.nix +++ b/nix/modules/hive-ci.nix @@ -480,8 +480,24 @@ in # only bites in the post-restart cold window. Non-fatal shape: # if it never comes up the unit fails cleanly (recoverable) # rather than the runner claiming jobs into a dead daemon. + # + # `--store daemon` is load-bearing. A bare `nix store ping` + # uses the `auto` store, which — when run as root with the + # daemon socket absent — silently resolves to a LOCAL store + # (root can write /nix/store directly) and pings successfully. + # systemd service units don't source the profile that sets + # `NIX_REMOTE=daemon`, so this is the real environment here. + # At cold boot the daemon socket IS absent: nix-daemon.socket + # carries `ConditionPathIsReadWrite=/nix/var/nix/daemon-socket` + # and is condition-skipped until /nix/var goes read-write. So + # a bare ping would pass against the local store while the + # daemon is still down — defeating the gate's whole purpose + # (the runner would start and claim jobs the daemon can't yet + # service). Pinning `--store daemon` makes the poll verify the + # actual daemon socket, so the gate honours its contract and + # waits until the daemon — not a local fallback — answers. for _ in $(seq 1 90); do - if ${pkgs.nix}/bin/nix store ping >/dev/null 2>&1; then + if ${pkgs.nix}/bin/nix store ping --store daemon >/dev/null 2>&1; then exit 0 fi sleep 2