docs: name options by the path an operator can set, not by cfg.*

`cfg` is whatever the reading module bound it to. It does not exist in a
NixOS configuration, so a sentence naming an option as `cfg.<name>` is
correct about behaviour and unusable as an instruction — the reader has
to go find the real path.

The four sites in docs/networking/gateway.md this was filed for:

  cfg.sshPort       -> services.hyperhive.swarm.forge.sshPort
  cfg.dashboardPort -> services.hyperhive.c0re.dashboardPort
  cfg.frontend (x2) -> services.hyperhive.c0re.frontend

Sweeping docs/ for the pattern rather than the ticket's line numbers
found five more, in four other files:

  approvals.md    cfg.hyperhiveFlake        -> services.hyperhive.c0re.hyperhiveFlake
  matrix.md       cfg.registrationTokenFile -> services.hyperhive.deploy.matrix.registrationTokenFile
  matrix.md       cfg.gatewayHost           -> services.hyperhive.swarm.matrix.gatewayHost
  conventions.md  cfg.dashboardPort         -> services.hyperhive.c0re.dashboardPort
  gotchas.md      cfg.dashboardPort         -> services.hyperhive.c0re.dashboardPort

matrix.md is the clearest case for doing this at all: its two `cfg.`
references resolve to *different* option trees — `deploy.matrix` and
`swarm.matrix` — so the shorthand is ambiguous even within one file.

Each path is read off the `mkOption` that declares it plus the
`options.services.hyperhive.*` root it sits under, with the indentation
checked so a nested block cannot have been missed. `cfg.frontend` is
declared in hive-c0re, not the gateway: the gateway module binds
`cfg = config.services.hyperhive.gateway`, which has no `frontend`.

