harness-base: hyperhive.web.useUnixSocket option to flip HIVE_WEB_SOCKET (#815)

closes #815. last harness-side piece of the #784 phase 2 rollout.

new option `hyperhive.web.useUnixSocket` (default false). When true,
the harness service env gets HIVE_WEB_SOCKET set to the canonical
/run/hive-agent/${userName}/web.sock path — making web_ui::serve
bind a UnixListener (PR #800) instead of TCP. Path matches
hive_c0re::agent_sockets::socket_path_for(name) so the c0re
bind-mount (#813) and the gateway's eventual upstream config all
derive from the same canonical shape (no triangulation drift).

Default false so an agent's web UI keeps binding TCP until the
per-agent flip is explicit. Rollout shape:
1. flip one canary agent (atlas volunteered) to true via agent.nix
2. validate atlas's gateway-side step 3 against that canary
3. flip remaining agents per-agent as the gateway side soaks
4. eventually drop this option once everyone's on unix (step 4 of #784)

Sub-agent-only by design — manager UI serves at / via the c0re
dashboard upstream, never via /agent/<name>/, so the per-agent
unix path is irrelevant for it (the env var is set unconditionally
for code simplicity; the manager's bind socket would just sit
unused).
This commit is contained in:
damocles 2026-05-31 15:49:16 +02:00 committed by mara
commit e04b6075e5

View file

@ -75,6 +75,40 @@ in
'';
};
options.hyperhive.web.useUnixSocket = lib.mkOption {
type = lib.types.bool;
default = false;
example = true;
description = ''
When `true`, set `HIVE_WEB_SOCKET=/run/hive-agent/${userName}/web.sock`
on the harness service env, which makes `web_ui::serve` bind a
`UnixListener` at that path instead of the legacy TCP listener
on `HIVE_PORT`. Closes the third hop of the #784 rollout: PR
#800 added the harness-side opt-in, #809 / #813 added the c0re
bind-mount + JSON-map plumbing, this is the per-agent flip
that activates the unix-domain path.
Default `false` so an agent's web UI keeps binding TCP until
the per-agent flip is explicit. Rollout shape:
1. flip one canary agent (atlas volunteered) to `true` via its
`agent.nix` once #813 lands;
2. validate the gateway's `proxy_pass http://unix:.../web.sock`
end-to-end against that canary (atlas's step 3);
3. flip remaining agents per-agent as the gateway side soaks;
4. eventually drop this option once every agent's on unix +
atlas's gateway is the only path step 4 of #784 drops the
harness's TCP fallback at the same time.
Sub-agent-only by design: the manager's UI serves at `/` via
the c0re dashboard upstream, not via `/agent/<name>/`, so this
option has no effect when `hyperhive.role = "manager"` (the
env var is set unconditionally for clarity, but the manager's
web UI doesn't route through the gateway's per-agent unix
upstream its bind socket would just sit unused).
'';
};
options.hyperhive.role = lib.mkOption {
type = lib.types.enum [
"agent"
@ -1324,6 +1358,16 @@ in
HIVE_ASSETS_DIR = "${pkgs.hyperhive-assets}/share/hyperhive";
HIVE_ROLE = config.hyperhive.role;
}
// lib.optionalAttrs config.hyperhive.web.useUnixSocket {
# Per-agent unix-socket flip for the web UI (#784 phase 2
# step 2c). When set, the harness's `web_ui::serve` binds
# a `UnixListener` at this path instead of TCP. Path
# matches `hive_c0re::agent_sockets::socket_path_for(name)`
# so the lifecycle bind-mount (#813) and the gateway's
# upstream config all derive from the same canonical
# `/run/hive-agent/<name>/web.sock` shape — no triangulation.
HIVE_WEB_SOCKET = "/run/hive-agent/${userName}/web.sock";
}
// lib.optionalAttrs isManager {
# Standalone-eval fallbacks; meta.rs overrides at deploy time.
# HIVE_PORT = FNV-1a("hm1nd") % 900 + 8100.