diff --git a/docs/swarm.md b/docs/swarm.md index b2f4c388..6138bd94 100644 --- a/docs/swarm.md +++ b/docs/swarm.md @@ -19,31 +19,37 @@ the additional config needed when the swarm spans multiple hosts. ```nix services.hyperhive = { - domain = "pr1ma.example.com"; # machine-addressable DNS domain - hiveName = "pr1ma"; # human display name (optional) + swarm.domain = "example.com"; # required — the swarm's DNS domain + hiveName = "pr1ma"; # required — this hive's label in it + # domain = "pr1ma.example.com"; # derived from the two above swarm.name = "constellat1on"; # shared swarm display name (optional) - swarm.domain = "example.com"; # the swarm's DNS domain }; ``` -`domain` is required whenever hyperhive is enabled — eval fails with a -hint if it is unset. It drives `HYPERHIVE_HIVE_DOMAIN` in every -container so agents can form qualified labels -(`iris@pr1ma.example.com`). +`swarm.domain` and `hiveName` are **required** whenever hyperhive is +enabled; eval fails with a hint naming each. Neither is defaulted, +because a guessed value here is a wrong hostname that evaluates cleanly +and deploys — an eval failure asking the operator to write the address +down is the cheaper outcome. **Upgrading past this release means setting +both once.** -You can also *not* write it: with `swarm.domain` and `hiveName` set, -`domain` defaults to `.`, since every hive in a -swarm occupies its own sub-domain of it. That is a default and not a -rename — a hive that pins `domain` explicitly keeps exactly the value it -has today, which is the point: re-rooting where a value *comes from* -must not reinterpret the values already deployed. +`domain` is required too, but you no longer have to *write* it: it +defaults to `.`, since every hive in a swarm +occupies its own sub-domain of it. A hive that pins `domain` explicitly +keeps exactly the value it has today — that's why this is a default and +not a rename: re-rooting where a value *comes from* must not reinterpret +the values already deployed. -`hiveName` and `swarm.name` are purely display — they surface in the -dashboard chrome header and per-agent system prompts. Federated hives -at different domains can share a `swarm.name`; that it sits under -`swarm` and -`hiveName` does not is the whole distinction — one names this hive, the -other names the group it belongs to. +`domain` drives `HYPERHIVE_HIVE_DOMAIN` in every container so agents can +form qualified labels (`iris@pr1ma.example.com`). + +`swarm.name` is purely display — it surfaces in the dashboard chrome +header and per-agent system prompts, and federated hives at different +domains can share one. `hiveName` surfaces in the same places but is +*not* only display: it is the leftmost label of the hive's domain. That +`swarm.name` sits under `swarm` and `hiveName` does not is the whole +distinction — one names this hive, the other names the group it belongs +to. See `docs/conventions.md` § Hive identity for the env-var chain and `qualify()` / `qualified_label()` semantics. diff --git a/nix/host-modules/hive-network.nix b/nix/host-modules/hive-network.nix index 4f460d01..fa836ad0 100644 --- a/nix/host-modules/hive-network.nix +++ b/nix/host-modules/hive-network.nix @@ -178,6 +178,29 @@ in `.`. ''; } + { + assertion = config.services.hyperhive.swarm.domain != null; + message = '' + hyperhive requires services.hyperhive.swarm.domain to be + set — the DNS domain of the swarm this hive belongs to, + of which this hive occupies one sub-domain. There is no + fallback: a guessed value would be a wrong hostname that + evaluates cleanly and deploys. Set it + (`services.hyperhive.swarm.domain = "example.com";`) — + with `hiveName` it also derives + `services.hyperhive.domain` for you. + ''; + } + { + assertion = config.services.hyperhive.hiveName != null; + message = '' + hyperhive requires services.hyperhive.hiveName to be set — + it is this hive's label within the swarm, and the leftmost + part of the domain it is addressed by + (`.`), not only a display name. + Set it (`services.hyperhive.hiveName = "pr1ma";`). + ''; + } ]; # Virtual bridge — each agent container attaches a veth pair (isolation diff --git a/nix/host-modules/hyperhive.nix b/nix/host-modules/hyperhive.nix index bb3f5b16..6de59aee 100644 --- a/nix/host-modules/hyperhive.nix +++ b/nix/host-modules/hyperhive.nix @@ -85,11 +85,12 @@ in `services.hyperhive.hiveName` and a hive needs no domain of its own. - A swarm needs this set somewhere to address its hives uniformly; - it is left nullable so an existing single-hive deployment that - pins `services.hyperhive.domain` directly keeps evaluating - untouched. The only thing eval insists on is that the hive ends - up with a domain, by either route. + **Required** when `services.hyperhive.enable`, and deliberately + not defaulted: there is no fallback worth having. A guessed + swarm domain is a wrong hostname that evaluates cleanly and + deploys, which is worse than an eval failure telling an + operator to write down the one address their swarm answers to. + Upgrading past this costs one line, once. ''; }; @@ -105,14 +106,13 @@ in example = "pr1ma"; description = '' Human-readable name of this single-host hive instance. - Distinct from `services.hyperhive.domain` (the machine- - addressable DNS name): the domain may carry the hive name as - its leftmost label by convention, but this option is the - canonical readable identity. Exposed to agents as - `HYPERHIVE_HIVE_NAME`; surfaced in the dashboard chrome and - per-agent system prompt when set. Null falls back to the - default behaviour (chrome shows the domain, prompt doesn't - mention a hive name). + **Required** when `services.hyperhive.enable`. Distinct from + `services.hyperhive.domain` (the machine-addressable DNS name) + but no longer merely cosmetic: a hive occupies + `.`, so this is the label the hive is + *addressed* by as well as the one it is called. Exposed to + agents as `HYPERHIVE_HIVE_NAME`; surfaced in the dashboard + chrome and per-agent system prompt. ''; };