docs/gateway.md: section on the #784 unix-socket upstream chain (mara on #832)

This commit is contained in:
damocles 2026-05-31 16:17:36 +02:00 committed by mara
commit 90c72d9131

View file

@ -67,6 +67,43 @@ Per-vhost timeouts + body-size limits live in the location blocks:
SSH for forge stays direct on `cfg.sshPort` — separate listener protocol, not HTTP-over-nginx.
## Per-agent unix-socket upstream (#784)
Sub-agent `/agent/<name>/` upstreams flip from TCP loopback to a
unix-domain socket as each agent opts in. The mechanism:
1. **Agent side** (`hyperhive.web.useUnixSocket = true` in
`agent.nix`, #815). Sets `HIVE_WEB_SOCKET=/run/hive-agent/<name>/web.sock`
on the harness service env; `web_ui::serve` binds a `UnixListener`
at that path instead of TCP.
2. **Host side**. `hive-c0re` bind-mounts the per-agent subdir
(`/run/hive-agent/<name>/`) into the agent's container (#813). Dir
bind, not file bind — file bind-mounts don't survive the
harness's `unlink + bind(2)` cycle on socket replace. Per-agent
subdir keeps each agent's container blind to siblings'
sockets (mara on #800).
3. **Marker gate**. After successful `bind_unix`, the harness drops
`<dir>/.bound` next to the socket. c0re's `agent_sockets::write`
filters its JSON map by marker presence — only agents whose
harness has actually bound the socket appear there (#784 atlas
gate). Without this filter, the gateway would `proxy_pass` to a
non-existent socket for every sub-agent that hasn't opted in yet.
4. **Gateway side** (#829). Reads `agent-sockets.json` at
request-handling time and routes `/agent/<name>/` to
`http://unix:/run/hive-agent/<name>/web.sock:/`. Whole
`/run/hive-agent/` is bind-mounted read-only into the gateway
container so it can reach every published socket.
c0re re-fires `agent_sockets::write` every 10s so newly-bound
markers get picked up without needing a container-start hook in
every lifecycle path. `write()` is idempotent: steady-state cost is
one stat per agent per tick.
Transition: agents that haven't flipped `useUnixSocket = true` still
appear in `agent-ports.json` (the legacy TCP map) and the gateway
falls back to TCP for them. Step 4 of #784 will drop the TCP map +
the harness's TCP bind once every agent's flipped.
## Sequencing history
- #15 v0 (per-agent routing, #740) — first sub-app behind the gateway, JSON port table from c0re.
@ -74,6 +111,7 @@ SSH for forge stays direct on `cfg.sshPort` — separate listener protocol, not
- #749 / #754 — forge to sub-domain (mara: sub-domain over sub-path).
- #747 / #764 — matrix sub-domain vhost + `.well-known` delegation.
- #772 / #775 — fluffychat hops from `<hive>/matrix/` to `matrix.<hive>/`.
- #784 / #800 / #813 / #815 / #822 / #829 — sub-agent UI flips to unix-domain socket upstream, opt-in per agent.
Next-up tracked separately: #14 (container netns isolation), TLS (#594).