diff --git a/docs/conventions.md b/docs/conventions.md index 864ddf44..4a0d8a6b 100644 --- a/docs/conventions.md +++ b/docs/conventions.md @@ -13,6 +13,44 @@ exist because something already went wrong without them. (8100..8999) for every agent including the manager; dashboard `cfg.dashboardPort` (default 7000). +## Hive identity (label + domain + display names) + +Four env vars cover the identity surface, read by +`hive_ag3nt::identity`: + +- `HIVE_LABEL` — short, hive-local agent label (`iris`, + `damocles`). `label()` returns it; falls back to empty string if + the env var is missing so downstream callers can decide how to + surface "unknown agent" rather than getting a panic from this + module. +- `HYPERHIVE_HIVE_DOMAIN` — the hive's canonical DNS domain (e.g. + `darkest.space`), set by `hive-c0re.nix` from + `services.hyperhive.domain`. When configured, `qualified_label()` + returns `${label}@${domain}` (e.g. `iris@darkest.space`); when + unset (single-hive deployments, dev/test) it degrades to just + the short label so existing callers see no change. The + qualified form surfaces in the per-agent web UI title, the + system-prompt template, and `/api/state.qualified_label`. +- `HYPERHIVE_HIVE_NAME` — human display name of this hive + (`pr1ma`). Read by `hive_name()`; `None` when unset. +- `HYPERHIVE_SWARM_NAME` — human display name of the wider swarm + this hive belongs to (`constellat1on`). Read by `swarm_name()`; + federated hives at different DNS domains can share a swarm + name. + +`hive_name` + `swarm_name` are **distinct** from +`HYPERHIVE_HIVE_DOMAIN`: the domain may carry the hive name as +its leftmost label by convention, but the convention isn't +machine-readable, and federated hives at different DNS domains +can share a swarm name. Humans want both: the address +(`@darkest.space`) AND the prose name (`pr1ma`). Matrix MXIDs +still use the domain-based convention untouched. + +`qualify(label)` is the same shape as `qualified_label()` but +applies to an arbitrary label the caller already has (e.g. a peer +name from the broker); it's the right surface when rendering a +peer's name when the caller knows it's hive-local. + ## Identity = socket There are no auth tokens on the per-agent unix sockets. The socket diff --git a/hive-ag3nt/src/identity.rs b/hive-ag3nt/src/identity.rs index 4cbbd1d9..1145ff8b 100644 --- a/hive-ag3nt/src/identity.rs +++ b/hive-ag3nt/src/identity.rs @@ -1,32 +1,7 @@ //! Agent identity helpers — short label + hive-qualified long name + -//! human display names for the hive and swarm. -//! -//! `HIVE_LABEL` is the short, hive-local agent name (e.g. `iris`, `damocles`). -//! `HYPERHIVE_HIVE_DOMAIN` is the hive's canonical DNS domain (e.g. -//! `darkest.space`). When the hive-domain env var is set (set by the -//! `hive-c0re.nix` module from `hyperhive.domain`), the qualified label is -//! `${label}@${domain}` — e.g. `iris@darkest.space`. When unset (single-hive -//! deployments, dev/test scenarios) the qualified label degrades to just the -//! short label so existing callers see no change. -//! -//! Per #589 v0: this qualified form surfaces in the per-agent web UI title, -//! the system prompt template, and `/api/state.qualified_label`. Broker -//! `from` / `to` qualification + dashboard rendering of cross-hive -//! identities are subsequent follow-ups inside #589. -//! -//! `HYPERHIVE_HIVE_NAME` + `HYPERHIVE_SWARM_NAME` are human-readable -//! display names for the local hive (`pr1ma`) and the wider swarm -//! (`constellat1on`) — added in #701 after mara's -//! `internal-requests#9` ("we want to persist this name somewhere in -//! the hive"). They're **distinct** from the DNS domain above: the -//! domain may carry the hive name as its leftmost label by -//! convention, but the convention isn't machine-readable, and -//! federated hives at different DNS domains can share a swarm name. -//! Both reverse the earlier #589 spec decision (mara #6577 / iris -//! #6582 dropped `hyperhive.hiveName` in favour of "the domain IS the -//! name") — turns out humans want both: the address (`@darkest.space`) -//! AND the prose name (`pr1ma`). Matrix MXIDs still use the -//! domain-based convention untouched. +//! human display names for the hive and swarm. Full env var surface + +//! domain-vs-name distinction documented in +//! `docs/conventions.md::Hive identity (label + domain + display names)`. use std::env; @@ -54,7 +29,7 @@ pub fn hive_domain() -> Option { /// this is the prose label humans use in conversation. Returns None /// when the host-side `services.hyperhive.hiveName` option is unset, /// in which case callers fall back to the domain or the short label -/// at their discretion (#701). +/// at their discretion. #[must_use] pub fn hive_name() -> Option { env::var("HYPERHIVE_HIVE_NAME") @@ -65,7 +40,7 @@ pub fn hive_name() -> Option { /// 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 (#701). +/// `services.hyperhive.swarmName` option is unset. #[must_use] pub fn swarm_name() -> Option { env::var("HYPERHIVE_SWARM_NAME") @@ -100,12 +75,12 @@ mod tests { use super::*; use std::sync::Mutex; - /// Per damocles's #595 review: cargo's test runner parallelises by - /// default, so a `with_env` helper that mutates process-wide env vars - /// races between tests in this module. Serialise on a module-scope - /// mutex so each `with_env` call holds the lock for its set / run / - /// restore window. Cheap (each test body is microseconds) and avoids - /// pulling in `serial_test` for just one module. + /// cargo's test runner parallelises by default, so a `with_env` + /// helper that mutates process-wide env vars races between tests in + /// this module. Serialise on a module-scope mutex so each `with_env` + /// call holds the lock for its set / run / restore window. Cheap + /// (each test body is microseconds) and avoids pulling in + /// `serial_test` for just one module. static ENV_LOCK: Mutex<()> = Mutex::new(()); /// Helper: run `f` with a clean env, restoring previous values on exit. @@ -118,9 +93,9 @@ mod tests { with_full_env(label, domain, None, None, f); } - /// Extended form of [`with_env`] covering the #701 display-name env - /// vars (hive name + swarm name) alongside label + domain. Same - /// SAFETY contract — serialised on `ENV_LOCK`, restore in scope. + /// Extended form of [`with_env`] covering the display-name env vars + /// (hive name + swarm name) alongside label + domain. Same SAFETY + /// contract — serialised on `ENV_LOCK`, restore in scope. fn with_full_env( label: Option<&str>, domain: Option<&str>, @@ -260,7 +235,7 @@ mod tests { fn name_accessors_independent_from_domain() { // hive_name + swarm_name surface without HYPERHIVE_HIVE_DOMAIN // being set — the names are display labels, not derived from - // the DNS domain (#701, mara on internal-requests#9). + // the DNS domain. with_full_env( Some("iris"), None,