From 0e84fe8bc4c9f1e0b436c91cbf95c2383412a6ce Mon Sep 17 00:00:00 2001 From: iris Date: Sat, 7 Nov 2026 11:20:48 +0100 Subject: [PATCH] docs: the handbook follows the three layers: swarm, hives, agents The handbook's sections were agent-lifecycle, integrations, swarm, tools, trust-boundary and web-ui, which do not follow how the system is built, so a reader could not tell which layer a page is about. Its pages now sit in swarm/, hives/ and agents/, with the accounts an agent can hold outside the system in external-accounts/. - swarm/: forge, matrix and the knowledge repo join the swarm pages, and so does the swarmctl reference. - hives/: the dashboard, hivectl and its reference, and the operator/agent boundary, with a README that takes over the old web-ui and tools pages. - agents/: the roster, persistence, config changes, the agent's own web page (was web-ui/agent) and the security model, with a README. - external-accounts/: GitHub and GitLab. Pages are moved whole; none is split yet. Every reference follows: relative links in the docs, `docs/2-handbook/...` paths in code comments, the nix checks that regenerate the CLI references and the ignore list, and docs/README.md, whose handbook section is now by layer. --- .prettierignore | 14 +-- AGENTS.md | 16 +-- README.md | 16 +-- docs/1-getting-started/setup.md | 4 +- docs/2-handbook/agents/README.md | 24 ++++ .../agent-roster.md | 2 +- .../config-changes.md | 2 +- .../persistence.md | 8 +- .../{trust-boundary => agents}/security.md | 2 +- .../{web-ui/agent.md => agents/web-page.md} | 4 +- docs/2-handbook/external-accounts/README.md | 12 ++ .../github.md | 4 +- .../gitlab.md | 0 docs/2-handbook/hives/README.md | 113 +++++++++++++++++ .../{trust-boundary => hives}/boundary.md | 0 .../2-handbook/{web-ui => hives}/dashboard.md | 4 +- .../{tools => hives}/hivectl-cli.md | 0 docs/2-handbook/{tools => hives}/hivectl.md | 6 +- docs/2-handbook/swarm/README.md | 17 ++- .../{integrations => swarm}/forge.md | 6 +- .../{integrations => swarm}/knowledge.md | 0 .../{integrations => swarm}/matrix.md | 2 +- docs/2-handbook/swarm/schedules.md | 2 +- docs/2-handbook/swarm/sso.md | 4 +- .../{tools => swarm}/swarmctl-cli.md | 0 docs/2-handbook/swarm/ui.md | 6 +- docs/2-handbook/tools/README.md | 24 ---- docs/2-handbook/web-ui/README.md | 115 ------------------ docs/4-implementation/agent-tools/README.md | 2 +- docs/4-implementation/agent-tools/matrix.md | 2 +- docs/4-implementation/networking/gateway.md | 2 +- .../networking/snapshot-store.md | 4 +- .../4-implementation/scheduler/coordinator.md | 10 +- docs/4-implementation/scheduler/jobq.md | 2 +- .../scheduler/observability.md | 2 +- docs/4-implementation/swarm/builder.md | 2 +- docs/4-implementation/swarm/inference.md | 2 +- .../trust-boundary/boundary-mechanism.md | 4 +- .../trust-boundary/hive-c0re-privilege.md | 2 +- .../trust-boundary/nix-builds.md | 2 +- docs/4-implementation/turn-loop/README.md | 6 +- .../turn-loop/claude-invocation.md | 2 +- docs/4-implementation/turn-loop/config.md | 2 +- docs/4-implementation/turn-loop/mcp.md | 2 +- docs/4-implementation/web-ui/shape.md | 4 +- docs/5-project/process/conventions.md | 14 +-- docs/5-project/process/gotchas.md | 6 +- docs/README.md | 115 ++++++++++-------- frontend/packages/agent/src/agent.css | 6 +- .../packages/agent/src/components/Header.tsx | 2 +- frontend/packages/agent/src/index.html | 2 +- frontend/packages/agent/src/screen.html | 6 +- frontend/packages/agent/src/types.ts | 2 +- frontend/packages/dashboard/src/agents.js | 20 +-- frontend/packages/dashboard/src/common.css | 2 +- frontend/packages/dashboard/src/dashboard.css | 2 +- frontend/packages/dashboard/src/index.html | 2 +- .../shared/src/side-panel/hive-side-panel.js | 2 +- hive-agent/src/harness_state.rs | 2 +- hive-agent/src/login.rs | 2 +- hive-agent/src/paths.rs | 2 +- hive-agent/src/vacuum.rs | 2 +- hive-agent/src/web_ui/auth.rs | 2 +- hive-agent/src/web_ui/state.rs | 4 +- hive-c0re/README.md | 4 +- hive-c0re/src/forge/mod.rs | 2 +- hive-c0re/src/lifecycle/host_config.rs | 2 +- hive-c0re/src/migrate.rs | 2 +- hive-c0re/src/stores/build_logs.rs | 2 +- hive-c0re/src/workers/crash_watch.rs | 2 +- hive-core-agent-sock/README.md | 2 +- hive-forge-notify/README.md | 2 +- .../src/bin/hive-github-notify/main.rs | 2 +- .../src/bin/hive-github-notify/source.rs | 2 +- hive-forge-notify/src/notify.rs | 24 ++-- hive-host-sock/README.md | 2 +- hive-host-sock/src/lib.rs | 2 +- hive-priv-sock/README.md | 2 +- hive-priv/README.md | 2 +- hivectl/README.md | 2 +- hivectl/src/choom.rs | 2 +- nix/agent-modules/agent-service.nix | 2 +- nix/agent-modules/forge.nix | 2 +- nix/agent-modules/matrix.nix | 4 +- nix/agent-modules/user.nix | 2 +- nix/agent-modules/weston-vnc.nix | 2 +- nix/checks.nix | 16 +-- nix/host-modules/hive-c0re/default.nix | 4 +- nix/host-modules/hive-c0re/options.nix | 2 +- nix/host-modules/hive-forge/service.nix | 2 +- nix/host-modules/hive-matrix.nix | 8 +- nix/host-modules/hive-priv.nix | 2 +- swarm-controller/src/vcs_metrics.rs | 2 +- swarm-secret-client/src/policy.rs | 4 +- swarmctl/README.md | 2 +- 95 files changed, 398 insertions(+), 368 deletions(-) create mode 100644 docs/2-handbook/agents/README.md rename docs/2-handbook/{agent-lifecycle => agents}/agent-roster.md (99%) rename docs/2-handbook/{agent-lifecycle => agents}/config-changes.md (99%) rename docs/2-handbook/{agent-lifecycle => agents}/persistence.md (99%) rename docs/2-handbook/{trust-boundary => agents}/security.md (99%) rename docs/2-handbook/{web-ui/agent.md => agents/web-page.md} (99%) create mode 100644 docs/2-handbook/external-accounts/README.md rename docs/2-handbook/{integrations => external-accounts}/github.md (97%) rename docs/2-handbook/{integrations => external-accounts}/gitlab.md (100%) create mode 100644 docs/2-handbook/hives/README.md rename docs/2-handbook/{trust-boundary => hives}/boundary.md (100%) rename docs/2-handbook/{web-ui => hives}/dashboard.md (99%) rename docs/2-handbook/{tools => hives}/hivectl-cli.md (100%) rename docs/2-handbook/{tools => hives}/hivectl.md (97%) rename docs/2-handbook/{integrations => swarm}/forge.md (98%) rename docs/2-handbook/{integrations => swarm}/knowledge.md (100%) rename docs/2-handbook/{integrations => swarm}/matrix.md (99%) rename docs/2-handbook/{tools => swarm}/swarmctl-cli.md (100%) delete mode 100644 docs/2-handbook/tools/README.md delete mode 100644 docs/2-handbook/web-ui/README.md diff --git a/.prettierignore b/.prettierignore index 3550935a..294890a0 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,8 +4,8 @@ # generator, not the formatter, owns these files' layout. Every CLI # reference doc belongs here — adding one and forgetting this line is # what made swarmctl's fail. -docs/2-handbook/tools/hivectl-cli.md -docs/2-handbook/tools/swarmctl-cli.md +docs/2-handbook/hives/hivectl-cli.md +docs/2-handbook/swarm/swarmctl-cli.md docs/4-implementation/agent-tools/forge-cli.md docs/4-implementation/agent-tools/swarm-logs-cli.md docs/4-implementation/agent-tools/swarm-metrics-cli.md @@ -15,14 +15,14 @@ docs/4-implementation/agent-tools/swarm-metrics-cli.md # indentation normalisation, so these files need manual re-wrap before # adding them back to the formatter scope. AGENTS.md -docs/2-handbook/agent-lifecycle/config-changes.md +docs/2-handbook/agents/config-changes.md docs/5-project/process/conventions.md docs/4-implementation/networking/gateway.md -docs/2-handbook/integrations/matrix.md -docs/2-handbook/agent-lifecycle/persistence.md +docs/2-handbook/swarm/matrix.md +docs/2-handbook/agents/persistence.md docs/4-implementation/web-ui/terminal-rendering.md docs/4-implementation/agent-tools/forge.md docs/4-implementation/agent-tools/matrix.md docs/4-implementation/turn-loop/README.md -docs/2-handbook/web-ui/agent.md -docs/2-handbook/web-ui/dashboard.md +docs/2-handbook/agents/web-page.md +docs/2-handbook/hives/dashboard.md diff --git a/AGENTS.md b/AGENTS.md index a51d7973..994f7c35 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,12 +10,12 @@ when you need depth on a subsystem. This file is the index. the env var — inside an agent container `localhost` is the *agent*, not the forge, so a hardcoded loopback address fails to connect. - Operator/agent trust-boundary design: - **[docs/2-handbook/trust-boundary/boundary.md](docs/2-handbook/trust-boundary/boundary.md)** (`area/ops` issues + **[docs/2-handbook/hives/boundary.md](docs/2-handbook/hives/boundary.md)** (`area/ops` issues for the deployment/gateway/privsep work — the separator is a **slash**, and `--label area:ops` now fails with `did you mean "area/ops"?`). - Agent trust model (trust boundary, prompt-injection threat model, capability = accepted risk), credential isolation + sandbox threat model: - **[docs/2-handbook/trust-boundary/security.md](docs/2-handbook/trust-boundary/security.md)**. + **[docs/2-handbook/agents/security.md](docs/2-handbook/agents/security.md)**. - Odd-looking nspawn / container plumbing usually has a story: **[docs/5-project/process/gotchas.md](docs/5-project/process/gotchas.md)**. @@ -33,8 +33,8 @@ nix fmt # treefmt is the CI gate, NOT bare cargo fmt Changed a `hivectl` / `swarmctl` verb or flag? Regenerate its doc — only CI's `nix flake check` catches the drift: -`nix develop -c cargo run --bin hivectl -- markdown-docs > docs/2-handbook/tools/hivectl-cli.md` -(same for `swarmctl` → `docs/2-handbook/tools/swarmctl-cli.md`). CI red but local +`nix develop -c cargo run --bin hivectl -- markdown-docs > docs/2-handbook/hives/hivectl-cli.md` +(same for `swarmctl` → `docs/2-handbook/swarm/swarmctl-cli.md`). CI red but local green → build the suspect check (e.g. `nix build .#checks.x86_64-linux.hivectl-docs`) before blaming the builder. @@ -58,10 +58,10 @@ Per-hive (host + in-container): crate. - **`hivectl/`** — operator CLI; talks to `hive-c0re` over the host admin socket, does NOT link it. Verb reference (CI-enforced): - [`docs/2-handbook/tools/hivectl-cli.md`](docs/2-handbook/tools/hivectl-cli.md). + [`docs/2-handbook/hives/hivectl-cli.md`](docs/2-handbook/hives/hivectl-cli.md). - **`hive-priv/`** — minimal root helper, socket-activated at `/run/hive/priv.sock`; the few root ops (bind-mount edits, nsenter) - `hive-c0re` delegates. See `docs/2-handbook/trust-boundary/boundary.md`. + `hive-c0re` delegates. See `docs/2-handbook/hives/boundary.md`. - **`hive-agent/`** — the in-container serve loop: turn-loop *policy* (`turn.rs`) over `hive-runtime`, per-agent web UI, event + turn-stats sinks, system-prompt renderer, claude launch config (`mcp_config.rs`). @@ -130,7 +130,7 @@ Swarm-level: **`users.yml` in place**, shared with `swarm-authelia-bridge`; that crate's README says what both writers must uphold. Verb reference (CI-enforced): - [`docs/2-handbook/tools/swarmctl-cli.md`](docs/2-handbook/tools/swarmctl-cli.md). + [`docs/2-handbook/swarm/swarmctl-cli.md`](docs/2-handbook/swarm/swarmctl-cli.md). - **`swarm-authelia-bridge/`** (+ **`swarm-authelia-bridge-sock/`** wire types) — the other writer of authelia's users DB; runs inside `swarm-authelia`. @@ -225,7 +225,7 @@ in this file and drifted. - **Operator-facing doc with real implementation detail mixed in**: wrap the implementation part in a `
…` block (blank line after `` so the markdown inside renders) rather - than a sibling page — see `docs/2-handbook/integrations/github.md`'s + than a sibling page — see `docs/2-handbook/external-accounts/github.md`'s "Implementation" section. It only collapses in a rendered browser, and the `` line isn't markdown-processed, so keep it plain prose with no backticks. diff --git a/README.md b/README.md index 160d71f0..053f5bc4 100644 --- a/README.md +++ b/README.md @@ -92,13 +92,13 @@ box it gets: credentials, and notifications turned into todos. Optional linked accounts on other forges, GitLab (`glab` + push), and GitHub (`gh` + push) via `services.hyperhive.agent.github.enable`. → - [forge](docs/2-handbook/integrations/forge.md) · [gitlab](docs/2-handbook/integrations/gitlab.md) · - [github](docs/2-handbook/integrations/github.md) + [forge](docs/2-handbook/swarm/forge.md) · [gitlab](docs/2-handbook/external-accounts/gitlab.md) · + [github](docs/2-handbook/external-accounts/github.md) - **matrix** — its own account(s) on the swarm homeserver, as MCP tools. → [matrix](docs/4-implementation/agent-tools/matrix.md) - **knowledge** — the swarm's shared `internal/knowledge` repo, read-only at `/knowledge`, plus hyperhive's own docs in the container. → - [knowledge](docs/2-handbook/integrations/knowledge.md) + [knowledge](docs/2-handbook/swarm/knowledge.md) - **web UI** — a per-agent page behind the gateway: live terminal of the turn stream, model / effort switching, cancel. - **GUI** (opt-in, `services.hyperhive.agent.gui.enable`) — a Wayland @@ -175,11 +175,11 @@ once, top to bottom. [`docs/2-handbook/swarm/ui.md`](docs/2-handbook/swarm/ui.md) - **`swarmctl`** — the swarm's CLI, on the swarm-controller host: create agents and mint their identities, manage SSO users, make forge admins. - → [reference](docs/2-handbook/tools/swarmctl-cli.md) + → [reference](docs/2-handbook/swarm/swarmctl-cli.md) - **per-hive** — each hive's dashboard (container state, rebuild queue) and `hivectl` for host-level administration and - container shells. → [`docs/2-handbook/web-ui/`](docs/2-handbook/web-ui/README.md) · - [hivectl](docs/2-handbook/tools/hivectl.md) + container shells. → [`docs/2-handbook/hives/`](docs/2-handbook/hives/README.md) · + [hivectl](docs/2-handbook/hives/hivectl.md) You are an SSO user too: `swarmctl user add --group admins`, and a first login through authelia creates your forge and matrix accounts; @@ -193,8 +193,8 @@ pick the page for your task rather than reading front to back. Some common entry points: - connecting hives into a swarm → [`2-handbook/swarm/`](docs/2-handbook/swarm/README.md) -- how config changes flow → [`2-handbook/agent-lifecycle/config-changes.md`](docs/2-handbook/agent-lifecycle/config-changes.md) -- trust boundary + threat model → [`trust-boundary/`](docs/2-handbook/trust-boundary/boundary.md) +- how config changes flow → [`2-handbook/agents/config-changes.md`](docs/2-handbook/agents/config-changes.md) +- trust boundary + threat model → [`hives/boundary.md`](docs/2-handbook/hives/boundary.md), [`agents/security.md`](docs/2-handbook/agents/security.md) - what an agent's turn looks like → [`4-implementation/turn-loop/`](docs/4-implementation/turn-loop/README.md) - every `services.hyperhive.*` option → [options reference](https://hyperhive.darkest.space/options/) diff --git a/docs/1-getting-started/setup.md b/docs/1-getting-started/setup.md index 9df438de..60f01206 100644 --- a/docs/1-getting-started/setup.md +++ b/docs/1-getting-started/setup.md @@ -114,7 +114,7 @@ container keeps starting with the hive meanwhile. From here on, ask ruth. Open her card on `/agents` in the swarm UI and use the message box under her terminal. She is the manager agent: her MCP surface is the privileged one that configures agents, and she can recover the others. Changes to -an agent's config arrive as PRs you merge. → [`2-handbook/agent-lifecycle/agent-roster.md`](../2-handbook/agent-lifecycle/agent-roster.md) +an agent's config arrive as PRs you merge. → [`2-handbook/agents/agent-roster.md`](../2-handbook/agents/agent-roster.md) To create an agent yourself instead, use the swarm UI, or: @@ -129,7 +129,7 @@ swarm UI's job view for progress. Later config changes are PRs on `agent-configs/iris`; you merge them on the forge, and the merge deploys them. → -[`2-handbook/agent-lifecycle/config-changes.md`](../2-handbook/agent-lifecycle/config-changes.md#config-changes) +[`2-handbook/agents/config-changes.md`](../2-handbook/agents/config-changes.md#config-changes) ## After setup: use the swarm UI diff --git a/docs/2-handbook/agents/README.md b/docs/2-handbook/agents/README.md new file mode 100644 index 00000000..79ff1c5c --- /dev/null +++ b/docs/2-handbook/agents/README.md @@ -0,0 +1,24 @@ +# Agents + +An **agent** is one Claude instance in its own NixOS container, with its own +state directory, forge account and matrix accounts. This section covers +running one: its identity, what survives a restart, how its config changes, what +its own page shows and how far you can trust it. + +- **[Roster](agent-roster.md)** — the agents of a hive, and who may do what + to whom. +- **[Persistence](persistence.md)** — what survives a restart, a destroy and + a purge. +- **[Config changes](config-changes.md)** — how a change to an agent's config + flows from a pull request to its container. +- **[The agent's web page](web-page.md)** — the per-agent terminal view, its + actions and its endpoints. +- **[Security model](security.md)** — the trust model, the prompt-injection + threat model and credential isolation. + +The swarm creates and configures agents: the create form and its archetypes +are in [`swarm/archetypes.md`](../swarm/archetypes.md), logging an agent in to +claude is in [`swarm/claude-login.md`](../swarm/claude-login.md), and you set +an agent's permissions with `swarmctl agent permissions` or on the swarm UI. +What an agent can do inside its container is in +[`4-implementation/agent-tools/`](../../4-implementation/agent-tools/README.md). diff --git a/docs/2-handbook/agent-lifecycle/agent-roster.md b/docs/2-handbook/agents/agent-roster.md similarity index 99% rename from docs/2-handbook/agent-lifecycle/agent-roster.md rename to docs/2-handbook/agents/agent-roster.md index 000a2f10..2da2cd01 100644 --- a/docs/2-handbook/agent-lifecycle/agent-roster.md +++ b/docs/2-handbook/agents/agent-roster.md @@ -130,4 +130,4 @@ comments as the source of truth for exactly which checks exist today. - Milestone: "Agent privileges and sub-agents" (tracked internally) - Audit table source: milestone comment (tracked internally) -- Operator/agent trust boundary (orthogonal axis): [`boundary.md`](../trust-boundary/boundary.md) +- Operator/agent trust boundary (orthogonal axis): [`boundary.md`](../hives/boundary.md) diff --git a/docs/2-handbook/agent-lifecycle/config-changes.md b/docs/2-handbook/agents/config-changes.md similarity index 99% rename from docs/2-handbook/agent-lifecycle/config-changes.md rename to docs/2-handbook/agents/config-changes.md index 0f67f5b0..65103365 100644 --- a/docs/2-handbook/agent-lifecycle/config-changes.md +++ b/docs/2-handbook/agents/config-changes.md @@ -218,7 +218,7 @@ each `git` call inline, never writing it into a repo's config, so no stored token sits in a repo an agent might one day read. The dashboard deep-links into this org — a `config repo` link -per container row. See `docs/2-handbook/web-ui/dashboard.md`. +per container row. See `docs/2-handbook/hives/dashboard.md`. ### Submitting agent's view of config repos diff --git a/docs/2-handbook/agent-lifecycle/persistence.md b/docs/2-handbook/agents/persistence.md similarity index 99% rename from docs/2-handbook/agent-lifecycle/persistence.md rename to docs/2-handbook/agents/persistence.md index a24b5941..042ea107 100644 --- a/docs/2-handbook/agent-lifecycle/persistence.md +++ b/docs/2-handbook/agents/persistence.md @@ -18,7 +18,7 @@ keeps its state, purging it doesn't.** undo.** Only reach for this when you actually want the agent gone for good. The agent's matrix encryption keys go with the state dir, but an account whose key backup is on (see - [matrix](../integrations/matrix.md)) gets them back from its + [matrix](../swarm/matrix.md)) gets them back from its homeserver when it next comes up, so its encrypted history stays readable. @@ -106,7 +106,7 @@ back through when debugging a regression. Age-only within the history sooner than a quiet one. The trade-off (accepted): a misbehaving harness can skip its own cleanup — but a compromised harness is already inside the container trust boundary -([`docs/2-handbook/trust-boundary/security.md`](../trust-boundary/security.md)), and these are ephemeral local +([`docs/2-handbook/agents/security.md`](security.md)), and these are ephemeral local artifacts, so cleaning them up where they live is the honest fix. @@ -270,7 +270,7 @@ Under `/var/lib/hyperhive/agents//`: has a value. - `hyperhive-harness.json` — rate-limited / needs-login flags read by the dashboard's async container-state fetch. See - `docs/2-handbook/web-ui/dashboard.md::Container row`. + `docs/2-handbook/hives/dashboard.md::Container row`. The agent writes its own instructions to `AGENTS.md` here; claude and opencode load it automatically from their cwd, `state/`. At boot, @@ -696,7 +696,7 @@ the store answers that it holds none, never because a read failed. place; a missing file is an empty set. A file the controller can't read or parse stops the sync, grants included, and the controller logs `operator matrix admin: pass failed` on every pass. See - [`docs/2-handbook/integrations/matrix.md`](../integrations/matrix.md#operators-are-homeserver-admins). + [`docs/2-handbook/swarm/matrix.md`](../swarm/matrix.md#operators-are-homeserver-admins). ## Run-time dirs diff --git a/docs/2-handbook/trust-boundary/security.md b/docs/2-handbook/agents/security.md similarity index 99% rename from docs/2-handbook/trust-boundary/security.md rename to docs/2-handbook/agents/security.md index ff31a314..03df04f7 100644 --- a/docs/2-handbook/trust-boundary/security.md +++ b/docs/2-handbook/agents/security.md @@ -131,7 +131,7 @@ checkpoints**, not about sandboxing the agent from its own tools: technical control. - **Operator sign-off** — config changes are config PRs an operator merges on the forge (see - [`config-changes.md`](../agent-lifecycle/config-changes.md)), and + [`config-changes.md`](config-changes.md)), and scheduled prompts are operator-only, set at swarm level (see [`schedules.md`](../swarm/schedules.md)). Before that merge, the swarm builder evaluates an unmerged config PR diff --git a/docs/2-handbook/web-ui/agent.md b/docs/2-handbook/agents/web-page.md similarity index 99% rename from docs/2-handbook/web-ui/agent.md rename to docs/2-handbook/agents/web-page.md index fd88e84e..0fd2805c 100644 --- a/docs/2-handbook/web-ui/agent.md +++ b/docs/2-handbook/agents/web-page.md @@ -1,7 +1,7 @@ # Per-agent page -> Part of [Web UI](README.md). See also: -> [Shape (shared)](../../4-implementation/web-ui/shape.md) · [Dashboard layout](dashboard.md) +> Part of [Agents](README.md). See also: +> [Shape (shared)](../../4-implementation/web-ui/shape.md) · [Dashboard layout](../hives/dashboard.md) Two fixed-position layers frame a full-viewport terminal: a header and diff --git a/docs/2-handbook/external-accounts/README.md b/docs/2-handbook/external-accounts/README.md new file mode 100644 index 00000000..ea8bf240 --- /dev/null +++ b/docs/2-handbook/external-accounts/README.md @@ -0,0 +1,12 @@ +# External accounts + +An agent can hold an account on a service outside the swarm, so it can push +code or read notifications there as itself. These pages cover linking such an +account to an agent and what the agent then does with it. They sit outside the +swarm, the hives and the agents themselves; the swarm's own forge and +homeserver are in [`swarm/`](../swarm/README.md). + +- **[GitHub](github.md)** — give an agent a GitHub account: `gh`, + `git push` and the notification poller, and how the token reaches it. +- **[GitLab](gitlab.md)** — the same for one or more GitLab instances + (`glab` and `git push`). diff --git a/docs/2-handbook/integrations/github.md b/docs/2-handbook/external-accounts/github.md similarity index 97% rename from docs/2-handbook/integrations/github.md rename to docs/2-handbook/external-accounts/github.md index 9d2e96d1..46e4b606 100644 --- a/docs/2-handbook/integrations/github.md +++ b/docs/2-handbook/external-accounts/github.md @@ -59,7 +59,7 @@ reads it: [credentials-reference.md](../swarm/credentials-reference.md). workflow needs. Agents have passwordless sudo, so a compromised or hallucinating agent can act as the account within the token's scopes; scope is the real blast-radius limiter, and the container boundary is - the enforcement. See [security.md](../trust-boundary/security.md). + the enforcement. See [security.md](../agents/security.md). ## Implementation @@ -94,7 +94,7 @@ minimal environment that wouldn't carry one. `hive-github-notify` polls github.com for the agent, turning each unread notification thread into a todo. it's a **separate binary and a separate systemd unit** from the internal forge's poller -(`hive-forge-notify`, see [forge.md](forge.md#notification-poller-hive-forge-notifysrcnotifyrs)), +(`hive-forge-notify`, see [forge.md](../swarm/forge.md#notification-poller-hive-forge-notifysrcnotifyrs)), installed by `nix/agent-modules/github.nix` under `services.hyperhive.agent.github.enable`. Both binaries ship from the one `hive-forge-notify` derivation, so the unit is a second `ExecStart` diff --git a/docs/2-handbook/integrations/gitlab.md b/docs/2-handbook/external-accounts/gitlab.md similarity index 100% rename from docs/2-handbook/integrations/gitlab.md rename to docs/2-handbook/external-accounts/gitlab.md diff --git a/docs/2-handbook/hives/README.md b/docs/2-handbook/hives/README.md new file mode 100644 index 00000000..e1ca2d04 --- /dev/null +++ b/docs/2-handbook/hives/README.md @@ -0,0 +1,113 @@ +# Hives + +A **hive** is one host running `hive-c0re` and its agent containers. This +section is for the operator of that host: the per-hive dashboard, the +`hivectl` CLI and the operator/agent trust boundary on the host. For what +the whole swarm shares, see [the swarm UI](../swarm/ui.md) instead. + +- **[Dashboard](dashboard.md)** — every tab and standalone page of the + per-hive dashboard, in full detail: endpoint shapes, event wiring, badge + rules. +- **[hivectl](hivectl.md)** — the curated guide to the host CLI: + provisioning forge and matrix accounts, container lifecycle shortcuts, + interactive agent shell access. +- **[hivectl-cli](hivectl-cli.md)** — the flag-by-flag reference, + generated from the binary and kept in lockstep by CI. +- **[The operator/agent boundary](boundary.md)** — what the operator may do + that an agent may not, and why the line sits where it does. + +For `swarmctl`, the swarm operator's CLI, see +[`swarmctl-cli.md`](../swarm/swarmctl-cli.md). The tool surface agents get +inside their containers is in +[`4-implementation/agent-tools/`](../../4-implementation/agent-tools/README.md). + +## Where things are + +Everything starts at the **dashboard**, served at `/`. A pages menu (the +link icon beside the profile avatar, at the right of the tab strip) links to +the other surfaces: the API docs and the swarm UI. + +The dashboard is a single page with these tabs: + +- **4G3NTS** — every agent, live. This is the default tab and the one you + check most. +- **R3BU1LD QU3U3** — the rebuild queue. A build's output and history are on + the swarm's `builds` Grafana board. +- **K3PT ST4T3** — kept state from agents with no container (tombstones), + with a purge button per entry. + +Each agent also has its own page, a full terminal view of that agent's +session. Select its name anywhere in the dashboard, or open `/agent//` +(or `http://:/` if the gateway isn't in front). [The agent's web page](../agents/web-page.md) +covers it. + +## The things you do here + +**Check on an agent.** 4G3NTS shows every container as a row: name, whether +it's running, what it's doing (a live status pill such as `rebuilding…` or +`starting…` while something's in flight), and quick links (stats, screen, +forge profile). Select the name to open its terminal and watch it work. + +**Review a config change.** Agent config changes (new packages, env vars, MCP +servers) are pull requests on the agent's `agent-configs` repo. Review and +merge them on the forge; the merge deploys the change. See +[`config-changes.md`](../agents/config-changes.md#config-changes). + +**Start, stop, restart or rebuild an agent.** Select one or more agents on +4G3NTS (select the icon) and use the selection bar, or use the per-agent `⋮` +menu on a single row. Rebuilding downloads and applies the closure the swarm +declares for the agent again. The hive applies a changed declaration itself, +so use it to retry one that failed. + +**Watch a build.** The R3BU1LD QU3U3 tab shows the rebuild queue live, plus a +streaming log of whatever's building. Useful right after merging a config +change or bumping a flake input. + +**Grant or revoke a permission.** Not on the hive dashboard: an agent's +permissions live in the swarm. Set them with `swarmctl agent permissions`, or +on the swarm UI's create-agent screen when creating the agent; see +[`5-project/process/conventions.md`](../../5-project/process/conventions.md#permissions). + +**Read an agent's logs.** Logs aren't in the hive dashboard. Every hive ships +its agents', daemons' and infra containers' journals to the swarm's +VictoriaLogs; read them in Grafana's **Explore**, as +[`swarm/services.md`](../swarm/services.md#logs-victorialogs) says. + +**Set up a schedule.** Scheduled prompts are swarm-level: set them with +`swarmctl schedule` ([`swarm/schedules.md`](../swarm/schedules.md)) or in the +schedules card on the swarm UI's messages tab ([`swarm/ui.md`](../swarm/ui.md)). + +## More depth + +The dashboard and the per-agent pages are single-page apps that share one +skeleton: `GET /` returns a static shell, `/api/state` returns JSON, and +JavaScript renders, with no full-page reloads. + +- **[Shape (shared by both)](../../4-implementation/web-ui/shape.md)** — the + SPA skeleton, SSE multiplexing, terminal pane, listener bind, per-agent + relative paths, the `data-async` form pattern and atomic repaint. +- **[CSS theme variables](../../4-implementation/web-ui/css-vars.md)** — the + Catppuccin Mocha custom properties declared once in `base.css`, and the + rule that per-page stylesheets reference them and never redeclare them. +- **[swarm-ui design guide](../../5-project/web-ui/design-guide.md)** — the + visual language, motion, theming, error UX and component-first principles + for the swarm-level Preact app. `/components` on a running swarm UI is the + living demo of every building block it names. + +For the code, these jump straight to the relevant section: + +- **"How does the dashboard SPA stay live without polling?"** → + [`shape.md`](../../4-implementation/web-ui/shape.md) (SSE multiplexing, + Worker-death self-heal, atomic repaint). +- **"What does a container row contain?"** → [`dashboard.md`](dashboard.md) + (Container row, Selection bar). +- **"What endpoints does the dashboard expose?"** → + [`dashboard.md`](dashboard.md) (Dashboard endpoints, Dashboard event + channel). +- **"How does the per-agent terminal render tool calls?"** → + [`terminal-rendering.md`](../../4-implementation/web-ui/terminal-rendering.md) + (the full row taxonomy and dispatch walkthrough); for a summary see + [`web-page.md`](../agents/web-page.md) (Per-stream rendering). +- **"Which CSS variable to use, and where are the colours defined?"** → + [`css-vars.md`](../../4-implementation/web-ui/css-vars.md) (Palette, the + single-source `base.css` rule). diff --git a/docs/2-handbook/trust-boundary/boundary.md b/docs/2-handbook/hives/boundary.md similarity index 100% rename from docs/2-handbook/trust-boundary/boundary.md rename to docs/2-handbook/hives/boundary.md diff --git a/docs/2-handbook/web-ui/dashboard.md b/docs/2-handbook/hives/dashboard.md similarity index 99% rename from docs/2-handbook/web-ui/dashboard.md rename to docs/2-handbook/hives/dashboard.md index adf1e53f..ef6a5143 100644 --- a/docs/2-handbook/web-ui/dashboard.md +++ b/docs/2-handbook/hives/dashboard.md @@ -1,7 +1,7 @@ # Dashboard layout -> Part of [Web UI](README.md). See also: -> [Shape (shared)](../../4-implementation/web-ui/shape.md) · [Per-agent page](agent.md) +> Part of [Hives](README.md). See also: +> [Shape (shared)](../../4-implementation/web-ui/shape.md) · [Per-agent page](../agents/web-page.md) This page covers the per-hive UI that hive-c0re serves. Swarm-wide surfaces — the agent roster, agent creation, linking external forge and diff --git a/docs/2-handbook/tools/hivectl-cli.md b/docs/2-handbook/hives/hivectl-cli.md similarity index 100% rename from docs/2-handbook/tools/hivectl-cli.md rename to docs/2-handbook/hives/hivectl-cli.md diff --git a/docs/2-handbook/tools/hivectl.md b/docs/2-handbook/hives/hivectl.md similarity index 97% rename from docs/2-handbook/tools/hivectl.md rename to docs/2-handbook/hives/hivectl.md index f668555e..a316f961 100644 --- a/docs/2-handbook/tools/hivectl.md +++ b/docs/2-handbook/hives/hivectl.md @@ -6,7 +6,7 @@ admin socket `/run/hyperhive/host.sock`, which is root-only by default — so it needs `sudo` unless you grant sudoless access by listing your login user in `services.hyperhive.deploy.hive-controller.adminUsers` (adds you to the `hive-admin` group that owns the socket; see -[`docs/2-handbook/trust-boundary/boundary.md`](../trust-boundary/boundary.md#host-admin-socket-access-hivectl)). +[`docs/2-handbook/hives/boundary.md`](boundary.md#host-admin-socket-access-hivectl)). Available via the `hive-c0re` package in the host NixOS config. Unlike the `hive-c0re` daemon subcommands (which go through the broker), @@ -19,7 +19,7 @@ reference autogenerated from the binary's own command tree, see markdown-docs` subcommand and kept in lockstep with the code by the `hivectl-docs` flake check (CI fails if the committed copy drifts). Regenerate with `nix build .#default && ./result/bin/hivectl -markdown-docs > docs/2-handbook/tools/hivectl-cli.md`. +markdown-docs > docs/2-handbook/hives/hivectl-cli.md`. ## Agents @@ -78,7 +78,7 @@ Drop into an interactive Claude session inside an agent container. Replaces the current process with `machinectl shell @h-` running claude from the agent's state dir. Requires root, or membership in `hive-admin` (the same sudoless-`hivectl` group as the [host admin -socket](../trust-boundary/boundary.md) — hive-c0re ships a polkit rule +socket](boundary.md) — hive-c0re ships a polkit rule granting that group the one action `machinectl shell` needs); `choom` checks this itself and refuses up front with a message naming the requirement rather than letting systemd reject the exec later with an diff --git a/docs/2-handbook/swarm/README.md b/docs/2-handbook/swarm/README.md index 6ad7f80d..7df93a91 100644 --- a/docs/2-handbook/swarm/README.md +++ b/docs/2-handbook/swarm/README.md @@ -39,6 +39,13 @@ grafana, the controller, authelia, …) → `admins` only. → [`ui.md`](ui.md) - **shared services** — one forge, homeserver, SSO, queue and metrics/logs stack, each on whichever host you put it. → [`services.md`](services.md) +- **forge** — the swarm's Forgejo: per-agent accounts, notifications and the + CLI agents use. → [`forge.md`](forge.md) +- **matrix** — the swarm's homeserver, several accounts per agent, and + federation. → [`matrix.md`](matrix.md) +- **knowledge repo** — the reference docs every agent reads, and how to add + one. → [`knowledge.md`](knowledge.md) +- **`swarmctl`** — the swarm operator's CLI. → [`swarmctl-cli.md`](swarmctl-cli.md) - **SSO** — the secrets authelia generates and how each reaches its reader. → [`sso.md`](sso.md) - **secrets** — the rules a credential follows → [`credentials.md`](credentials.md); @@ -453,13 +460,13 @@ them, and the notification router, not the controller, decides what they mean. A `config-pr` delivery reporting a PR merged into `main` queues a deploy of its `merge_commit_sha` on the one hive whose wanted state places the agent; with no such hive, or more than one, the controller deploys nothing. See -[config-changes.md § Config changes](../agent-lifecycle/config-changes.md#config-changes). +[config-changes.md § Config changes](../agents/config-changes.md#config-changes). A merge whose `closed` delivery never arrives deploys nothing either; the operator recovers by redelivering that delivery from the forge hook page, which re-enters the same handler and re-queues the deploy. **`internal/knowledge` is on that path.** The controller's is the only -hook on it ([`knowledge.md`](../integrations/knowledge.md) covers clearing a +hook on it ([`knowledge.md`](knowledge.md) covers clearing a leftover). A webhook has exactly one target URL, so a second registration would take delivery away from the first rather than add a recipient. @@ -479,7 +486,7 @@ host also serves the swarm UI vhost — that's what publishes the endpoint, and a hook the forge can't reach would collect failed deliveries while looking healthy. The controller generates the HMAC secret on first start and keeps it -(see [`docs/2-handbook/agent-lifecycle/persistence.md`](../agent-lifecycle/persistence.md)). +(see [`docs/2-handbook/agents/persistence.md`](../agents/persistence.md)). To check it's working, push to `internal/knowledge` and look for `webhook: verified delivery` in `journalctl -u swarm-controller`. A @@ -588,7 +595,7 @@ mechanism. added to the public CAs; it holds the store's `pki` root, so a peer whose certificate chains to the same root validates. A peer outside this swarm's root needs a CA-issued certificate (ACME). Federation firewall - and TLS requirements: [`2-handbook/integrations/matrix.md`](../integrations/matrix.md). + and TLS requirements: [`2-handbook/swarm/matrix.md`](matrix.md). 3. **WireGuard mesh** (optional) — `deploy.wireguard.enable` reads each entry's `wireguardPublicKey`/`wireguardEndpoint`/`wireguardAddress` @@ -683,7 +690,7 @@ If both hosts are behind NAT, you need a STUN relay or a third host swarm's `btrfs receive` endpoint and the `swarm.snapshotStore` option - [`5-project/process/conventions.md`](../../5-project/process/conventions.md) § Hive identity — env vars, qualified labels -- [`2-handbook/integrations/matrix.md`](../integrations/matrix.md) — matrix +- [`2-handbook/swarm/matrix.md`](matrix.md) — matrix federation, TLS cert autogeneration, firewall posture - [`4-implementation/networking/gateway.md`](../../4-implementation/networking/gateway.md) — nginx vhosts and the `.well-known/matrix/` autodiscovery scheme diff --git a/docs/2-handbook/integrations/forge.md b/docs/2-handbook/swarm/forge.md similarity index 98% rename from docs/2-handbook/integrations/forge.md rename to docs/2-handbook/swarm/forge.md index b0680aac..8209c99b 100644 --- a/docs/2-handbook/integrations/forge.md +++ b/docs/2-handbook/swarm/forge.md @@ -105,13 +105,13 @@ Two things live in the `agent-configs` Forgejo organization: allowlists are the `operators` team, and the agent can neither push `main` directly nor self-merge. An operator's merge in the Forgejo UI deploys the merged commit (see - [config-changes.md § Config changes](../agent-lifecycle/config-changes.md#config-changes)). + [config-changes.md § Config changes](../agents/config-changes.md#config-changes)). hive-c0re pushes nothing to this org and reads nothing from it. Repos stay private, so an agent can't read another agent's config. The agent's **persistent meta flake input** is this repo's `main` head, pinned by sha in `internal/meta` (`agent-.url = git+/agent-configs/.git?rev=`; see - [config-changes.md § Meta flake](../agent-lifecycle/config-changes.md#meta-flake)). + [config-changes.md § Meta flake](../agents/config-changes.md#meta-flake)). The `hive-forge` CLI (separate workspace crate, see [`README.md`](../../README.md) file map) wraps the Forgejo REST API @@ -140,7 +140,7 @@ state-dir `forge-token` changes, so a token minted later still starts the polling. The crate builds a second, independent binary for a different host — see -[github.md](github.md#notifications). +[github.md](../external-accounts/github.md#notifications). The host-specific calls — list unread, mark read, resolve own login — live behind `Source` in `hive-forge-notify/src/source.rs`; diff --git a/docs/2-handbook/integrations/knowledge.md b/docs/2-handbook/swarm/knowledge.md similarity index 100% rename from docs/2-handbook/integrations/knowledge.md rename to docs/2-handbook/swarm/knowledge.md diff --git a/docs/2-handbook/integrations/matrix.md b/docs/2-handbook/swarm/matrix.md similarity index 99% rename from docs/2-handbook/integrations/matrix.md rename to docs/2-handbook/swarm/matrix.md index bf4491c5..711e6ff9 100644 --- a/docs/2-handbook/integrations/matrix.md +++ b/docs/2-handbook/swarm/matrix.md @@ -351,7 +351,7 @@ federation at the protocol level from first boot (`allow_federation = true`) but trusts no remote homeserver until you list it here. For a closed single-hive deployment the default empty list is correct — add peer hive domains here when connecting hives into a swarm (see -[`docs/2-handbook/swarm/`](../swarm/README.md)). +[`docs/2-handbook/swarm/`](README.md)). **`maxRequestSize`** (default `20_000_000` bytes = 20 MB) — maximum size of a single matrix client request body. Matches the matrix-spec diff --git a/docs/2-handbook/swarm/schedules.md b/docs/2-handbook/swarm/schedules.md index a9dc7a0e..7961b13c 100644 --- a/docs/2-handbook/swarm/schedules.md +++ b/docs/2-handbook/swarm/schedules.md @@ -41,7 +41,7 @@ kqzpmwab "standup" every 1d from 2026-10-05T07:00:00Z next 2026-10-05T07:00: - `schedule list` shows one row per prompt: id, name, cadence, start, next fire time, agents, and the first line of the body. -The full flag reference is [`swarmctl-cli.md`](../tools/swarmctl-cli.md). +The full flag reference is [`swarmctl-cli.md`](swarmctl-cli.md). ## When a prompt fires diff --git a/docs/2-handbook/swarm/sso.md b/docs/2-handbook/swarm/sso.md index 795f45e3..d00e7d32 100644 --- a/docs/2-handbook/swarm/sso.md +++ b/docs/2-handbook/swarm/sso.md @@ -50,7 +50,7 @@ this password is stored nowhere — record it now the hash. It reads and writes authelia's `users.yml` directly — it's the one user store, shared with `swarm-authelia-bridge`, which creates agent identities in the same file. No restart: authelia watches it. Full -reference: [`2-handbook/tools/swarmctl-cli.md`](../tools/swarmctl-cli.md). +reference: [`2-handbook/swarm/swarmctl-cli.md`](swarmctl-cli.md). You can edit `users.yml` by hand, and `swarmctl` will read what you wrote. ⚠️ It rewrites the whole file on every change, so **comments and @@ -208,7 +208,7 @@ Four consequences worth stating plainly: - **A member of `admins` becomes a matrix homeserver admin** once their first matrix login has created the account: `swarm-controller` promotes them within five minutes, and never demotes. See - [`2-handbook/integrations/matrix.md`](../integrations/matrix.md#operators-are-homeserver-admins). + [`2-handbook/swarm/matrix.md`](matrix.md#operators-are-homeserver-admins). - **tuwunel re-reads its secret file on every OAuth exchange**, not only at startup, and its own sandboxing hides most paths from it. It gets the diff --git a/docs/2-handbook/tools/swarmctl-cli.md b/docs/2-handbook/swarm/swarmctl-cli.md similarity index 100% rename from docs/2-handbook/tools/swarmctl-cli.md rename to docs/2-handbook/swarm/swarmctl-cli.md diff --git a/docs/2-handbook/swarm/ui.md b/docs/2-handbook/swarm/ui.md index 24f2711d..8e5ff913 100644 --- a/docs/2-handbook/swarm/ui.md +++ b/docs/2-handbook/swarm/ui.md @@ -734,7 +734,7 @@ A saved change isn't instant. The hive reads the caps about every 30 seconds, and a running agent takes a changed cap at its next spawn or rebuild, so the row shows the new value before the agent runs under it. The card reads `GET /api/agents/{agent}/limits`; when that read fails, the card shows the -reason and a **retry** button. [hivectl](../tools/hivectl.md#per-agent-resource-limits) +reason and a **retry** button. [hivectl](../hives/hivectl.md#per-agent-resource-limits) sets the hive's own limits. ### Permissions @@ -929,7 +929,7 @@ a link dialog closes. - **link a gitlab account** — `PUT /api/hives/{hive}/agents/{agent}/gitlab-accounts/{label}` with a GitLab base URL and an access token, stored at `swarm/agents//gitlab/