Watch
0
0
Fork
You've already forked hyperhive
0

remove c0re.preBuildAgentTemplates and agentBaseToplevel

This commit is contained in:
atlas 2026-11-01 22:20:15 +01:00
commit 8a7f254c74
7 changed files with 84 additions and 98 deletions

View file

@ -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

View file

@ -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

View file

@ -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" ]

View file

@ -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).

View file

@ -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 (

View file

@ -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,

View file

@ -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