diff --git a/docs/swarm.md b/docs/swarm.md index 6138bd94..c255d44a 100644 --- a/docs/swarm.md +++ b/docs/swarm.md @@ -19,37 +19,20 @@ the additional config needed when the swarm spans multiple hosts. ```nix services.hyperhive = { - 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 + domain = "pr1ma.example.com"; # machine-addressable DNS domain + hiveName = "pr1ma"; # human display name (optional) swarm.name = "constellat1on"; # shared swarm display name (optional) }; ``` -`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.** - -`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. - -`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. +`domain` is required when matrix federation is on (`matrix.enable`); +it drives `HYPERHIVE_HIVE_DOMAIN` in every container so agents can +form qualified labels (`iris@pr1ma.example.com`). `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. See `docs/conventions.md` § Hive identity for the env-var chain and `qualify()` / `qualified_label()` semantics. diff --git a/nix/host-modules/hive-forge/default.nix b/nix/host-modules/hive-forge/default.nix index c50532ef..518e22cf 100644 --- a/nix/host-modules/hive-forge/default.nix +++ b/nix/host-modules/hive-forge/default.nix @@ -120,9 +120,7 @@ in domain = lib.mkOption { type = lib.types.str; - # Total on a null hive domain so the required-domain assertion in - # hive-network.nix is the thing that fires; see the comment there. - default = if hyperhiveDomain == null then "forge.invalid" else "forge.${hyperhiveDomain}"; + default = "forge.${hyperhiveDomain}"; defaultText = lib.literalExpression ''"forge.''${services.hyperhive.domain}"''; example = "git.example.com"; description = '' diff --git a/nix/host-modules/hive-matrix.nix b/nix/host-modules/hive-matrix.nix index 35c2bbdb..419d5376 100644 --- a/nix/host-modules/hive-matrix.nix +++ b/nix/host-modules/hive-matrix.nix @@ -190,9 +190,7 @@ in gatewayHost = lib.mkOption { type = lib.types.nullOr lib.types.str; - # Total on a null hive domain so the required-domain assertion in - # hive-network.nix is the thing that fires; see the comment there. - default = if hyperhiveDomain == null then "matrix.invalid" else "matrix.${hyperhiveDomain}"; + default = "matrix.${hyperhiveDomain}"; defaultText = lib.literalExpression ''"matrix.''${services.hyperhive.domain}"''; example = "matrix.example.com"; description = '' diff --git a/nix/host-modules/hive-network.nix b/nix/host-modules/hive-network.nix index fa836ad0..c7f6728e 100644 --- a/nix/host-modules/hive-network.nix +++ b/nix/host-modules/hive-network.nix @@ -153,17 +153,6 @@ in # hyperhive is enabled: the shared-netns mode was removed, so there # is one mode (private netns behind the bridge). (lib.mkIf config.services.hyperhive.enable { - # This message is only useful if an operator can actually reach - # it, and an assertion competes with every eager default that - # reads the value it guards: option defaults that interpolate the - # domain (`forge.`, `matrix.`) throw while the - # assertion list is being evaluated, so the operator sees - # `cannot coerce null to a string` naming an unrelated option - # instead of the sentence below. Those defaults therefore stay - # total, falling back to a name under the reserved `.invalid` TLD - # (RFC 2606) — a value this assertion then refuses to let out the - # door, and one that fails loudly at resolution rather than - # quietly working if it somehow did. assertions = [ { assertion = config.services.hyperhive.domain != null; @@ -172,33 +161,7 @@ in hive resolver is authoritative for `` and its sub-domains, and agents reach the forge/matrix through the gateway by that domain. Pin a hostname - (`services.hyperhive.domain = "example.com";`), or set - `services.hyperhive.swarm.domain` and - `services.hyperhive.hiveName` and it is derived for you as - `.`. - ''; - } - { - 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";`). + (`services.hyperhive.domain = "example.com";`). ''; } ]; diff --git a/nix/host-modules/hyperhive.nix b/nix/host-modules/hyperhive.nix index 6de59aee..9ea5b35e 100644 --- a/nix/host-modules/hyperhive.nix +++ b/nix/host-modules/hyperhive.nix @@ -4,12 +4,8 @@ # ./default.nix aggregator. { lib, - config, ... }: -let - hiveCfg = config.services.hyperhive; -in { # The swarm's display name moved under `swarm` when the swarm-global # settings were consolidated; the hive's own name and domain stayed put, @@ -36,19 +32,7 @@ in # Hive identity (label + domain + display names). options.services.hyperhive.domain = lib.mkOption { type = lib.types.nullOr lib.types.str; - # Every hive in a swarm lives at its own sub-domain of the swarm's, - # so this is derivable rather than something each hive repeats. It - # stays a DEFAULT and not a rename: an alias would reinterpret the - # domains hives have already deployed, whereas a default only fills - # in the ones that never set it. Null (both parts unset) keeps the - # existing "required" assertion in hive-network.nix as the single - # place this can fail. - default = - if hiveCfg.swarm.domain != null && hiveCfg.hiveName != null then - "${hiveCfg.hiveName}.${hiveCfg.swarm.domain}" - else - null; - defaultText = lib.literalExpression ''"''${hiveName}.''${swarm.domain}", or null when either is unset''; + default = null; example = "darkest.space"; description = '' Canonical host domain for hyperhive subsystems that need a @@ -62,35 +46,6 @@ in `HYPERHIVE_HIVE_DOMAIN`; consumed by `hive-agent::identity::hive_domain()` for `@` qualified labels. - - Defaults to `.` when both of those are - set, so a hive in a swarm does not restate its own address. - Setting this explicitly always wins. - ''; - }; - - # Where the swarm lives. Declared beside the hive's own identity - # because it is what that identity is derived FROM — every hive in a - # swarm is a sub-domain of it. Unlike the renamed options nearby, this - # is genuinely new: nothing moved here, so there is no alias. - options.services.hyperhive.swarm.domain = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - example = "darkest.space"; - description = '' - DNS domain of the wider swarm this hive belongs to. Each hive - occupies its own sub-domain of it, which is why - `services.hyperhive.domain` defaults to - `.` — set this plus - `services.hyperhive.hiveName` and a hive needs no domain of its - own. - - **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. ''; }; @@ -106,13 +61,14 @@ in example = "pr1ma"; description = '' Human-readable name of this single-host hive instance. - **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. + 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). ''; };