Watch
0
0
Fork
You've already forked hyperhive
0

docs: sort the top-level directories into five sections by what the reader wants

Every docs directory moves under 1-getting-started, 2-handbook,
4-implementation or 5-project; the options reference (section 3) comes from
the website and has no directory here. trust-boundary stays whole under the
handbook for now. web-ui, swarm and tools split between handbook and
implementation, and the command-line references move to
2-handbook/reference. Links, path references in code and nix, and the docs
index follow the moves; no page content changes.
This commit is contained in:
iris 2026-11-06 18:30:12 +01:00 • committed by mara
commit 6739bb903d
38 changed files with 736 additions and 701 deletions

View file

@ -1,5 +1,5 @@
# The `bao-bootstrap` policy: what the 24h bootstrap token may do, and nothing
# else. ../../docs/getting-started/setup.md has the operator write it with the
# else. ../../docs/1-getting-started/setup.md has the operator write it with the
# root token, from the copy ./swarm-bao.nix ships at
# /etc/hyperhive/bao-bootstrap-policy.hcl; `swarm-bao-granter-role` then acts
# with it. Every other grant is written by the `bao-granter` principal this

View file

@ -397,7 +397,7 @@ in
No hive CA is generated any more: the gateway leaf is issued by the
secret store's pki mount, whose per-hive role sets its lifetime
(services.hyperhive.deploy.bao.servicesPkiLeafTtlHours). Remove this
definition. See docs/swarm/ca.md.
definition. See docs/4-implementation/swarm/ca.md.
''
)
(lib.mkRemovedOptionModule
@ -406,7 +406,7 @@ in
No hive CA is generated any more: the gateway leaf is issued by the
secret store's pki mount, whose per-hive role sets its lifetime
(services.hyperhive.deploy.bao.servicesPkiLeafTtlHours). Remove this
definition. See docs/swarm/ca.md.
definition. See docs/4-implementation/swarm/ca.md.
''
)
@ -728,7 +728,7 @@ in
machine-addressable DNS name. Exposed to agents as
`HYPERHIVE_HIVE_NAME`; surfaced in the dashboard chrome and per-agent
system prompt. The identity surfaces are listed in
`docs/process/conventions.md`, § Hive identity.
`docs/5-project/process/conventions.md`, § Hive identity.
'';
};

View file

