Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbf3757551 | ||
|
|
747f405c6f | ||
|
|
ec565120af |
5 changed files with 124 additions and 22 deletions
|
|
@ -19,20 +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)
|
||||
};
|
||||
```
|
||||
|
||||
`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.
|
||||
`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 `<hiveName>.<swarm.domain>`, 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.
|
||||
|
||||
See `docs/conventions.md` § Hive identity for the env-var chain
|
||||
and `qualify()` / `qualified_label()` semantics.
|
||||
|
|
|
|||
|
|
@ -120,7 +120,9 @@ in
|
|||
|
||||
domain = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "forge.${hyperhiveDomain}";
|
||||
# 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}";
|
||||
defaultText = lib.literalExpression ''"forge.''${services.hyperhive.domain}"'';
|
||||
example = "git.example.com";
|
||||
description = ''
|
||||
|
|
|
|||
|
|
@ -190,7 +190,9 @@ in
|
|||
|
||||
gatewayHost = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = "matrix.${hyperhiveDomain}";
|
||||
# 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}";
|
||||
defaultText = lib.literalExpression ''"matrix.''${services.hyperhive.domain}"'';
|
||||
example = "matrix.example.com";
|
||||
description = ''
|
||||
|
|
|
|||
|
|
@ -153,6 +153,17 @@ 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.<domain>`, `matrix.<domain>`) 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;
|
||||
|
|
@ -161,7 +172,33 @@ in
|
|||
hive resolver is authoritative for `<hive-domain>` 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
|
||||
`<hiveName>.<swarm.domain>`.
|
||||
'';
|
||||
}
|
||||
{
|
||||
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
|
||||
(`<hiveName>.<swarm.domain>`), not only a display name.
|
||||
Set it (`services.hyperhive.hiveName = "pr1ma";`).
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -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,35 @@
|
|||
`HYPERHIVE_HIVE_DOMAIN`; consumed by
|
||||
`hive-agent::identity::hive_domain()` for `<name>@<domain>`
|
||||
qualified labels.
|
||||
|
||||
Defaults to `<hiveName>.<swarm.domain>` 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
|
||||
`<hiveName>.<swarm.domain>` — 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.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
@ -61,14 +106,13 @@
|
|||
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
|
||||
`<hiveName>.<swarm.domain>`, 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.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue