fix(#2399): split daemon/harness/MCP bins into per-binary packages

mara: "no, do split packages for the separate daemons" — instead of
grouping all daemon/harness/MCP bins into one hyperhive-daemon
derivation, each bin (hive-c0re, hive-priv, hive-agent,
hive-agent-mcp, hive-agent-wake, hive-bash-daemon, hive-bash-mcp,
hive-matrix-daemon, hive-matrix-mcp, hive-metric) is now its own
named package + overlay output, matching the existing hivectl /
hive-forge split. harness-base.nix's ExecStart/command lines now
point at the specific pkgs.hive-* each ExecStart needs, and
environment.systemPackages only carries the two bins actually
PATH-looked-up in-container (hive-agent-wake, hive-metric) instead
of the whole bundle.
This commit is contained in:
atlas 2026-07-13 17:42:37 +02:00 committed by mara
commit 650224c9c6
2 changed files with 94 additions and 48 deletions

103
flake.nix
View file

@ -171,25 +171,40 @@
inherit (nixpkgs) lib;
inherit (nixpkgs.lib) nixosSystem;
};
# Daemon + harness + MCP server binaries. Excludes hivectl and
# hive-forge which are their own derivations below — so each bin
# is compiled exactly once. `packages.default` joins all three
# via symlinkJoin; no binary is compiled more than once regardless
# of which packages the operator builds together.
# One package per daemon/harness/MCP-server binary — matches the
# `hivectl` / `hive-forge` split below rather than grouping them
# into a single derivation. Consumers (agent containers, host
# module, `nix profile install`) depend on exactly the binaries
# they need instead of an all-or-nothing bundle. All share
# `cargoArtifacts` (built once via `buildDepsOnly` above), so
# splitting doesn't cost extra rustc invocations — each call
# below just asks crane to build+link its one requested `--bin`.
#
# Tests are kept in the separate `checks.cargo-test` derivation
# (carries the hyperhive-assets build input for the prompt-template
# assertions in hive-ag3nt::prompt::tests). Keeping them out of the
# binary derivations means a prompt edit doesn't bust the cargo cache.
daemonBins = craneLib.buildPackage {
src = cleanSrc;
inherit cargoArtifacts nativeBuildInputs;
cargoExtraArgs = "--bin hive-c0re --bin hive-priv --bin hive-agent --bin hive-agent-mcp --bin hive-agent-wake --bin hive-bash-daemon --bin hive-bash-mcp --bin hive-matrix-daemon --bin hive-matrix-mcp --bin hive-metric";
pname = "hyperhive-daemon";
version = "0.1.0";
meta.description = "hyperhive daemon + privileged helper + agent harness + bash/matrix MCP servers";
doCheck = false;
};
mkDaemonBin =
bin: description:
craneLib.buildPackage {
src = cleanSrc;
inherit cargoArtifacts nativeBuildInputs;
cargoExtraArgs = "--bin ${bin}";
pname = bin;
version = "0.1.0";
meta.description = description;
doCheck = false;
};
hiveC0rePkg = mkDaemonBin "hive-c0re" "hyperhive host coordinator daemon";
hivePrivPkg = mkDaemonBin "hive-priv" "hyperhive privileged root helper";
hiveAgentPkg = mkDaemonBin "hive-agent" "hyperhive in-container agent harness serve loop";
hiveAgentMcpPkg = mkDaemonBin "hive-agent-mcp" "hyperhive agent-surface MCP server";
hiveAgentWakePkg = mkDaemonBin "hive-agent-wake" "hyperhive external wake CLI push a message into an agent's own inbox";
hiveBashDaemonPkg = mkDaemonBin "hive-bash-daemon" "hyperhive per-agent bash-task runner daemon";
hiveBashMcpPkg = mkDaemonBin "hive-bash-mcp" "hyperhive bash-task MCP bridge";
hiveMatrixDaemonPkg = mkDaemonBin "hive-matrix-daemon" "hyperhive per-agent matrix-sdk daemon";
hiveMatrixMcpPkg = mkDaemonBin "hive-matrix-mcp" "hyperhive matrix MCP bridge";
hiveMetricPkg = mkDaemonBin "hive-metric" "hyperhive agent-emitted custom metrics CLI";
# Operator CLI — ships `hivectl` (with shell completions and the
# `wg` wrapper) without the daemon binaries. Suitable for
# `nix profile install .#hivectl` / `environment.systemPackages
@ -248,26 +263,39 @@
default = pkgs.symlinkJoin {
name = "hyperhive";
paths = [
daemonBins
hiveC0rePkg
hivePrivPkg
hiveAgentPkg
hiveAgentMcpPkg
hiveAgentWakePkg
hiveBashDaemonPkg
hiveBashMcpPkg
hiveMatrixDaemonPkg
hiveMatrixMcpPkg
hiveMetricPkg
hivectlPkg
hiveForgePkg
];
};
# Per-bin split packages — useful for operator workstations that
# only want the CLI(s) without the daemon binaries.
# Per-bin split packages. Agent containers depend on the
# individual bins they actually exec/PATH-need (see
# `harness-base.nix`) instead of the `default` bundle — that
# keeps `hivectl` (dials the *host* admin socket, unreachable
# from inside a container, drags in `wireguard-tools`) and a
# redundant `hive-forge` copy (already on agent PATH via
# `hive-forge-tools.nix`) out of every agent's closure.
hivectl = hivectlPkg;
hive-forge = hiveForgePkg;
# The daemon/harness/MCP bins alone, no `hivectl` and no second
# `hive-forge` copy. Agent containers use this (via the
# `hyperhive-daemon` overlay output below) instead of `default` —
# they need `hive-agent{,-mcp,-wake}` /
# `hive-bash-{daemon,mcp}` / `hive-matrix-{daemon,mcp}`, never
# the operator-only `hivectl` (dials the *host* admin socket,
# unreachable from inside a container, and drags in
# `wireguard-tools` as a wrapper dep) or a redundant `hive-forge`
# (already on agent PATH via `hive-forge-tools.nix`) — this is
# the fix for the agent-derivation-bloat report.
daemonBins = daemonBins;
hive-c0re = hiveC0rePkg;
hive-priv = hivePrivPkg;
hive-agent = hiveAgentPkg;
hive-agent-mcp = hiveAgentMcpPkg;
hive-agent-wake = hiveAgentWakePkg;
hive-bash-daemon = hiveBashDaemonPkg;
hive-bash-mcp = hiveBashMcpPkg;
hive-matrix-daemon = hiveMatrixDaemonPkg;
hive-matrix-mcp = hiveMatrixMcpPkg;
hive-metric = hiveMetricPkg;
# Bundled browser assets — see ./nix/frontend.nix. Output is
# $out/{dashboard,agent}/ which the Rust binaries serve via
# tower_http::ServeDir.
@ -327,10 +355,21 @@
overlays = {
default = final: prev: {
hyperhive = self.packages.${prev.stdenv.hostPlatform.system}.default;
# Agent-scoped subset of `hyperhive` — daemon/harness/MCP bins
# only, no `hivectl` / no redundant `hive-forge` copy. See
# `packages.<system>.daemonBins` above.
hyperhive-daemon = self.packages.${prev.stdenv.hostPlatform.system}.daemonBins;
# Per-binary daemon/harness/MCP-server packages, exposed via the
# overlay so container nix evaluations can depend on exactly the
# bin(s) they need instead of the full `hyperhive` bundle — see
# `packages.<system>.hive-*` above and their use in
# `harness-base.nix`.
hive-c0re = self.packages.${prev.stdenv.hostPlatform.system}.hive-c0re;
hive-priv = self.packages.${prev.stdenv.hostPlatform.system}.hive-priv;
hive-agent = self.packages.${prev.stdenv.hostPlatform.system}.hive-agent;
hive-agent-mcp = self.packages.${prev.stdenv.hostPlatform.system}.hive-agent-mcp;
hive-agent-wake = self.packages.${prev.stdenv.hostPlatform.system}.hive-agent-wake;
hive-bash-daemon = self.packages.${prev.stdenv.hostPlatform.system}.hive-bash-daemon;
hive-bash-mcp = self.packages.${prev.stdenv.hostPlatform.system}.hive-bash-mcp;
hive-matrix-daemon = self.packages.${prev.stdenv.hostPlatform.system}.hive-matrix-daemon;
hive-matrix-mcp = self.packages.${prev.stdenv.hostPlatform.system}.hive-matrix-mcp;
hive-metric = self.packages.${prev.stdenv.hostPlatform.system}.hive-metric;
# Bundled frontend dist (see ./nix/frontend.nix). Output is
# $out/{dashboard,agent}/; consumers pick the surface they
# need. Exposed via the overlay so containers' nix evaluations