@ -41,7 +41,7 @@ in
(lib.mkIf (onHiveVhost && hyperhiveCfg.deploy.matrix.enable) {
# `<hive>/matrix/*` → 301 → `gatewayHost`'s vhost/$1 (`chat.<swarm-domain>`
# by default; legacy deep-link shim for the fluffychat sub-domain).
# See `docs/networking/gateway.md`.
# See `docs/4-implementation/networking/gateway.md`.
services.hyperhive.gateway.vhosts.${hyperhiveCfg.domain}.locations."/matrix/" = {
extraConfig = ''
rewrite ^/matrix/(.*)$ ${homeserverUrl}/$1 permanent;
@ -53,7 +53,7 @@ in
services.hyperhive.gateway.vhosts.${hyperhiveCfg.domain}.locations = {
# `.well-known/matrix/{client,server}` discovery JSON, pointing
# clients and peers at `gatewayHost`: the homeserver has no other
# address. CORS `*` per matrix spec. See `docs/networking/gateway.md`.
# address. CORS `*` per matrix spec. See `docs/4-implementation/networking/gateway.md`.
"= /.well-known/matrix/client" = {
extraConfig = ''
default_type application/json;
@ -69,7 +69,7 @@ in
# explicit even when it's the HTTPS default, unlike the client
# base_url above. Without it, peers federate to <gatewayHost>:8448
# (closed) while the endpoint actually lives on the gateway's 443
# vhost. See docs/networking/gateway.md discovery flow.
# vhost. See docs/4-implementation/networking/gateway.md discovery flow.
"= /.well-known/matrix/server" = {
extraConfig = ''
default_type application/json;

View file

@ -181,7 +181,7 @@ in
# Operators granted sudoless `hivectl`. Members of `hive-admin` can
# connect to the host admin socket (group-owned by hive-admin via the
# socket unit's `SocketGroup` below) without root. That socket is *full*
# hive control (spawn/kill/destroy/deploy, docs/trust-boundary/boundary.md), so this is
# hive control (spawn/kill/destroy/deploy, docs/2-handbook/trust-boundary/boundary.md), so this is
# an explicit opt-in allowlist — empty by default (root-only).
users.groups.hive-admin = {
members = controllerCfg.adminUsers;
@ -210,7 +210,7 @@ in
# The gateway nginx is always the sole external entry point (it runs
# alongside hyperhive), so the per-agent web-port range stays closed on
# the host firewall. See `docs/networking/gateway.md::Firewall posture (host-level)`.
# the host firewall. See `docs/4-implementation/networking/gateway.md::Firewall posture (host-level)`.
# NB: `services.hyperhive.domain` is required when hyperhive is
# enabled — the canonical assertion lives in `hive-network.nix` (the
@ -356,7 +356,7 @@ in
# `0660 root:hive-admin` — group-owned by `hive-admin` so operators in
# that group (services.hyperhive.deploy.hive-controller.adminUsers) drive `hivectl`
# without root; an empty adminUsers list leaves the group memberless,
# so it stays effectively root-only. See docs/trust-boundary/boundary.md.
# so it stays effectively root-only. See docs/2-handbook/trust-boundary/boundary.md.
SocketMode = "0660";
SocketGroup = "hive-admin";
# Only consulted when the directory is absent at socket-unit

View file

@ -67,7 +67,7 @@ in
// {
# Identity env vars threaded into c0re's own service env and
# forwarded by meta.rs into every sub-agent's harness env —
# full chain in docs/process/conventions.md::Hive identity. `domain` is
# full chain in docs/5-project/process/conventions.md::Hive identity. `domain` is
# required (asserted in hive-network.nix), so it's always set.
HYPERHIVE_HIVE_DOMAIN = config.services.hyperhive.domain;
}
@ -122,7 +122,7 @@ in
# hive-c0re (forge/mod.rs `forge_http_base()`) and forwarded to
# agents via meta.rs for their forge-notify client. The forge is
# mandatory, so this is unconditional (the whole env block is already
# gated on hyperhive being enabled). See `docs/networking/gateway.md::HIVE_FORGE_URL`.
# gated on hyperhive being enabled). See `docs/4-implementation/networking/gateway.md::HIVE_FORGE_URL`.
HIVE_FORGE_URL = "http://${config.services.hyperhive.swarm.forge.domain}";
# The one blacklist of names an agent may not take — see

View file

@ -234,7 +234,7 @@ in
`hivectl` (and thus the whole hive) without `sudo`.
This is a real privilege grant: the admin socket is *full* hive
control — spawn / kill / destroy / deploy — see `docs/trust-boundary/boundary.md`.
control — spawn / kill / destroy / deploy — see `docs/2-handbook/trust-boundary/boundary.md`.
Keep the list to trusted operators. Empty (the default) keeps the
socket root-only, as before.
'';

View file

@ -4,7 +4,7 @@
# dashboard re-themes with no operator action and no npm/esbuild
# rebuild (a pure file-copy over the prebuilt dist). `colors.css` is
# the entire swap contract — `theme.css` derives every semantic var
# from the 16 base16 slots (see docs/web-ui/css-vars.md). The guarded
# from the 16 base16 slots (see docs/4-implementation/web-ui/css-vars.md). The guarded
# access makes this a clean no-op when stylix isn't imported into the
# host config. Exposed as the read-only `deploy.hive-controller.servedFrontend` option.
#

View file

@ -161,7 +161,7 @@ in
# netns, on the one host with `deploy.forgejo.enable`. Agents reach it
# at `forge.<domain>` via the gateway. State at
# `/var/lib/nixos-containers/hive-forge/var/lib/forgejo/` survives
# restart. See `docs/networking/gateway.md::hive-forge container shape`.
# restart. See `docs/4-implementation/networking/gateway.md::hive-forge container shape`.
imports = [
./service.nix
@ -319,7 +319,7 @@ in
# `server_name = forge.domain`, proxies all `/` → forgejo. Tuned for
# git: `client_max_body_size 1G`, `proxy_read_timeout 1h` (multi-GB
# clones). SSH stays direct on `forge.sshPort`. See
# `docs/networking/gateway.md`.
# `docs/4-implementation/networking/gateway.md`.
services.hyperhive.gateway.vhosts = {
"${cfg.domain}" = {
locations = {
@ -963,7 +963,7 @@ in
# container, where forgejo already stores it at rest in the
# login-source row — root and forgejo are the only
# principals here, and root can read the resting copy
# anyway. Accepted deliberately (see docs/swarm/), not
# anyway. Accepted deliberately (see docs/2-handbook/swarm/), not
# overlooked; upstream gap filed.
# An ARRAY, not a string. A string of arguments has to be
# word-split at the call site to become argv, and splitting

View file

@ -55,7 +55,7 @@ in
Public hostname for the forge. Doubles as both the forgejo
`DOMAIN` setting (clone URLs forgejo advertises) AND the
gateway vhost server-name (sub-domain routing — see
`docs/networking/gateway.md`).
`docs/4-implementation/networking/gateway.md`).
Defaults to `forge.''${services.hyperhive.swarm.domain}` — the
swarm's domain, not this hive's, because a swarm runs **one**
@ -85,7 +85,7 @@ in
Defaults to `https://''${cfg.domain}`, the gateway vhost. When
`null`, the dashboard **hides** forge links rather than
guessing one — see `docs/web-ui/dashboard.md::Container row` for
guessing one — see `docs/2-handbook/web-ui/dashboard.md::Container row` for
the rationale (a link built from the operator's own browser
hostname + a container port is only an accident away from
wrong on any deployment that isn't plain localhost).

View file

@ -5,7 +5,7 @@
# answers on the hive bridge, so neither can be confined to a network
# namespace of its own.
# Full vhost map + discovery flow + design rationale in
# `docs/networking/gateway.md`. Layout: ./options.nix (option declarations),
# `docs/4-implementation/networking/gateway.md`. Layout: ./options.nix (option declarations),
# ./vhosts.nix (the catch-all `_` vhost), ./declared-vhosts.nix
# (renders the vhosts service modules declare under `gateway.vhosts`), ./error-pages.nix
# (styled static pages), ./dns.nix + ./dnsmasq.nix (the resolver, which
@ -241,7 +241,7 @@ in
# and it puts a file at every cert path the config names or fails: one
# nginx cannot find takes the WHOLE gateway down, not one vhost. Both
# mechanisms, and what it cost the time this was
# collapsed: `docs/networking/gateway.md::Self-signed TLS (default)`.
# collapsed: `docs/4-implementation/networking/gateway.md::Self-signed TLS (default)`.
#
# ALWAYS runs (no ConditionPathExists) and is idempotent, because it
# has to reconcile broken state from earlier failed boots — a 0700 dir
@ -350,7 +350,7 @@ in
# through hive-priv after each agents.conf write, deliberately as an
# explicit trigger rather than a path unit. Why, and what hive-priv
# dispatches per unit state:
# `docs/networking/gateway.md::Per-agent unix-socket upstream`.
# `docs/4-implementation/networking/gateway.md::Per-agent unix-socket upstream`.
services.nginx = {
enable = true;
@ -414,7 +414,7 @@ in
};
# `/etc/hosts` entries for local dev — the bare hive domain plus
# every name a service module contributed. See `docs/networking/gateway.md`
# every name a service module contributed. See `docs/4-implementation/networking/gateway.md`
# ("Local dev").
#
# This does not restate the per-service list (the vhosts and the

View file

@ -1,7 +1,7 @@
# Static error/help pages the gateway serves for routes it has
# special-cased, all rendered from one Catppuccin-styled template.
# Useful pages instead of nginx's default 404/502 — see
# `docs/networking/gateway.md::Per-agent error pages` for the design rationale +
# `docs/4-implementation/networking/gateway.md::Per-agent error pages` for the design rationale +
# page-vs-status semantics. Published as `gateway.lib.errorPages`.
{ pkgs }:
let

View file

@ -51,7 +51,7 @@ in
# The gateway always terminates TLS: self-signed is the implicit
# floor when neither `tls.certDir` nor ACME is set, so there is no
# http-only mode. Listen addresses every vhost shares — plain http
# on `cfg.port` plus TLS on `cfg.httpsPort`. See `docs/networking/gateway.md`
# on `cfg.port` plus TLS on `cfg.httpsPort`. See `docs/4-implementation/networking/gateway.md`
# ("TLS modes").
listen = [
{
@ -90,7 +90,7 @@ in
# — invisibly, it works and keeps working against any certificate at
# all. Full reasoning for every directive here (plus two real
# footguns — session-cache keying, and a `Host`-header clobber that
# can recurse a subrequest into itself) is in docs/networking/gateway.md's
# can recurse a subrequest into itself) is in docs/4-implementation/networking/gateway.md's
# "Dialing another vhost by name" section — read it before touching
# this.
verifiedProxyTo = name: ''

View file

@ -71,7 +71,7 @@ in
Defaults to `chat.''${services.hyperhive.swarm.domain}` — the
swarm's domain, because a swarm runs **one** homeserver. Set to
`null` to skip the gateway vhost, which leaves nothing able to
reach the homeserver. See `docs/networking/gateway.md` for the vhost map + matrix
reach the homeserver. See `docs/4-implementation/networking/gateway.md` for the vhost map + matrix
discovery flow, and the federation port-8448 caveat at the
bottom of that doc.

View file

@ -228,7 +228,7 @@ let
# skips the dart web-worker compile + the emscripten native_imaging
# build. Two derivations below cover both. Full rationale (why
# passthru.pubspecLock.dependencySources, why `dontConfigure`, why
# `make -C js`, why build-CWD-relative dart path): docs/integrations/matrix.md::
# `make -C js`, why build-CWD-relative dart path): docs/2-handbook/integrations/matrix.md::
# fluffychat-web build fixes.
fluffychat-web-imaging = pkgs.stdenv.mkDerivation {
@ -312,8 +312,8 @@ in
# default). Container shape,
# serverName vs gatewayHost split, provisioning flow (registration
# token + LoadCredential), assertion rationale, initial rollout
# settings: docs/integrations/matrix.md. Vhost map + discovery flow + tuning
# knobs: docs/networking/gateway.md.
# settings: docs/2-handbook/integrations/matrix.md. Vhost map + discovery flow + tuning
# knobs: docs/4-implementation/networking/gateway.md.
# `swarm.matrix`, in ./hive-matrix-service.nix, is what the homeserver IS from
# any hive's point of view: the name it answers to, the URLs it is
@ -492,7 +492,7 @@ in
services.hyperhive.gateway.dns.enable = lib.mkDefault true;
# Accept-header SPA map, used only by the `/` location below (see
# docs/networking/gateway.md "SPA fallback"): text/html → index.html, else a
# docs/4-implementation/networking/gateway.md "SPA fallback"): text/html → index.html, else a
# sentinel so `try_files` falls through to 404. `appendHttpConfig`
# is a `lines` option, so this merges with anything else the host
# contributes instead of replacing it.
@ -573,7 +573,7 @@ in
# hive-network.nix) when not set explicitly, so no separate
# domain/serverName assertion is needed here. gatewayHost may not be
# "" (same footgun as forge.domain — nginx rejects an empty
# server_name). docs/integrations/matrix.md::Assertion rationale.
# server_name). docs/2-handbook/integrations/matrix.md::Assertion rationale.
assertions = [
{
assertion = cfg.gatewayHost == null || cfg.gatewayHost != "";
@ -765,7 +765,7 @@ in
# Activation-time token generation — without this the bind-mount
# would hand tuwunel an empty file on first boot and break every
# registration until restart. Idempotent;
# docs/integrations/matrix.md::Provisioning flow.
# docs/2-handbook/integrations/matrix.md::Provisioning flow.
# Tell an operator whose homeserver already exists that `serverName` is
# unpinned, at the one moment they are looking: the rebuild.
#

View file

@ -60,7 +60,7 @@ let
in
{
# Hive-internal network — the host-side bridge every container in a
# private netns hangs off. Full design: docs/networking/network.md.
# private netns hangs off. Full design: docs/4-implementation/networking/network.md.
options.services.hyperhive.network = {
enable = lib.mkOption {
@ -267,7 +267,7 @@ in
# Container isolation overlay — the routing, NAT and firewall half of
# the same bridge, so it rides the same gate.
# See docs/networking/network.md#container-isolation.
# See docs/4-implementation/networking/network.md#container-isolation.
(lib.mkIf cfg.enable {
# Agents route internet traffic via the bridge; NAT masquerades their RFC-1918 IPs.

View file

@ -1,5 +1,5 @@
# hive-priv — the narrow root privileged helper hive-c0re delegates
# to, socket-activated at /run/hive/priv.sock. See docs/trust-boundary/boundary.md
# to, socket-activated at /run/hive/priv.sock. See docs/2-handbook/trust-boundary/boundary.md
# for the operator/agent trust-boundary design.
{
pkgs,

View file

@ -301,7 +301,7 @@ in
# federation peers) anchor on that mount's root, which ships in
# `trust-bundle.pem`. Leaf rotation never re-breaks them, and nothing here
# generates or signs with a CA key. See
# `docs/networking/gateway.md` ("Self-signed TLS") and docs/swarm/ca.md.
# `docs/4-implementation/networking/gateway.md` ("Self-signed TLS") and docs/4-implementation/swarm/ca.md.
options.services.hyperhive.deploy.hive-controller.tls = {
stateDir = lib.mkOption {
@ -436,7 +436,7 @@ in
# --- Trust bundle: what a consumer must TRUST, the store's `pki`
# root, which both the gateway leaf and the swarm-services leaf
# chain to (docs/swarm/ca.md).
# chain to (docs/4-implementation/swarm/ca.md).
#
# Written IN PLACE, never renamed into position — containers
# bind-mount this file and a bind mount follows the inode, so a

View file

@ -65,7 +65,7 @@ let
lib.mkRemovedOptionModule [ "services" "hyperhive" "swarm" "ca" name ] ''
The host-held swarm root CA is gone: the secret store's pki root is the
only trust anchor, and nothing generates or reads a root under
${swarmCaDir}. Remove this definition. See docs/swarm/ca.md.
${swarmCaDir}. Remove this definition. See docs/4-implementation/swarm/ca.md.
'';
in
{
@ -81,7 +81,7 @@ in
${option} is ${toString path}, a file every host deletes along with
the host-held CA it belonged to. Point it at the store's mTLS CA:
/var/lib/swarm-bao-pki/ca.pem on the host that runs the store, the copy
placed by hand on any other host. See docs/swarm/ca.md.
placed by hand on any other host. See docs/4-implementation/swarm/ca.md.
'';
}) caFileOptions;

View file

@ -31,7 +31,7 @@ in
# 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/process/conventions.md::
# chain → identity.rs → claude prompt): docs/5-project/process/conventions.md::
# Hive identity (label + domain + display names).
options.services.hyperhive.domain = lib.mkOption {
type = lib.types.nullOr lib.types.str;
@ -133,7 +133,7 @@ in
# The hive's name is `deploy.hive-controller.hiveName`, declared in
# ./deploy.nix beside the switch that makes a host run a hive. The
# identity surfaces (label, domain, display names, env-var chain) are in
# docs/process/conventions.md::Hive identity.
# docs/5-project/process/conventions.md::Hive identity.
#
# A hive turns the name into an identifier with no fallback: hive-c0re's
# OIDC client and matrix localpart, the CN of the hive's `client.pem`

View file

@ -42,7 +42,7 @@
exit 0
fi
echo ${lib.escapeShellArg "the store refused the bootstrap token in ${bootstrapTokenFile}: it has expired, been revoked, or does not carry the bao-bootstrap policy."} >&2
echo "one-time step, as root on this host (docs/getting-started/setup.md):" >&2
echo "one-time step, as root on this host (docs/1-getting-started/setup.md):" >&2
${lib.concatMapStringsSep "\n" (l: "echo ${lib.escapeShellArg " ${l}"} >&2") setupSteps}
cat "$err" >&2
exit 4

Some files were not shown because too many files have changed in this diff Show more