docs: restructure into topic subdirectories, collapse duplicated index
Per mara's go-ahead on hyperhive#3902 ("getting started is good, but
terminal rendering does not go in there i think"):
Moved 21 top-level docs/*.md files into 7 new topic subdirectories
(existing web-ui/, turn-loop/, swarm/, tools/, crates/ untouched):
getting-started/ setup.md
agent-lifecycle/ agent-hierarchy.md, approvals.md, persistence.md
trust-boundary/ boundary.md, security.md
integrations/ forge.md, matrix.md, github.md, knowledge.md
networking/ gateway.md, network.md, snapshot-store.md
scheduler/ jobq.md, coordinator.md, ci.md, observability.md
process/ conventions.md, gotchas.md, pr-review-gate.md
web-ui/ terminal-rendering.md (moved into the EXISTING dir,
per mara's correction to the original getting-started
guess -- it's UI implementation detail, not onboarding)
The physical layout now matches docs/README.md's own topical headers,
which already amounted to this taxonomy -- see the scoping comment on
the issue for the two findings that motivated this (a genuine
duplication between CLAUDE.md's old "Reading paths" list and
docs/README.md's grouped one, since drifted out of sync with each
other; and the flat layout not matching the grouping we already had).
Fixed every cross-reference this moved across the whole repo (~120
files: docs/ internal links at every depth, Rust doc comments, nix
module option docs, crate READMEs) -- verified two ways: a grep sweep
confirming zero remaining references to any old path, and a script
that resolves every markdown link in docs/**/*.md + CLAUDE.md +
README.md against the filesystem and reports anything that doesn't
exist (zero broken links).
Collapsed CLAUDE.md's "Reading paths" section (the duplicate) down to
a pointer at docs/README.md, now the single index. Rewrote
docs/README.md itself to use the new subdirectory paths and added the
one doc it was missing that CLAUDE.md's old copy had (pr-review-gate.md).
Classified all 22 docs/*.md files first via a haiku subagent (mara's
suggestion) on two axes -- proposed grouping and operator-vs-
implementation focus -- before finalizing the taxonomy; spot-checked
the report and found internal inconsistencies (its classification
table disagreed with its own summary section for a few files), so this
taxonomy is my original proposal + the one correction mara gave
directly, not a blind application of the subagent's table. The
operator-focus data it gathered is still useful for a follow-up
content pass (docs skewing 'mixed' rather than pure operator-facing),
not addressed in this PR -- structure only.
nix fmt clean, both pre-push lints clean.
This commit is contained in:
parent
e4a22b4190
commit
07b62612b0
124 changed files with 301 additions and 377 deletions
203
docs/getting-started/setup.md
Normal file
203
docs/getting-started/setup.md
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
# First-run setup (fresh-deploy bootstrap)
|
||||
|
||||
How to bring a fresh hyperhive hive online: provision accounts, open
|
||||
the gateway, bootstrap swarm SSO, make matrix reachable, and spawn the
|
||||
first sub-agents.
|
||||
|
||||
Aimed at `ruth` (the root/manager agent) on a fresh deploy, but it's a
|
||||
plain reference doc — read it whenever you need the bootstrap command
|
||||
sequence. All `hivectl` commands below run as **root on the host** (not
|
||||
inside an agent container); the `request_*` steps run from ruth's own
|
||||
turn via the MCP tools.
|
||||
|
||||
**Bringing up a hive that does not host its own swarm services?** Read
|
||||
[`swarm/secrets.md`](../swarm/secrets.md) first. Everything below assumes
|
||||
each credential is generated where it is read, which is true on an
|
||||
all-local deploy and not otherwise — that page says which files an
|
||||
operator has to place, and where.
|
||||
|
||||
## Step-by-step
|
||||
|
||||
### 1 · Forge
|
||||
|
||||
```bash
|
||||
# Provision (or refresh) ruth's own forge account — do this first. Ruth's
|
||||
# bootstrap bypasses the normal spawn-approval flow (see step 6), so unlike
|
||||
# every other agent it does not get its forge account auto-provisioned —
|
||||
# this manual step is still load-bearing.
|
||||
hivectl forge create-user ruth
|
||||
|
||||
# Sub-agents spawned later (via the approval flow in step 6) get their
|
||||
# forge accounts auto-provisioned — nothing to run here for them.
|
||||
```
|
||||
|
||||
The human operator's own forge account is created via swarm SSO instead of
|
||||
a manual `hivectl` step — see step 3 (`swarmctl user add`).
|
||||
|
||||
### 2 · Gateway (HTTP Basic auth)
|
||||
|
||||
```bash
|
||||
# Add an operator login to the gateway (reads password from stdin)
|
||||
echo "hunter2" | hivectl gateway create-user mara --password-stdin
|
||||
|
||||
# List existing users
|
||||
hivectl gateway list-users
|
||||
```
|
||||
|
||||
### 3 · Secret store (only when `deploy.bao`)
|
||||
|
||||
⚠️ **A sealed store still answers.** OpenBao starts uninitialised and
|
||||
sealed, so the container is up and the port responds while every read
|
||||
times out — the failure looks like a hang, not like a store that was
|
||||
never initialised. Do this before anything is pointed at it.
|
||||
|
||||
```bash
|
||||
# On the host that RUNS the store, once.
|
||||
bao operator init # keep the keys it prints and the root token OFF this host
|
||||
```
|
||||
|
||||
Whether anything more is needed depends on
|
||||
`services.hyperhive.deploy.bao.seal`:
|
||||
|
||||
- **`pkcs11`** (the default) — the key is bound to the host's TPM and the
|
||||
store unseals itself on every restart. `init` is the only manual step.
|
||||
- **`shamir`** — no TPM, so `bao operator unseal` is needed again after
|
||||
every restart, with the keys `init` printed.
|
||||
|
||||
The store serves TLS, and on a hive that deploys it you need do nothing: a
|
||||
first-boot unit mints a CA of the store's own plus the two leaves it signs —
|
||||
the store's server certificate and this host's client certificate — and points
|
||||
`deploy.bao.serverCertFile`, `.serverKeyFile` and `.clientCaFile` at the store's
|
||||
half, `.clientCertFile`, `.clientKeyFile` and `.serverCaFile` at the reader's.
|
||||
|
||||
Those are `mkDefault`s, so naming your own paths wins. Do that when your
|
||||
certificates come from a real internal CA; the store has no opinion about
|
||||
which. A hive that does **not** deploy the store names the reader's three
|
||||
itself: that leaf is issued out of band, and it is the one credential the store
|
||||
cannot hand you, being what opens it. ⚠️ Not the gateway's HTTPS certificates and not the hive CA — this is
|
||||
**mTLS between services and the store**, a separate trust domain, because a
|
||||
store that took its identity from an authority it will itself distribute could
|
||||
never come up before that authority.
|
||||
|
||||
Making even the `init` unnecessary is tracked in issue #3768.
|
||||
|
||||
### 4 · Swarm SSO (only when `deploy.authelia`)
|
||||
|
||||
⚠️ **Required to finish the install, not optional.** Authelia treats an
|
||||
empty user store as a fatal startup error, so until this runs the
|
||||
container crash-loops and `auth.<swarm.domain>` answers `502 Bad
|
||||
Gateway` — a working vhost in front of an upstream that refuses to
|
||||
start. Skipping this step looks like a broken proxy.
|
||||
|
||||
```bash
|
||||
# Runs as root on the host that RUNS authelia (not necessarily the
|
||||
# controller host). Prints a generated password once — record it.
|
||||
swarmctl user add mara --display-name Mara --email mara@example.com --group admins
|
||||
```
|
||||
|
||||
⚠️ **Keep `--group admins`.** It is not decoration: operator-only
|
||||
surfaces (the swarm UI below) are gated on that group, and an account
|
||||
without it authenticates successfully and is then refused — which reads
|
||||
like a broken login rather than a missing group.
|
||||
|
||||
If an account already exists without it, `user add` will refuse rather
|
||||
than amend — adding the group afterwards is `swarmctl user update mara
|
||||
--add-group admins`.
|
||||
|
||||
Detail, including what the password is and why this stays manual:
|
||||
[`swarm/sso.md`](../swarm/sso.md).
|
||||
|
||||
### 5 · Swarm UI (only when `deploy.swarm-ui`, on by default with the controller)
|
||||
|
||||
Nothing to run — it is served on the swarm apex
|
||||
(`https://<swarm.domain>/`) as soon as the host rebuilds. Two things
|
||||
decide whether you can actually open it:
|
||||
|
||||
- **You are in `admins`** (step 3). The gateway asks authelia whether
|
||||
you have a session; the rule that makes it mean *operator* wants the
|
||||
group. Without it you log in and still get bounced.
|
||||
- **The name resolves to this host.** It is published to the hive's own
|
||||
resolver and to `/etc/hosts` when `gateway.localHostsEntry` is on; from
|
||||
anywhere else it needs a real DNS record like any other public name.
|
||||
|
||||
Detail, including why reachability is deliberately not the access
|
||||
control: [`swarm/ui.md`](../swarm/ui.md).
|
||||
|
||||
### 6 · Matrix
|
||||
|
||||
```bash
|
||||
# 5a. Ensure the hive-internal admin account exists first
|
||||
hivectl matrix sync-admin
|
||||
|
||||
# 5b. Provision ruth's own matrix account — same bootstrap-bypass reasoning
|
||||
# as forge above, still a required manual step.
|
||||
hivectl matrix create-user ruth
|
||||
|
||||
# 5c. Invite the operator to the hive Space (and optionally to rooms)
|
||||
hivectl matrix invite mara
|
||||
hivectl matrix invite @mara:yourserver --room '#hive-chat:yourserver'
|
||||
|
||||
# 5d. Promote the operator to homeserver admin if needed
|
||||
hivectl matrix promote-user mara
|
||||
```
|
||||
|
||||
The human operator's own matrix account is created via swarm SSO instead of
|
||||
a manual `hivectl` step — see step 3 (`swarmctl user add`).
|
||||
|
||||
### 7 · Spawn sub-agents
|
||||
|
||||
Sub-agent creation goes through the approval queue — ruth proposes, the
|
||||
operator approves, the container builds. From ruth's own turn (inside
|
||||
the container, via MCP tools):
|
||||
|
||||
```
|
||||
# Step 1: initialise a new agent's config repo
|
||||
request_init_config(name: "iris")
|
||||
# → operator approves → config_ready event lands in the inbox
|
||||
|
||||
# Step 2: edit /agents/iris/config/agent.nix and commit it. Then the
|
||||
# operator spawns iris (dashboard ◆ R3QU3ST SP4WN / Spawn approval),
|
||||
# which builds + starts the container from that config.
|
||||
|
||||
# Later config changes: open a PR on agent-configs/iris (hive-forge);
|
||||
# the operator reviews + approves it — no MCP tool call.
|
||||
```
|
||||
|
||||
See [`approvals.md`](../agent-lifecycle/approvals.md) for the full flow.
|
||||
|
||||
### 8 · Useful host commands
|
||||
|
||||
```bash
|
||||
# Roster: all agents, status, rev, parent, pending reminders
|
||||
hivectl list-agents
|
||||
|
||||
# Restart a stuck container (no rebuild)
|
||||
hivectl agent <agent> restart
|
||||
|
||||
# Open a Claude session inside an agent's container
|
||||
hivectl agent <agent> choom
|
||||
|
||||
# Open hive web surfaces in a browser (or just print the URLs)
|
||||
hivectl open # operator dashboard
|
||||
hivectl open forge # Forgejo
|
||||
hivectl open matrix # Matrix GUI (fluffychat)
|
||||
```
|
||||
|
||||
See [`tools/hivectl.md`](../tools/hivectl.md) for every `hivectl` verb.
|
||||
|
||||
## Security notes
|
||||
|
||||
- **No forge admin token is stored in any agent state dir.** Agents
|
||||
hold a regular agent token in their `forge-token` file; sensitive
|
||||
creds (the core token, the matrix admin token) live on the host.
|
||||
- All config changes (forge PRs on `agent-configs/<name>`) go through
|
||||
operator approval — agents can't unilaterally rebuild containers, by design.
|
||||
See [`boundary.md`](../trust-boundary/boundary.md) and [`security.md`](../trust-boundary/security.md).
|
||||
- **Telemetry ingest is authenticated per hive**, and the `hive` label comes
|
||||
from which hive authenticated rather than from the payload — so no hive can
|
||||
report metrics as another. A first-run all-local hive gets this with nothing
|
||||
to configure; joining a swarm you don't host needs one secret copied across.
|
||||
See [`observability.md`](../scheduler/observability.md#authenticated-ingest).
|
||||
|
||||
Once the hive is running, ruth records anything it needs to remember
|
||||
across restarts in `/agents/ruth/state/notes.md`.
|
||||
Loading…
Reference in a new issue