From 8a7f254c741f100f0fa69e989ce64b0b780caa6d Mon Sep 17 00:00:00 2001 From: atlas Date: Sun, 1 Nov 2026 22:20:15 +0100 Subject: [PATCH] remove c0re.preBuildAgentTemplates and agentBaseToplevel --- docs/scheduler/coordinator.md | 22 ---------- flake.nix | 8 ---- nix/host-modules/deploy.nix | 27 ++++++++---- nix/host-modules/hive-c0re/default.nix | 10 ----- nix/host-modules/hive-c0re/options.nix | 59 ++++++++++---------------- nix/module-eval/core-toggle.nix | 48 ++++++++++++++++++--- nix/packages/default.nix | 8 +--- 7 files changed, 84 insertions(+), 98 deletions(-) diff --git a/docs/scheduler/coordinator.md b/docs/scheduler/coordinator.md index 8ab87edf..0b62fc7b 100644 --- a/docs/scheduler/coordinator.md +++ b/docs/scheduler/coordinator.md @@ -515,28 +515,6 @@ For a hive-wide cap across all containers together, set `systemd.slices.machine.serviceConfig.CPUQuota` in your NixOS config — all nspawn containers live in `machine.slice`. -### Pre-building agent templates - -`preBuildAgentTemplates` (default `false`) causes the host NixOS -build to pre-fetch the `agent-base` container system closure, which every -agent builds from, into `/nix/store`, instead of -leaving that work to the first `nixos-container start`. The -trade-off: - -- **On** (recommended for x86_64 hosts that care about first-spawn - latency): the first `nixos-container start` for any new agent - completes in seconds because nothing remains to fetch. Cost: - `preBuildAgentTemplates` adds the full nixpkgs runtime closure + claude-code + the harness - binary to the host system closure (low single-digit GB - additional). -- **Off** (default): the host closure stays lean; the first spawn - does all the eval + fetch work at runtime (can take a few - minutes on a fresh store). - -**Note**: the meta flake pins the toplevel to `x86_64-linux`. Enabling on an -`aarch64` host forces a cross-compilation or remote-builder build, -which is almost never desired. Leave off on non-x86 hosts. - --- ## See also diff --git a/flake.nix b/flake.nix index b163d8cf..064d86df 100644 --- a/flake.nix +++ b/flake.nix @@ -133,14 +133,6 @@ assets = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.assets; xdgIcons = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.xdg-icons; hyperhiveRev = lib.mkDefault (self.rev or null); - # The agent-base toplevel every container builds from — wired into - # `system.extraDependencies` when - # `services.hyperhive.deploy.hive-controller.preBuildAgentTemplates` is on so - # the host system closure pre-fetches the heavy build - # inputs. x86_64-linux only (nixosConfigurations are - # hardcoded to that system); the gate keeps aarch64 hosts - # from pulling them in via cross-build. - agentBaseToplevel = lib.mkDefault self.packages.x86_64-linux.agent-base-toplevel; }; services.hyperhive.deploy.swarm-controller.package = lib.mkDefault diff --git a/nix/host-modules/deploy.nix b/nix/host-modules/deploy.nix index eabeaec3..250eb1e6 100644 --- a/nix/host-modules/deploy.nix +++ b/nix/host-modules/deploy.nix @@ -61,6 +61,13 @@ let certificate. Remove this definition; the leaf or directory it named is read by nothing now and can be deleted. ''; + + # Shared by the removed options that pre-fetched the agent-base closure. + agentPrebuildRemoved = '' + Hives pull agent closures from the swarm cache; nothing builds locally, so + there is no agent-base closure to pre-fetch into the host store. Remove + this definition. + ''; in { imports = [ @@ -223,14 +230,18 @@ in [ "services" "hyperhive" "c0re" "hyperhiveRev" ] [ "services" "hyperhive" "deploy" "hive-controller" "hyperhiveRev" ] ) - (lib.mkRenamedOptionModule - [ "services" "hyperhive" "c0re" "agentBaseToplevel" ] - [ "services" "hyperhive" "deploy" "hive-controller" "agentBaseToplevel" ] - ) - (lib.mkRenamedOptionModule - [ "services" "hyperhive" "c0re" "preBuildAgentTemplates" ] - [ "services" "hyperhive" "deploy" "hive-controller" "preBuildAgentTemplates" ] - ) + (lib.mkRemovedOptionModule [ + "services" + "hyperhive" + "c0re" + "agentBaseToplevel" + ] agentPrebuildRemoved) + (lib.mkRemovedOptionModule [ + "services" + "hyperhive" + "c0re" + "preBuildAgentTemplates" + ] agentPrebuildRemoved) (lib.mkRenamedOptionModule [ "services" "hyperhive" "c0re" "modelPrices" ] [ "services" "hyperhive" "deploy" "hive-controller" "modelPrices" ] diff --git a/nix/host-modules/hive-c0re/default.nix b/nix/host-modules/hive-c0re/default.nix index cd33fae9..822bd5d3 100644 --- a/nix/host-modules/hive-c0re/default.nix +++ b/nix/host-modules/hive-c0re/default.nix @@ -170,16 +170,6 @@ in # above for the rationale. environment.etc."hyperhive/serve.json".text = serveConfigJson; - # Pull the agent-base toplevel into the host system closure. - # `system.extraDependencies` adds paths to the system build - # without referencing them at runtime — nixos-rebuild fetches / - # builds them, they end up in /nix/store, and the first - # nixos-container update + start for an agent has nothing left to - # do. Gated because the closure is sizeable and pinned to x86_64. - system.extraDependencies = lib.optionals controllerCfg.preBuildAgentTemplates [ - controllerCfg.agentBaseToplevel - ]; - # Unprivileged coordinator user. hive-c0re runs as this user; # privileged operations are delegated to hive-priv which runs as # root, socket-activated at /run/hive/priv.sock (./hive-priv.nix). diff --git a/nix/host-modules/hive-c0re/options.nix b/nix/host-modules/hive-c0re/options.nix index 75fdfe0e..b382b85e 100644 --- a/nix/host-modules/hive-c0re/options.nix +++ b/nix/host-modules/hive-c0re/options.nix @@ -10,11 +10,32 @@ lib, ... }: +let + agentPrebuildRemoved = '' + Hives pull agent closures from the swarm cache; nothing builds locally, so + there is no agent-base closure to pre-fetch into the host store. Remove + this definition. + ''; +in { imports = [ (lib.mkRemovedOptionModule [ "services" "hyperhive" "c0re" "managerToplevel" ] '' - Every agent, ruth included, builds from `agentBaseToplevel`. Remove this definition. + Every agent, ruth included, builds from the `agent-base` configuration. Remove this definition. '') + (lib.mkRemovedOptionModule [ + "services" + "hyperhive" + "deploy" + "hive-controller" + "agentBaseToplevel" + ] agentPrebuildRemoved) + (lib.mkRemovedOptionModule [ + "services" + "hyperhive" + "deploy" + "hive-controller" + "preBuildAgentTemplates" + ] agentPrebuildRemoved) (lib.mkRemovedOptionModule [ "services" "hyperhive" "c0re" "hyperhiveDocs" ] '' Agents take their reference docs from the pinned `hyperhive` input, which carries `docs/`. Remove this definition. @@ -99,42 +120,6 @@ it is. ''; }; - agentBaseToplevel = lib.mkOption { - type = lib.types.package; - defaultText = lib.literalExpression "hyperhive.packages.x86_64-linux.agent-base-toplevel"; - description = '' - Pre-built agent-base container system closure, pulled into the - host system closure when `preBuildAgentTemplates` is on. Wired - by `nixosModules.default`; only evaluated when that option is - enabled. - ''; - }; - preBuildAgentTemplates = lib.mkOption { - type = lib.types.bool; - default = false; - example = true; - description = '' - Pre-fetch the agent-base container system closure, which every - agent builds from, into the host's /nix/store as part of this - host's NixOS build, instead of letting the first agent spawn - do all the work. - - Enabling this adds roughly the full nixpkgs runtime closure + - claude-code + the harness binary to your system closure size - (low single-digit GB), but the first `nixos-container start` - for any agent then completes in seconds instead of minutes - because nothing's left to fetch. - - Off by default because the toplevel is pinned to - `x86_64-linux` (nixos-containers run native arch). Enabling - on an aarch64 host would force nix to build the x86 closure - via cross or a remote builder, which is rarely what you want. - Flip to `true` on an x86_64 host when you care more about - first-spawn latency than host store size — or just - `nix build .#agent-base-toplevel` once manually to warm the - store. - ''; - }; modelPrices = lib.mkOption { type = lib.types.attrsOf ( diff --git a/nix/module-eval/core-toggle.nix b/nix/module-eval/core-toggle.nix index 1928e570..39a9fa60 100644 --- a/nix/module-eval/core-toggle.nix +++ b/nix/module-eval/core-toggle.nix @@ -1469,9 +1469,7 @@ let c0re.frontend = pkgs.coreutils; c0re.assets = pkgs.gnused; c0re.xdgIcons = pkgs.gnugrep; - c0re.agentBaseToplevel = pkgs.findutils; c0re.hyperhiveRev = "abc123"; - c0re.preBuildAgentTemplates = true; c0re.modelPrices.sonnet = { input = 1.0; output = 2.0; @@ -1501,10 +1499,8 @@ let && path c.frontend == path pkgs.coreutils && path c.assets == path pkgs.gnused && path c.xdgIcons == path pkgs.gnugrep - && path c.agentBaseToplevel == path pkgs.findutils && path c.servedFrontend == path pkgs.coreutils && c.hyperhiveRev == "abc123" - && c.preBuildAgentTemplates && c.modelPrices.sonnet.cache_write == 4.0 && c.agentCpuQuota == "300%" && c.agentMemoryMax == "8G" @@ -1519,9 +1515,7 @@ let "frontend" "assets" "xdgIcons" - "agentBaseToplevel" "hyperhiveRev" - "preBuildAgentTemplates" "modelPrices" "agentCpuQuota" "agentMemoryMax" @@ -1539,6 +1533,48 @@ let && serve.build_slots == 3 && old.users.groups.hive-admin.members == [ "alice" ]; } + { + # Under either namespace, each removed pre-fetch option fails evaluation naming + # itself and the swarm cache. The controls are a host that sets none, and + # a host that sets a moved sibling option (`buildSlots`), which warns + # but does not fail. + name = "a definition of a removed agent-base pre-fetch option fails evaluation, naming the option and the swarm cache"; + ok = + let + refused = + m: path: + lib.any ( + a: + !a.assertion + && lib.hasInfix "services.hyperhive.${path}" a.message + && lib.hasInfix "swarm cache" a.message + ) m.assertions; + setting = lib.listToAttrs ( + lib.concatMap + ( + ns: + lib.mapAttrsToList + (name: value: { + name = "${ns}.${name}"; + value = hiveWithController (lib.setAttrByPath (lib.splitString "." "${ns}.${name}") value); + }) + { + preBuildAgentTemplates = true; + agentBaseToplevel = pkgs.findutils; + } + ) + [ + "c0re" + "deploy.hive-controller" + ] + ); + sibling = hiveWithController { c0re.buildSlots = 3; }; + in + lib.length (lib.attrNames setting) == 4 + && lib.all (path: refused setting.${path} path) (lib.attrNames setting) + && !(lib.any (path: refused bare path) (lib.attrNames setting)) + && !(lib.any (path: refused sibling path) (lib.attrNames setting)); + } { # What the moved options render with their defaults: the flake source, the agent limits # and build slots in serve.json, the sudoless-hivectl group's members, diff --git a/nix/packages/default.nix b/nix/packages/default.nix index 55947c0e..266f5dc3 100644 --- a/nix/packages/default.nix +++ b/nix/packages/default.nix @@ -285,13 +285,7 @@ in ghidra-12-1 = pkgs.callPackage ./ghidra-12-1.nix { }; # Pre-built system closure every agent container builds from. Exposed as a package - # so operators can `nix build .#agent-base-toplevel` (or wire - # them into their host system closure via the - # `preBuildAgentTemplates` option on the hive-c0re module — - # see nix/host-modules/hive-c0re/options.nix). Speeds up the first agent - # spawn dramatically because the heavy lifting (nixpkgs + - # claude-code + hive-agent binary) is already in the store - # when the meta evaluator goes to build the container. + # so operators can `nix build .#agent-base-toplevel`. # # nixosConfigurations are pinned to x86_64-linux (nixos- # containers only run native arch), so this toplevel is