hyperhive/CLAUDE.md
atlas c051cd9717 docs(#2862): document the snapshot store, drop the dedicated option
mara: the option was the wrong shape for the concern. "this host runs
nothing else" is a deployment expectation, not something a module
should assert about its own host — and asserting it made co-location
look like a config toggle rather than what it is.

Replaced with docs/snapshot-store.md, which the module had no docs
page at all before: enabling it, why the mesh is the authentication
(cryptokey routing already binds source address to pubkey, so certs
would authenticate the same fact twice and add an expiry), why the
destination is keyed per agent (a per-hive prefix splits an agent's
chain the first time it migrates), what the sender may and may not
choose, why the firewall rule is interface-scoped, what a snapshot
does and does not contain, and what the pull side still needs.

The dedicated-host expectation is stated there as an operational
assumption with its own failure mode — true on day one, quietly false
the day someone notices the box has spare disk — rather than as an
assertion someone flips to false to make the build proceed.

Linked from CLAUDE.md's reading paths.
2026-07-31 19:03:24 +02:00

200 lines
11 KiB
Markdown

# hyperhive — claude entry point
Hey claude. This is your starting page. The detailed docs live in
[`docs/`](docs/) and are written for humans + you both — read them
when you need depth on a subsystem. This file is the index.
- High-level project intro: **[README.md](README.md)**.
- Open work + backlog: the **[forge issue
tracker](http://localhost:3000/hyperhive/hyperhive/issues)**.
- Operator/agent trust-boundary design:
**[docs/boundary.md](docs/boundary.md)** (`area:ops` issues
for the deployment/gateway/privsep work).
- Agent trust model (trust boundary, prompt-injection threat model,
capability = accepted risk), credential isolation + sandbox threat model:
**[docs/security.md](docs/security.md)**.
## Repo map
One line per crate / top-level dir. **Each module's authoritative,
always-current description lives in its own `//!` doc-comment** —
`grep`/read the module when you need detail. This index is kept
deliberately lean: it auto-loads into every turn's context, and a
hand-maintained per-file tree drifts out of sync with the code.
### Rust workspace (`Cargo.toml` members)
- **`hive-c0re/`** — host daemon (runs as the unprivileged `hive-core`
user). `src/main.rs` is the `hive-c0re` binary — **daemon-only**
(`serve` + the periodic vacuum/sweep loops); the operator CLI lives in
the separate `hivectl` crate, which talks to the daemon over the host
admin socket. Owns the sqlite broker, approval + question + reminder +
schedule queues, the meta flake, lifecycle (`nixos-container`
shellouts), gateway / forge / matrix provisioning, per-container stats,
and the axum operator dashboard (`dashboard.rs`). Largest crate.
- **`hivectl/`** — standalone operator CLI (`hivectl` binary). Talks to
the `hive-c0re` daemon over the host admin socket (`hive-host-sock`
wire types) — does NOT link `hive-c0re`. Verbs: `list-agents`,
`agent <name> <spawn|kill|destroy|rebuild|restart|set-parent|choom|
watch|…>`, `approvals <pending|approve|deny>`, `forge`/`matrix`/
`github`/`gateway` provisioning, `stop`/`start`, `wg`/`peer-config`.
- **`hive-agent/`**, **`hive-agent-mcp/`** —
in-container harness, two sibling crates for every agent (not a
single `hive-ag3nt/` dir — that's the runtime/binary-family nickname,
not a directory).
- **`hive-agent/`** — the serve-loop binary: turn-loop *policy* layer
(`turn.rs`) over the `hive-claude` driver, per-agent web UI (`web_ui/`
module dir), event + turn-stats sqlite sinks, login flow, system-prompt
renderer.
- **`hive-agent-mcp/`** — the embedded MCP server (long-lived
streamable-http listener, `hive-mcp-http` systemd unit) + its claude
launch-config layer (tool-group/capability → `--allowedTools`,
`--mcp-config` render).
- **`hive-claude/`** — reusable, app-agnostic driver for headless
`claude --print`: spawns the CLI, streams + classifies stream-json,
parses per-turn `Telemetry`, and drives a durable self-compacting
`InfiniteSession` (name + `SessionStore` + `CompactionPolicy`). Uses
`thiserror` (it's a library); the `hive-*` binaries consume it with
`anyhow`. See `hive-claude/README.md`.
- **`hive-priv/`** — minimal root privileged-helper, socket-activated at
`/run/hive/priv.sock`; performs the few root operations (bind-mount
edits, nsenter) the unprivileged `hive-c0re` delegates to it. See
`docs/boundary.md`.
- **`hive-forge/`** — `hive-forge` Forgejo CLI wrapper; one module per
verb under `src/verbs/`.
- **`hive-forge-notify/`** — per-agent notification poller daemons; turns
unread notification threads into todos on the harness's in-agent
socket. Two binaries from one crate: `hive-forge-notify` (the hive's
Forgejo) and `hive-github-notify` (github.com, installed by
`nix/agent-modules/github.nix`). Was a task inside the `hive-agent`
serve loop; own process since it needs nothing else from the harness.
- **`hive-matrix-mcp/`** — per-agent matrix-sdk daemon
(`hive-matrix-daemon`); serves its MCP tools (`send_message`,
`read_room`, …) directly over streamable-http (no stdio bridge),
same shape as `hive-bash-mcp`.
- **`hive-bash-mcp/`** — per-agent bash-task runner daemon
(`hive-bash-daemon`); serves its MCP tools (`run`/`status`/`kill`)
directly over streamable-http (no stdio bridge), writes task files
under `/harness/bash-tasks/`, and records the favorite-tools
`bash_commands` stat into turn-stats.sqlite.
- **`hive-sh4re/`** — shared wire types (Agent / Manager request +
response, `Message`, `Approval`, `HelperEvent`) used across the unix
sockets. Host-admin-socket and hive-priv-socket wire types have been
split out into their own crates (below) so `hivectl` and `hive-priv`
don't need to pull in the rest of `hive-sh4re`.
- **`hive-host-sock/`** — wire types for the host admin socket
(`/run/hyperhive/host.sock`), the protocol `hivectl` speaks to
`hive-c0re`. Split out of `hive-sh4re` so a standalone `hivectl` only
depends on this protocol crate, not the whole daemon crate.
- **`hive-priv-sock/`** — wire types for the `hive-priv` privileged-helper
socket (`/run/hive/priv.sock`), shared by `hive-priv` (server) and
`hive-c0re` (client). Also split out of `hive-sh4re`.
- **`hive-sock-client/`** — the shared JSON-line-over-unix-socket client
every daemon uses to talk to a hyperhive socket. Generic over the
request/response types, so the host-served control socket and the
harness's in-agent socket both use it with their own wire-type crates.
Retry is a policy value (`Retry::None` for callers already inside a poll
loop, `Retry::RideOutRestart` for callers with no natural retry), and
the response is either decoded (`request`) or drained (`notify`).
Deliberately separate from the `*-sock` crates — those stay
dependency-free wire types.
- **`hive-metric/`** — small CLI to push a single labeled metric to the
OTEL collector via the OpenTelemetry Rust SDK / OTLP HTTP exporter.
### Other top-level dirs
- **`frontend/`** — npm workspaces → static dashboard + per-agent UI
dist, built hermetically by `nix/packages/frontend.nix`. Packages:
`shared` (terminal pane + Catppuccin palette), `dashboard` (the
operator SPA), `agent` (the default per-container UI).
- **`nix/`** — `host-modules/` (the host stack: hyperhive core options,
`hive-{c0re,priv,forge,gateway,matrix,network,tls,ci}`, otel, swarm),
`agent-modules/` (the per-agent harness feature modules),
`templates/{agent,ruth}.nix` (container entry points), `packages/`
(flake package outputs), `docs/` (the options-doc derivation), plus
`sources.nix` / `rust.nix` / `checks.nix` / `devshell.nix` /
`treefmt.nix` behind the thin `flake.nix`.
- **`docs/`** — subsystem reference docs (see *Reading paths* below).
- **`branding/`**, **`scripts/`** — static assets + helper scripts.
## Reading paths
Pick the doc that matches your task. None depend on the others —
read them à la carte.
- **"How do I bring a fresh hive online (first-run hivectl
bootstrap)?"** → [`docs/setup.md`](docs/setup.md).
- **"What does the dashboard look like?"** →
[`docs/web-ui.md`](docs/web-ui.md) (index; sub-pages:
[`shape`](docs/web-ui/shape.md),
[`dashboard`](docs/web-ui/dashboard.md),
[`agent`](docs/web-ui/agent.md)).
- **"How does the per-agent terminal classify + colour
events?"** → [`docs/terminal-rendering.md`](docs/terminal-rendering.md).
- **"How does claude get its prompt and what tools does it have?"** →
[`docs/turn-loop.md`](docs/turn-loop.md) (index: the loop, binary shape,
turn outcomes; sub-pages:
[`claude-invocation`](docs/turn-loop/claude-invocation.md),
[`config`](docs/turn-loop/config.md), [`mcp`](docs/turn-loop/mcp.md)).
- **"How do config changes flow from manager to operator to
container?"** → [`docs/approvals.md`](docs/approvals.md).
- **"What state survives destroy / purge / restart?"** →
[`docs/persistence.md`](docs/persistence.md).
- **"Naming, commit style, wire protocol, the `data-async`
pattern."** → [`docs/conventions.md`](docs/conventions.md).
- **"Why does the nspawn flag look like that?"** →
[`docs/gotchas.md`](docs/gotchas.md).
- **"What nginx vhosts does the gateway serve? How does matrix
discovery work?"** → [`docs/gateway.md`](docs/gateway.md).
- **"How do per-agent forge accounts work? What does forge_notify
poll + how does it format wake messages?"** →
[`docs/forge.md`](docs/forge.md).
- **"What verbs does `hive-forge` support? How do I post a comment,
upload an attachment, manage subscriptions?"** →
[`docs/tools/forge.md`](docs/tools/forge.md).
- **"What does `hivectl` do? How do I provision a forge/matrix account,
manage gateway users, restart containers, or drop into an agent shell?"** →
[`docs/tools/hivectl.md`](docs/tools/hivectl.md).
- **"How does the matrix-tuwunel container work? What about
fluffychat-web and per-agent matrix accounts?"** →
[`docs/matrix.md`](docs/matrix.md).
- **"How do I give an agent a GitHub account (`gh` + `git push`)?
How is the PAT injected?"** → [`docs/github.md`](docs/github.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).
- **"Where do agent snapshots go? How does the swarm's `btrfs receive`
endpoint authenticate a pushing hive, and what does a snapshot
actually contain?"** →
[`docs/snapshot-store.md`](docs/snapshot-store.md).
- **"How does the rebuild queue work? What are queue kinds and sources?"** →
[`docs/coordinator.md`](docs/coordinator.md).
- **"How does the CI runner work? What's the auto-registration flow?"** →
[`docs/ci.md`](docs/ci.md).
- **"What is `/knowledge`? How does the hive-wide knowledge repo sync,
and how do I contribute a document?"** →
[`docs/knowledge.md`](docs/knowledge.md).
- **"How do I export Claude Code metrics (tokens, cost, tool calls) to
a Prometheus/Grafana collector? What OTEL options are available?"** →
[`docs/observability.md`](docs/observability.md).
## Conventions & process
The docs below own the details — this section just points at them.
- **Commit style, naming, identity, reconcile verb:** →
[`docs/conventions.md`](docs/conventions.md).
- **Never add `#[allow(clippy::…)]`** — fix the lint instead (extract a
helper, add backticks, etc.). Details + worked examples: →
[`docs/conventions.md`](docs/conventions.md#building--local-checks).
- **NixOS / nspawn quirks** (bind mounts, conf flags, etc.): →
[`docs/gotchas.md`](docs/gotchas.md).
- **Turn loop, sentinels (rate-limit, auth-failed), context
window:** → [`docs/turn-loop.md`](docs/turn-loop.md).
- **Two-step spawn, approval flow, flake.lock validation:** →
[`docs/approvals.md`](docs/approvals.md).
- **Pre-push lint hook** (catches tracker-tag and comment-block failures
before CI does — install once per clone):
`ln -sf ../../scripts/pre-push .git/hooks/pre-push`