hive-c0re: extract agent-socket-plumbing prose (#715 batch 5)

This commit is contained in:
damocles 2026-05-31 17:29:38 +02:00 committed by mara
commit d2f1a9d291
3 changed files with 44 additions and 98 deletions

View file

@ -1,11 +1,9 @@
//! `/var/lib/hyperhive/agent-ports.json` writer (#15 / #740).
//!
//! The hive-gateway nginx container lives in the host's system config,
//! not in the meta flake — its build can't be triggered by a
//! meta-rebuild on every agent spawn / move / destroy. Instead it
//! reads this JSON file at request-handling time to look up per-agent
//! upstream ports, so the file IS the source of truth for "which
//! agents exist and what's their web port" from the gateway's POV.
//! `/var/lib/hyperhive/agent-ports.json` writer. Legacy TCP map for
//! per-agent `/agent/<name>/` routing — the unix-socket replacement
//! lives in `agent_sockets.rs`. The gateway reads this JSON at
//! request-handling time rather than at gateway build time, so a
//! `nixos-container update` of the gateway isn't needed every time
//! an agent spawns / moves / destroys.
//!
//! Shape (flat object keyed by logical agent name → web port):
//!
@ -20,13 +18,9 @@
//!
//! Ports come from [`crate::lifecycle::agent_web_port`] — pure
//! FNV-1a(name) hash so the value is reproducible from the name
//! alone. The manager is intentionally excluded from the map: the
//! gateway routes `/` straight to it via the c0re dashboard upstream
//! (see `nix/modules/hive-gateway.nix`, atlas's #740) rather than a
//! per-agent `/agent/<name>/` prefix. Post-#753 the manager's port
//! is computed by the same hash as every other agent, but it still
//! doesn't appear here — keeping the routing surface "sub-agents
//! only" matches the gateway's current shape.
//! alone. Manager is excluded from the map: the gateway routes `/`
//! straight to it via the c0re dashboard upstream rather than a
//! per-agent `/agent/<name>/` prefix.
//!
//! Atomicity: write to a sibling `.tmp` file + rename so a partial
//! write never leaves an unparseable file in place. The gateway's
@ -116,7 +110,7 @@ mod tests {
// Use MANAGER_NAME in the input so the assert below actually
// exercises the filter path — a literal `"hm1nd"` would pass
// trivially if the constant ever changed and the filter
// silently became a no-op (argus on PR #748).
// silently became a no-op.
let names: Vec<String> = ["iris", MANAGER_NAME, "argus"]
.iter()
.map(|s| (*s).to_owned())