docs: put swarm-controller in the repo map and the swarm doc
The crate was a workspace member with no entry in CLAUDE.md, which is the index that auto-loads into every turn -- a member missing from it is invisible to everyone who comes after. Both entries carry the socket-directory constraint rather than just naming the daemon, because that is the one thing about this service a reader can get wrong from a position that looks correct.
This commit is contained in:
parent
435dfbfb33
commit
0fe2babbee
2 changed files with 41 additions and 0 deletions
11
CLAUDE.md
11
CLAUDE.md
|
|
@ -141,6 +141,17 @@ hand-maintained per-file tree drifts out of sync with the code.
|
|||
dependency-free wire types.
|
||||
- **`hive-metric/`** — small CLI to push a single labeled metric to the
|
||||
OTEL collector via the OpenTelemetry Rust SDK / OTLP HTTP exporter.
|
||||
- **`swarm-controller/`** — swarm-level daemon, opt-in per host
|
||||
(`services.hyperhive.swarm.controller.enable`). Where `hive-c0re` owns
|
||||
the agents on **one** host, this owns what is true **across** hives; a
|
||||
swarm runs one of them, so most hives leave it off. Serves HTTP over a
|
||||
unix socket (never a TCP port) that the gateway's nginx proxies to.
|
||||
⚠️ The socket lives in its **own** `RuntimeDirectory`: it is `0666`
|
||||
(nginx is a different user and `connect(2)` needs write), so the
|
||||
containing directory — bind-mounted wholesale into the gateway
|
||||
container — is the only access control there is. Never move it under a
|
||||
directory shared with anything else, `/run/hyperhive` (host admin
|
||||
socket) above all. A unit test pins the path.
|
||||
|
||||
### External dependencies with no directory here
|
||||
|
||||
|
|
|
|||
|
|
@ -235,6 +235,36 @@ one store, because the receiver keys destinations by *agent* so a
|
|||
migrating agent keeps one unbroken incremental chain. See
|
||||
[snapshot-store.md](snapshot-store.md).
|
||||
|
||||
## Swarm controller
|
||||
|
||||
`services.hyperhive.swarm.controller.enable` runs the `swarm-controller`
|
||||
daemon on this host. It is **off by default and deliberately not derived
|
||||
from `services.hyperhive.enable`**: a swarm has one controller, so
|
||||
enabling it is a statement about swarm topology, not about whether
|
||||
hyperhive is installed. Every hive runs `hive-c0re` (which owns the
|
||||
agents on that host); one hive additionally runs this (which owns what is
|
||||
true across hives).
|
||||
|
||||
It serves HTTP over a unix socket — `socketPath`, default
|
||||
`/run/swarm-controller/controller.sock` — rather than a TCP port. The
|
||||
gateway's nginx is the only intended client and reaches the socket
|
||||
through a bind-mount, and a listener that is never bound to an address
|
||||
cannot be reached from off-host by mistake.
|
||||
|
||||
⚠️ **The socket's directory is its access control.** The socket itself is
|
||||
`0666`, because nginx runs as a different user and `connect(2)` needs
|
||||
write — the same arrangement hive-c0re uses for the per-agent sockets.
|
||||
What keeps that safe is that the directory holds one socket and is
|
||||
bind-mounted into exactly one container. Pointing `socketPath` at a
|
||||
directory that carries anything else — `/run/hyperhive`, which holds the
|
||||
host **admin** socket, above all — exposes everything in it to every
|
||||
consumer that mounts it. Changing `socketPath` therefore means
|
||||
re-checking the gateway bind-mount, not just the daemon.
|
||||
|
||||
Today the daemon serves a single `/health` endpoint and holds no state:
|
||||
the unit exists so the swarm-level surfaces that follow have somewhere to
|
||||
land.
|
||||
|
||||
## Cross-references
|
||||
|
||||
- `docs/snapshot-store.md` — the swarm's `btrfs receive` endpoint, and
|
||||
|
|
|
|||
Loading…
Reference in a new issue