diff --git a/CLAUDE.md b/CLAUDE.md index 82a42aef..d1de27a8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -322,6 +322,9 @@ docs/ firewall + federation, provisioning flow, fluffychat-web build network.md host-side bridge + dnsmasq resolver, v1/v2 roadmap, foundation for netns isolation + swarm.md multi-hive swarm config: peer declaration, TLS trust + (CA vs certFingerprint), bilateral setup, identity + env vars, matrix federation pointer ``` ## Reading paths @@ -356,6 +359,9 @@ read them à la carte. [`docs/matrix.md`](docs/matrix.md). - **"How does DNS resolution work in agent containers? What's the bridge network for?"** → [`docs/network.md`](docs/network.md). +- **"How do I connect two hives into a swarm? How do I declare peer + hives and configure TLS trust?"** → + [`docs/swarm.md`](docs/swarm.md). ## Conventions & process diff --git a/docs/swarm.md b/docs/swarm.md new file mode 100644 index 00000000..37da4125 --- /dev/null +++ b/docs/swarm.md @@ -0,0 +1,103 @@ +# Multi-hive swarms + +A **swarm** is a collection of agents that share an identity and +coordinate across one or more hives. A single hyperhive instance +running on one host is already a swarm (one hive). This doc covers +the additional config needed when the swarm spans multiple hosts. + +## Terminology + +- **hive** — a single hyperhive installation on one host. Has its + own `services.hyperhive.domain` DNS name and its own set of agent + containers. +- **swarm** — one or more hives whose operators have declared them + as peers. Agents can be qualified as `agent@hive-domain`. +- **peer hive** — a remote hive declared under + `services.hyperhive.swarm.peers` on the local host. + +## Hive identity config + +```nix +services.hyperhive = { + domain = "pr1ma.example.com"; # machine-addressable DNS domain + hiveName = "pr1ma"; # human display name (optional) + swarmName = "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 +header and per-agent system prompts. Federated hives at different +domains can share a `swarmName`. + +See `docs/conventions.md` § Hive identity for the env-var chain +and `qualify()` / `qualified_label()` semantics. + +## Declaring peer hives + +```nix +services.hyperhive.swarm.peers = { + "lab.example.com" = { }; # CA-trusted (Let's Encrypt etc.) + "edge.corp" = { certFingerprint = "sha256:…"; }; # self-signed TLS +}; +``` + +The attrset key is the peer's DNS domain. `certFingerprint` is +optional: + +- **Omitted / null** — the system CA bundle validates the peer's TLS + cert. Correct for peers with Let's Encrypt or any standard CA cert. +- **Set** (`"sha256:…"`) — pin a specific cert fingerprint. Use this + for peers whose self-signed TLS cert doesn't chain to a CA your + host trusts. + +The nix module serialises the attrset to a `HYPERHIVE_PEERS` JSON +array (`[{ domain, cert_fingerprint }]`) injected into the c0re +environment and forwarded to agent containers. + +## What the config does at runtime + +1. **Dashboard P33RS tab** — `parse_peer_hives()` in `dashboard.rs` + reads `HYPERHIVE_PEERS` and includes + `peer_hives: Vec<{ name, url }>` in `/api/state`. The dashboard + shows a P33RS tab (hidden when the list is empty) with a card per + peer linking to `https://{domain}/`. See + `docs/web-ui/dashboard.md` § P33RS tab. + +2. **Agent identity** — `identity::peers()` in `hive-ag3nt` reads + the same env var and exposes the peer list to agents via + `get_agent_meta` so agents can address peers with qualified names + (`agent@peer-domain`). + +3. **Matrix federation** — when `matrix.enable` is on, tuwunel + federates with the peer's matrix server at + `matrix.{peer-domain}:8448`. No extra config needed; federation + works as soon as the domains are reachable and TLS validates. + See `docs/matrix.md` for federation firewall requirements. + +## Bilateral setup + +Each hive must declare the other. If hive A lists hive B as a peer, +B must also list A for agents on B to see A in their peer list: + +``` +# hive A (pr1ma.example.com) +services.hyperhive.swarm.peers."edge.corp" = { }; + +# hive B (edge.corp) +services.hyperhive.swarm.peers."pr1ma.example.com" = { certFingerprint = "sha256:…"; }; +``` + +Mixed trust is fine: A trusts B via CA bundle (no fingerprint), B +pins A's self-signed cert. + +## Cross-references + +- `docs/conventions.md` § Hive identity — env vars, qualified labels +- `docs/matrix.md` — matrix federation, TLS cert auto-generation, + firewall posture +- `docs/web-ui/dashboard.md` § P33RS tab — dashboard surface +- `docs/gateway.md` — nginx vhosts and the `.well-known/matrix/` + auto-discovery scheme