diff --git a/docs/swarm/README.md b/docs/swarm/README.md index 87466635..a704a692 100644 --- a/docs/swarm/README.md +++ b/docs/swarm/README.md @@ -129,10 +129,17 @@ conventionally `.`, but a wrong domain that evaluates cleanly points at a real machine that isn't the one you meant. **`certFingerprint`** (`"sha256:…"`, optional) pins that hive's TLS -_leaf_. Scopes **only** to hive-c0re's own peer HTTPS checks (the P33RS -dashboard links + agent peer discovery below); matrix federation never -consults it. Omit it for any hive under the swarm root CA or a public -CA — which is the normal case. +_leaf_. Matrix federation never consults it. Omit it for any hive +under the swarm root CA or a public CA — which is the normal case. + +⚠️ **Currently unconsumed by any Rust code.** It was read by the +per-hive dashboard's now-removed "peer hives" display (see below); +that was its only consumer. Left in place rather than deleted along +with that display — removing a documented, potentially +already-set nix option is a bigger, more consequential (breaking) +change than removing dead display code, and wants its own explicit +decision rather than being swept up here. A future peer-facing +feature (e.g. pinning a peer in `swarm-ui`) could pick it back up. > **There is no per-hive CA field.** Trust inside a swarm comes from the > swarm root ([`ca.md`](ca.md)): every hive chains to it, so one anchor @@ -180,19 +187,17 @@ environment and forwarded to agent containers. ## What the config does at runtime -1. **Dashboard P33RS tab** — hive-c0re reads `HYPERHIVE_PEERS` and - surfaces it as the peer list in the dashboard's state API. The - dashboard shows a P33RS tab (hidden when the list is empty) with a - card per peer linking to `https://{domain}/`. Wire format + module - pointer: `docs/web-ui/dashboard.md` § P33RS tab. - -2. **Agent identity** — the same `HYPERHIVE_PEERS` env var is - forwarded to agent containers, so agent code can discover peer - hives and address them with qualified names (`agent@domain`). See +1. **Agent identity** — the `HYPERHIVE_PEERS` env var is forwarded to + agent containers, so agent code can discover peer hives and + address them with qualified names (`agent@domain`). See `hive-agent/src/identity.rs`'s module doc for the label/domain - helpers. + helpers. The swarm-wide hive roster used to also be shown as a + "peer hives" list on the per-hive dashboard; that display was + removed in favour of `swarm-ui`'s own roster page (`docs/swarm/ + ui.md`), which reads the same directory from `swarm-controller` + instead. -3. **Matrix federation** — when `matrix.enable` is on, tuwunel +2. **Matrix federation** — when `matrix.enable` is on, tuwunel federates with the peer's matrix server (discovered via the peer's `.well-known/matrix/server` delegation, which the gateway serves). Federation validates the peer's TLS certificate against the matrix @@ -370,6 +375,8 @@ it is stored in the queue, not in the daemon. - `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/swarm/ui.md` — the swarm-wide hive roster, now the operator + surface for "what hives exist" (superseded the per-hive dashboard's + old "peer hives" display) - `docs/gateway.md` — nginx vhosts and the `.well-known/matrix/` auto-discovery scheme diff --git a/docs/web-ui/dashboard.md b/docs/web-ui/dashboard.md index 1428aff2..5d827a8c 100644 --- a/docs/web-ui/dashboard.md +++ b/docs/web-ui/dashboard.md @@ -7,7 +7,7 @@ The dashboard is served at `/dashboard.html` (with the home page at `/`). It has a fixed chrome header at the top and a `
` that shows exactly one tab pane at a time. The URL hash (`#swarm`, `#call`, `#system`, -`#permissions`, `#schedules`, `#peers`, `#settings`) drives which pane is +`#permissions`, `#schedules`, `#settings`) drives which pane is active; hash changes don't reload the page. FL0W, L0GS, and the optional M4TR1X client are separate pages reachable from the H0M3 hub at `/`, not from the dashboard tab strip. @@ -19,11 +19,10 @@ from the dashboard tab strip. `◆ SCH3DUL3S ◆`. In-page tabs only — the SYST3M panels moved to the standalone **C0R3** page (`/core.html`), and FL0W / L0GS / ST4TS / S3TT1NGS / M4TR1X live on their own pages too, all reachable from the - H0M3 hub (not the tab strip). Peer hives render as a headline under - SW4RM rather than a tab. Count pills on SW4RM + H0M3 hub (not the tab strip). Count pills on SW4RM (container count), Y3R C4LL (pending approvals + questions + unread - operator messages), and SCH3DUL3S (active schedules); P33RS and - S3TT1NGS have no count. + operator messages), and SCH3DUL3S (active schedules); S3TT1NGS has no + count. - **Banner-thin** (`░▒▓█▓▒░ HYPERHIVE / HIVE-C0RE / WE ARE THE WIRED ░▒▓█▓▒░`) — sits below the tab strip. - **Server-warnings banner** — a generic, sticky top-of-page strip shown @@ -642,44 +641,6 @@ the model id, longest match wins) mapping to `{ input, output, cache_read, cache_write }` USD-per-million-token prices. Models not covered fall back to hive-c0re's built-in estimate. -## P33R H1V3S (within the SW4RM tab) - -Peer hives in this swarm. Not its own tab — a headline block -(`#peers-block`) rendered under the SW4RM tab's container list (see -"Chrome header" above: "Peer hives render as a headline under SW4RM -rather than a tab"). The block is hidden when the -`state.peer_hives` array from `/api/state` is empty — i.e. when -`services.hyperhive.swarm.hives` holds no hive other than this one. -When at least one peer is present the `hidden` attribute is removed -and the cards render. - -**P33R H1V3S** — each peer renders as a card row: a hexagon icon -(`⬡`), the peer's DNS domain as the primary name, and the peer -dashboard HTTPS URL as a clickable secondary link. Clicking the -URL opens the peer hive's dashboard in a new tab. - -### Backend wiring - -The host daemon reads `services.hyperhive.swarm.peerHives` from the -nix config (the `swarm.hives` directory minus this hive), serialises -each entry as `{ name, url }` into `state.peer_hives: Vec`, -and includes the field in the `/api/state` snapshot. `tabs.js` -reads `state.peer_hives` on every `refreshState` call and calls -`swarm.js::renderPeerHives(peers)`, which rebuilds the `#peers-section` -div from scratch. - -The `name` field is the peer's DNS domain (its entry's `domain`, not -the attrset key — the key is the hive's name); `url` -is `https://{domain}/`. Both are derived from the env var -`HYPERHIVE_PEERS` (a JSON array of `{ domain, cert_fingerprint }` -objects) that the nix module writes into the c0re container -environment. `cert_fingerprint` is null for CA-trusted (e.g. -Let's Encrypt) peers and non-null to pin a self-signed cert. -`parse_peer_hives()` in `hive-c0re/src/dashboard/state_snapshot.rs` -converts each entry to the -`PeerHiveView { name: domain, url: "https://domain/" }` shape the -frontend reads. - ## S3TT1NGS tab Operator-local preferences. State lives in the browser's diff --git a/nix/host-modules/hive-c0re/environment.nix b/nix/host-modules/hive-c0re/environment.nix index 46be1d8e..852d2f23 100644 --- a/nix/host-modules/hive-c0re/environment.nix +++ b/nix/host-modules/hive-c0re/environment.nix @@ -211,10 +211,13 @@ in } // lib.optionalAttrs (config.services.hyperhive.swarm.peerHives != { }) { # Peer hives serialised as a JSON array of {domain, cert_fingerprint, - # wireguard_address?} objects. Consumed by hive-agent::identity::peers() - # + the dashboard's peer_hives StateSnapshot field (P33RS tab). - # `cert_fingerprint` is null for CA-trusted hives; `wireguard_address` - # is omitted when not part of the mesh. + # wireguard_address?} objects. Consumed by hive-agent::identity::peers(). + # `cert_fingerprint` is currently unconsumed (was read only by the + # per-hive dashboard's now-removed "peer hives" display — see + # docs/swarm/README.md's certFingerprint note); still emitted here + # since the shape is shared with `wireguard_address`, which is not + # dead. `cert_fingerprint` is null for CA-trusted hives; + # `wireguard_address` is omitted when not part of the mesh. # # Reads `peerHives` — `swarm.hives` minus this hive — so the "not me" # filter is the one derived in ../swarm.nix rather than a fifth copy. diff --git a/nix/host-modules/swarm-wireguard.nix b/nix/host-modules/swarm-wireguard.nix index 1f393131..557090ff 100644 --- a/nix/host-modules/swarm-wireguard.nix +++ b/nix/host-modules/swarm-wireguard.nix @@ -1,9 +1,9 @@ # The WireGuard inter-hive mesh for the local host. Split out of # ./swarm.nix because the two are different concerns with different # audiences: that file declares WHO the peers are (data hive-c0re -# serialises into HYPERHIVE_PEERS and the dashboard renders), while -# this one is plain host networking that a machine which runs no hive -# at all --- the snapshot store, for one --- still needs. +# serialises into HYPERHIVE_PEERS for agent identity), while this one +# is plain host networking that a machine which runs no hive at all +# --- the snapshot store, for one --- still needs. # # The two stay coupled by data, not by structure: the per-peer # `wireguard*` fields live on the peer submodule in ./swarm.nix, since diff --git a/nix/host-modules/swarm.nix b/nix/host-modules/swarm.nix index d3502e45..238d2a27 100644 --- a/nix/host-modules/swarm.nix +++ b/nix/host-modules/swarm.nix @@ -11,7 +11,8 @@ # detected it. One entry per hive makes that unrepresentable. # # Consumed by hive-c0re's environment (HYPERHIVE_PEERS — see -# ./hive-c0re), identity.rs + the dashboard's P33RS tab, and the mesh in +# ./hive-c0re), identity.rs, swarm-controller's own hive directory (its +# `/api/hives`, swarm-controller.nix), and the mesh in # ./swarm-wireguard.nix. The mesh lives there rather than here because # bringing up an interface is host networking rather than swarm # bookkeeping, and a host that runs no hive still needs it.