Deliberately unchanged: docs/networking/snapshot-store.md:136, where
`cfg.port` sits inside a ```nix block quoting module source. `cfg` is
correct there, and rewriting it would make the snippet wrong.

Closes #4193.
This commit is contained in:
atlas 2026-09-11 12:20:33 +02:00 committed by mara
commit 3f878408f0
5 changed files with 10 additions and 9 deletions

View file

@ -664,7 +664,8 @@ rebuilds any whose recorded hyperhive rev differs from the current
one — sub-agents and the root agent go through the same one — sub-agents and the root agent go through the same
`job_queue::templates::rebuild` DAG. `job_queue::templates::rebuild` DAG.
"Rev" = canonical filesystem path of `cfg.hyperhiveFlake`. Marker "Rev" = canonical filesystem path of
`services.hyperhive.c0re.hyperhiveFlake`. Marker
file: `/var/lib/hyperhive/applied/.<name>.hyperhive-rev`. If the file: `/var/lib/hyperhive/applied/.<name>.hyperhive-rev`. If the
flake input has no canonical path (for example a `github:` URL), flake input has no canonical path (for example a `github:` URL),
autoupdate is a no-op — rebuild manually. autoupdate is a no-op — rebuild manually.

View file

@ -96,7 +96,7 @@ Token-gated registration: hive-c0re holds the token, agents never
see it. The agent only receives the resulting `access_token`. see it. The agent only receives the resulting `access_token`.
1. **System activation** writes a 32-byte random hex token (64 1. **System activation** writes a 32-byte random hex token (64
chars) to `cfg.registrationTokenFile` chars) to `services.hyperhive.deploy.matrix.registrationTokenFile`
(`/var/lib/hyperhive/matrix-register-token` by default), mode (`/var/lib/hyperhive/matrix-register-token` by default), mode
`0600 root:root`, before any container start. Idempotent — only `0600 root:root`, before any container start. Idempotent — only
writes when the file is missing or empty; always re-applies 0600 writes when the file is missing or empty; always re-applies 0600
@ -215,7 +215,7 @@ resource-constrained hosts where a 20 MB request is unexpectedly large.
`config.assertions` in this module fail eval early rather than ship `config.assertions` in this module fail eval early rather than ship
surprising behaviour: surprising behaviour:
- **`cfg.gatewayHost != ""`** — same footgun as `forge.domain`: - **`services.hyperhive.swarm.matrix.gatewayHost != ""`** — same footgun as `forge.domain`:
empty string renders `.<hive>`-shaped garbage in both nginx empty string renders `.<hive>`-shaped garbage in both nginx
`server_name` (treated as wildcard catch-all, surprising) and `server_name` (treated as wildcard catch-all, surprising) and
`/etc/hosts` (invalid entry). `null` is the right opt-out shape; `/etc/hosts` (invalid entry). `null` is the right opt-out shape;

View file

@ -87,7 +87,7 @@ Per-vhost timeouts + body-size limits live in the location blocks:
- matrix `/_matrix/` (tuwunel): `client_max_body_size 50M` (media uploads), `proxy_read_timeout 1h` (long-poll `/sync`), CORS `*` (federation + cross-origin clients), `proxyWebsockets = true`. - matrix `/_matrix/` (tuwunel): `client_max_body_size 50M` (media uploads), `proxy_read_timeout 1h` (long-poll `/sync`), CORS `*` (federation + cross-origin clients), `proxyWebsockets = true`.
- per-agent `/agent/<name>/`: `proxy_read_timeout 1d` (long-lived SSE / WebSocket dashboards), `proxyWebsockets = true`, `X-Forwarded-Prefix` set so the harness can build absolute URLs when relative isn't enough. - per-agent `/agent/<name>/`: `proxy_read_timeout 1d` (long-lived SSE / WebSocket dashboards), `proxyWebsockets = true`, `X-Forwarded-Prefix` set so the harness can build absolute URLs when relative isn't enough.
SSH for forge stays direct on `cfg.sshPort` — separate listener protocol, not HTTP-over-nginx. SSH for forge stays direct on `services.hyperhive.swarm.forge.sshPort` — separate listener protocol, not HTTP-over-nginx.
## Per-agent unix-socket upstream ## Per-agent unix-socket upstream
@ -292,7 +292,7 @@ TLS (see [TLS modes](#tls-modes) above).
Every agent hashes into the same port range (no special case), so Every agent hashes into the same port range (no special case), so
one range opening covers every container. one range opening covers every container.
The dashboard port (`cfg.dashboardPort`, default 7000) is *not* The dashboard port (`services.hyperhive.c0re.dashboardPort`, default 7000) is *not*
listed in either case — it binds `127.0.0.1` only, so a firewall listed in either case — it binds `127.0.0.1` only, so a firewall
hole would be a no-op. Remote dashboard access flows through the hole would be a no-op. Remote dashboard access flows through the
gateway. Operators who opt out of the gateway lose external gateway. Operators who opt out of the gateway lose external
@ -457,12 +457,12 @@ store path baked in at hive-c0re build time, and c0re (writing
so they see the same store. so they see the same store.
**Graceful degradation**: if `HIVE_AGENT_FRONTEND_DIR` is empty or **Graceful degradation**: if `HIVE_AGENT_FRONTEND_DIR` is empty or
unset (for example a build that predates `cfg.frontend`), each agent gets the unset (for example a build that predates `services.hyperhive.c0re.frontend`), each agent gets the
legacy single-proxy block and nginx forwards all traffic to the agent legacy single-proxy block and nginx forwards all traffic to the agent
daemon as before. daemon as before.
**`extraFiles`**: per-agent `hyperhive.frontend.extraFiles` are in **`extraFiles`**: per-agent `hyperhive.frontend.extraFiles` are in
`mergedDist`, not in the base `cfg.frontend` dist. They're not under `mergedDist`, not in the base `services.hyperhive.c0re.frontend` dist. They're not under
the nix-store `alias` path, so requests for them fall through the nix-store `alias` path, so requests for them fall through
`try_files` to `@<name>_dynamic`, and the agent daemon serves them `try_files` to `@<name>_dynamic`, and the agent daemon serves them
as before. as before.

View file

@ -11,7 +11,7 @@ exist because something already went wrong without them.
- `MAX_AGENT_NAME` in `hive-c0re/src/lifecycle/mod.rs` enforces the cap. - `MAX_AGENT_NAME` in `hive-c0re/src/lifecycle/mod.rs` enforces the cap.
- Per-agent web UI port = `WEB_PORT_BASE + FNV1a(name) % WEB_PORT_RANGE` - Per-agent web UI port = `WEB_PORT_BASE + FNV1a(name) % WEB_PORT_RANGE`
(8100..8999) for every agent; dashboard (8100..8999) for every agent; dashboard
`cfg.dashboardPort` (default 7000). `services.hyperhive.c0re.dashboardPort` (default 7000).
## Hive identity (label + domain + display names) ## Hive identity (label + domain + display names)

View file

@ -193,7 +193,7 @@ agent (different hash → different port) and rebuilding. No state
file, no probing, no port-allocation drift — the value is file, no probing, no port-allocation drift — the value is
reproducible from just the name. Every agent hashes into reproducible from just the name. Every agent hashes into
8100..8999 via the same FNV-1a; dashboard 8100..8999 via the same FNV-1a; dashboard
at `cfg.dashboardPort` (default 7000). at `services.hyperhive.c0re.dashboardPort` (default 7000).
### Restart races on TCP bind ### Restart races on TCP bind