Compare commits

...
Author SHA1 Message Date
atlas
1a0cb0fb44 docs: name the swarm display name by its new path
Two sites spelled it as a brace group, services.hyperhive.{hiveName,
swarmName}, which no anchored rewrite can handle correctly now that only
one of the two moves; both are written out separately. One of them is an
MCP tool description, so it is rendered into every agent's system prompt.
2026-08-05 11:15:41 +02:00
atlas
30a94d35e9 refactor(nix): move the swarm display name under services.hyperhive.swarm
services.hyperhive.swarmName becomes services.hyperhive.swarm.name, with
one mkRenamedOptionModule in hyperhive.nix -- the module that declares
it, same convention as the forge and matrix renames, so each migration
stays independent of its siblings.

hiveName deliberately stays where it is. It names this hive; swarm.name
names the group the hive belongs to, and that they now sit one level
apart is the distinction rather than an inconsistency.

The per-agent hyperhive.swarmName is an internal mirror rendered from
the host value and does not move, same split as forge and matrix.
2026-08-05 11:15:41 +02:00
10 changed files with 39 additions and 20 deletions

View file

@ -297,7 +297,7 @@ status_text, status_set_at, hive_name, swarm_name }`:
or when `running = false` (see above).
- `hive_name` / `swarm_name`: display names read from
`HYPERHIVE_HIVE_NAME` / `HYPERHIVE_SWARM_NAME` env (sourced from
`services.hyperhive.hiveName` / `services.hyperhive.swarmName`).
`services.hyperhive.hiveName` / `services.hyperhive.swarm.name`).
Both `None` when the options aren't configured.
### Timestamps on the wire

View file

@ -121,7 +121,7 @@ Every agent's export includes these resource attributes automatically:
| `service.name` | `hyperhive-agent` (constant) |
| `agent` | agent logical name (e.g. `iris`) |
| `hive` | hive display name (`services.hyperhive.hiveName`) |
| `swarm` | swarm display name (`services.hyperhive.swarmName`, if set) |
| `swarm` | swarm display name (`services.hyperhive.swarm.name`, if set) |
Additional labels can be appended via `extraResourceAttributes` (see option
reference above); custom per-data-point labels can be passed with

View file

@ -20,17 +20,19 @@ 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)
swarmName = "constellat1on"; # shared swarm display name (optional)
hiveName = "pr1ma"; # human display name (optional)
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
`swarmName` are purely display — they surface in the dashboard chrome
`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 `swarmName`.
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.

View file

@ -437,8 +437,9 @@ impl AgentServer {
`status_set_at` are stale pre-stop values and should not be treated as live), \
and the target's self-reported `status` text (set via `set_status`) plus how \
long ago it was set. Also returns the hive + swarm display names (`hive_name`, \
`swarm_name`) when the operator has configured `services.hyperhive.{hiveName, \
swarmName}`; both lines omitted when unset. Pass `name` to query a peer (e.g. \
`swarm_name`) when the operator has configured \
`services.hyperhive.hiveName` / `services.hyperhive.swarm.name`; both lines \
omitted when unset. Pass `name` to query a peer (e.g. \
check whether iris is idle before pinging them); omit `name` to get your own \
identity stamp handy for state files / commit messages / cross-agent \
attribution that won't drift across renames or session-continue boundaries \

View file

@ -42,7 +42,7 @@ pub fn hive_name() -> Option<String> {
/// Human display name of the wider swarm this hive belongs to (e.g.
/// `constellat1on`). Federated hives at different DNS domains can
/// share a swarm name. Returns None when the host-side
/// `services.hyperhive.swarmName` option is unset.
/// `services.hyperhive.swarm.name` option is unset.
#[must_use]
pub fn swarm_name() -> Option<String> {
non_empty_env("HYPERHIVE_SWARM_NAME")

View file

@ -268,7 +268,9 @@ fn read_active_model(name: &hive_types::Ident) -> Option<String> {
/// Host-side hive + swarm display names, read from the c0re service's
/// own process env. The `hive-c0re.nix` module sets these from
/// `services.hyperhive.{hiveName, swarmName}`. The agent-side
/// `services.hyperhive.hiveName` + `services.hyperhive.swarm.name`
/// (the hive names itself; the swarm it joins is named one level out).
/// The agent-side
/// `hive-agent::identity::{hive_name, swarm_name}` accessors read the
/// same env vars after they're forwarded into each sub-agent's
/// harness service environment by `meta::render_flake`; surfacing

View file

@ -117,7 +117,7 @@ pub(super) struct StateSnapshot {
hive_name: Option<String>,
/// Human name of the wider swarm this hive belongs to (e.g.
/// `"constellat1on"`). Sourced from `HYPERHIVE_SWARM_NAME` env
/// var, set from `services.hyperhive.swarmName`. `None` when
/// var, set from `services.hyperhive.swarm.name`. `None` when
/// unset — chrome omits the swarm segment of the breadcrumb.
swarm_name: Option<String>,
/// Peer hives in the same swarm. Parsed from `HYPERHIVE_PEERS`

View file

@ -243,7 +243,7 @@ in
description = ''
Human-readable swarm name, rendered per-agent by
`meta.rs::render_flake` from the host's
`services.hyperhive.swarmName`. Same build-time/runtime split as
`services.hyperhive.swarm.name`. Same build-time/runtime split as
`hyperhive.hiveName`.
`null` means the hive is not part of a named swarm.

View file

@ -56,8 +56,8 @@ in
// lib.optionalAttrs (config.services.hyperhive.hiveName != null) {
HYPERHIVE_HIVE_NAME = config.services.hyperhive.hiveName;
}
// lib.optionalAttrs (config.services.hyperhive.swarmName != null) {
HYPERHIVE_SWARM_NAME = config.services.hyperhive.swarmName;
// lib.optionalAttrs (config.services.hyperhive.swarm.name != null) {
HYPERHIVE_SWARM_NAME = config.services.hyperhive.swarm.name;
}
// lib.optionalAttrs (!config.services.hyperhive.github.enable) {
# GitHub integration is on by default; only signal the OFF override to

View file

@ -7,6 +7,16 @@
...
}:
{
# 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";
@ -39,11 +49,12 @@
'';
};
# Human display names for hive + swarm. 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.
# 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;
@ -61,7 +72,10 @@
'';
};
options.services.hyperhive.swarmName = lib.mkOption {
# 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";