Every hive in a swarm occupies its own sub-domain of the swarm's, so the hive domain is derivable rather than something each hive restates. `services.hyperhive.swarm.domain` is new and nullable; the hive's own `domain` keeps its existing required-ness and its existing assertion, and gains a default of `<hiveName>.<swarm.domain>`. Deliberately a default and not a rename: an alias would reinterpret the domains hives have already deployed, while a default only fills in the ones that never set one. Same reason there is no new assertion — the existing message just names the derivation, so this adds a way to stop failing rather than a way to fail.
167 lines
7.4 KiB
Nix
167 lines
7.4 KiB
Nix
# Top-level, cross-cutting hyperhive options: the master enable
|
|
# switch, the hive's identity (domain + display names), and hive-wide
|
|
# feature toggles read by several subsystem modules. Imported by the
|
|
# ./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,
|
|
# because they describe this hive rather than the swarm it joins.
|
|
imports = [
|
|
(lib.mkRenamedOptionModule
|
|
[ "services" "hyperhive" "swarmName" ]
|
|
[ "services" "hyperhive" "swarm" "name" ]
|
|
)
|
|
];
|
|
|
|
# Top-level hyperhive enable flag. When true, automatically enables
|
|
# hive-c0re and the on-by-default hyperhive subsystems.
|
|
options.services.hyperhive.enable = lib.mkEnableOption "hyperhive — the agent swarm coordinator";
|
|
|
|
# Canonical hive DNS domain shared by every subsystem that needs a
|
|
# stable hostname. Typed nullOr (default null) so the option always
|
|
# exists, but it's REQUIRED whenever hyperhive is enabled — an
|
|
# assertion in hive-network.nix fails eval when it's unset, since
|
|
# matrix bakes it in on first boot and the gateway/forge/agent URLs all
|
|
# derive from it (no safe default). Full identity-surface
|
|
# context (HYPERHIVE_HIVE_DOMAIN / HIVE_NAME / SWARM_NAME env-var
|
|
# chain → identity.rs → claude prompt): docs/conventions.md::
|
|
# 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'';
|
|
example = "darkest.space";
|
|
description = ''
|
|
Canonical host domain for hyperhive subsystems that need a
|
|
stable name (currently: `services.hyperhive.swarm.matrix.serverName`
|
|
derives from this, defaulting to
|
|
`matrix.''${services.hyperhive.domain}` when `serverName` is
|
|
null). **Required** when `services.hyperhive.enable` — eval fails
|
|
with a helpful message if it's unset (it's baked into matrix on
|
|
first boot and drives the gateway/forge/agent URLs, with no safe
|
|
default; changing it later is destructive). Exposed to agents as
|
|
`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.
|
|
|
|
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.
|
|
'';
|
|
};
|
|
|
|
# Human display name for this hive. Distinct from the DNS domain
|
|
# above (machine-readable) — see docs/conventions.md::Hive identity
|
|
# for the domain-vs-name-vs-swarm distinction + the env-var
|
|
# propagation chain. The swarm's display name is
|
|
# `services.hyperhive.swarm.name`, one level out: this hive is named
|
|
# here, the swarm it belongs to is named there.
|
|
options.services.hyperhive.hiveName = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.str;
|
|
default = null;
|
|
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).
|
|
'';
|
|
};
|
|
|
|
# The one hive-level option that describes something ABOVE the hive,
|
|
# which is why it sits under `swarm` with the swarm-global services
|
|
# rather than beside `hiveName`.
|
|
options.services.hyperhive.swarm.name = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.str;
|
|
default = null;
|
|
example = "constellat1on";
|
|
description = ''
|
|
Human-readable name of the wider swarm this hive belongs to.
|
|
Hives at different DNS domains can share a swarm name when
|
|
they federate together. Exposed to agents as
|
|
`HYPERHIVE_SWARM_NAME`; surfaced in the dashboard chrome and
|
|
per-agent system prompt when set.
|
|
'';
|
|
};
|
|
|
|
# Whether this hive runs "ruthless" — with no root/manager agent at
|
|
# all. Some hives don't want a root agent — see issue tracker
|
|
# "scope concept: special agents".
|
|
options.services.hyperhive.ruthless = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
example = true;
|
|
description = ''
|
|
Run this hive "ruthless" — with no root (manager) agent at all (no
|
|
ruth). When `true`, hive-c0re skips the root-agent auto-management
|
|
sweep entirely (it otherwise creates the root agent's container when
|
|
missing and restarts it when present but stopped). Defaults to
|
|
`false` (the root agent is auto-managed as required
|
|
infrastructure). Exposed to hive-c0re as `HYPERHIVE_RUTHLESS`.
|
|
'';
|
|
};
|
|
|
|
options.services.hyperhive.github.enable = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = true;
|
|
example = false;
|
|
description = ''
|
|
Hive-wide switch for the per-agent GitHub integration (the `gh` CLI
|
|
wrapper + git credential helper, per `hyperhive.github.enable`). On by
|
|
default: every agent gets the integration, inert until a PAT is
|
|
provisioned via the dashboard credentials tab or `hivectl github
|
|
set-token`. Set `false` to turn it off for the whole hive --- the
|
|
meta-flake renderer (`hive-c0re/src/meta.rs`) then injects
|
|
`hyperhive.github.enable = false` into every agent. Exposed to hive-c0re
|
|
as `HYPERHIVE_GITHUB_DISABLED` (set only when the integration is off).
|
|
'';
|
|
};
|
|
}
|