diff --git a/docs/swarm.md b/docs/swarm.md index c255d44a..be4897ba 100644 --- a/docs/swarm.md +++ b/docs/swarm.md @@ -22,12 +22,23 @@ services.hyperhive = { domain = "pr1ma.example.com"; # machine-addressable DNS domain hiveName = "pr1ma"; # human display name (optional) swarm.name = "constellat1on"; # shared swarm display name (optional) + swarm.domain = "example.com"; # the swarm's DNS domain }; ``` -`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 +`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`). + +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. + +`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 diff --git a/nix/host-modules/hive-network.nix b/nix/host-modules/hive-network.nix index c7f6728e..218a88f8 100644 --- a/nix/host-modules/hive-network.nix +++ b/nix/host-modules/hive-network.nix @@ -161,7 +161,10 @@ 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";`). + (`services.hyperhive.domain = "example.com";`), or set + `services.hyperhive.swarm.domain` and + `services.hyperhive.hiveName` and it is derived for you as + `.`. ''; } ]; diff --git a/nix/host-modules/hyperhive.nix b/nix/host-modules/hyperhive.nix index 9ea5b35e..bb3f5b16 100644 --- a/nix/host-modules/hyperhive.nix +++ b/nix/host-modules/hyperhive.nix @@ -4,8 +4,12 @@ # ./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, @@ -32,7 +36,19 @@ # Hive identity (label + domain + display names). options.services.hyperhive.domain = lib.mkOption { type = lib.types.nullOr lib.types.str; - default = null; + # 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''; example = "darkest.space"; description = '' Canonical host domain for hyperhive subsystems that need a @@ -46,6 +62,34 @@ `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. + + 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. ''; };