README: reframe around multi-hive swarms, all-local quick start, agent amenities
This commit is contained in:
parent
2c7e586f47
commit
07828cd573
1 changed files with 162 additions and 80 deletions
256
README.md
256
README.md
|
|
@ -1,130 +1,212 @@
|
||||||
# <img src="branding/hyperhive.svg" alt="" width="38" align="top"> hyperhive
|
# <img src="branding/hyperhive.svg" alt="" width="38" align="top"> hyperhive
|
||||||
|
|
||||||
> a swarm of claude-code agents, each in its own nspawn cage, gossiping
|
> a swarm of coding agents spread across NixOS hosts — every agent in its
|
||||||
> over unix sockets. config changes flow as git commits, the operator
|
> own nspawn cage, every host a hive, one control plane over all of them.
|
||||||
> approves them in a browser, every deploy is a tag. cyberpunk-themed
|
> config changes flow as git commits, the operator approves them in a
|
||||||
> dashboard included. 💜⚡
|
> browser, every deploy is a tag. cyberpunk dashboard included. 💜⚡
|
||||||
|
|
||||||
Claude code is great in one window, _exponentielle_ across many — but
|
|
||||||
only if you can keep the agents from stepping on each other, give them
|
|
||||||
durable identity, and stop them from eating production. hyperhive is
|
|
||||||
the substrate.
|
|
||||||
|
|
||||||
- identity = unix socket
|
|
||||||
- communication = sqlite-backed broker (`send` / `recv` / `remind`)
|
|
||||||
- config = git (manager proposes, operator approves, deploys land as
|
|
||||||
tagged commits)
|
|
||||||
- blast radius = container
|
|
||||||
|
|
||||||
```
|
|
||||||
every hive (NixOS host, runs hive-c0re.service)
|
|
||||||
│
|
|
||||||
├── operator
|
|
||||||
│ ├── browser → :80 (hive-gateway) dashboard + per-agent UIs
|
|
||||||
│ │ /agent/<name>/ → per-agent unix socket
|
|
||||||
│ └── CLI → /run/hyperhive/host.sock admin protocol
|
|
||||||
│
|
|
||||||
├── hive-c0re (Rust daemon: lifecycle / broker / approvals /
|
|
||||||
│ auto-update / dashboard / sockets)
|
|
||||||
│
|
|
||||||
├── hive-gateway (optional) nginx — proxies :80 → c0re dashboard + per-agent sockets
|
|
||||||
│
|
|
||||||
└── agent containers
|
|
||||||
├── h-ruth manager (privileged MCP surface, approval gating)
|
|
||||||
└── h-<name> sub-agent (claude + MCP tools + per-agent web UI + unix socket)
|
|
||||||
|
|
||||||
one host per swarm (optional — connects hives; can be any hive, including
|
|
||||||
one that's also running the tree above)
|
|
||||||
│
|
|
||||||
├── hive-forge Forgejo — swarm-wide singleton, per-agent accounts + config mirror
|
|
||||||
├── hive-matrix tuwunel — swarm-wide singleton, Matrix homeserver + per-agent accounts
|
|
||||||
├── swarm-controller cross-hive state: hive directory, agent roster, jobs
|
|
||||||
├── swarm-ui swarm-wide SPA, served straight off the gateway (no own container)
|
|
||||||
├── swarm-authelia SSO — one login gates swarm-ui + Grafana + more
|
|
||||||
├── swarm-nats message queue (JetStream KV: hive-status, …)
|
|
||||||
├── swarm-otel telemetry collector, sole holder of the upstream credential
|
|
||||||
├── swarm-victoriametrics metrics store
|
|
||||||
├── swarm-victorialogs log store
|
|
||||||
└── swarm-grafana dashboards over the metrics/log stores, own OIDC login
|
|
||||||
```
|
|
||||||
|
|
||||||
**[→ website](https://hyperhive.darkest.space)** ·
|
**[→ website](https://hyperhive.darkest.space)** ·
|
||||||
**[→ docs](https://hyperhive.darkest.space/docs/)** ·
|
**[→ docs](https://hyperhive.darkest.space/docs/)** ·
|
||||||
**[→ options reference](https://hyperhive.darkest.space/options/)**
|
**[→ options reference](https://hyperhive.darkest.space/options/)**
|
||||||
|
|
||||||
Depth lives in [`docs/`](docs/) (rendered at
|
A coding agent is great in one window, _exponentielle_ across many — as
|
||||||
[hyperhive.darkest.space/docs/](https://hyperhive.darkest.space/docs/)) —
|
long as the agents stay off each other's toes, keep a durable identity,
|
||||||
start at [`docs/README.md`](docs/README.md) and pick the page matching
|
and leave production alone. hyperhive is the substrate for that, as a set
|
||||||
your task rather than reading front to back.
|
of NixOS modules:
|
||||||
|
|
||||||
## Quick start
|
- a **hive** is one host running `hive-c0re` and the agent containers it
|
||||||
|
owns;
|
||||||
|
- a **swarm** is any number of hives sharing one identity plane — SSO,
|
||||||
|
forge, matrix, secret store, telemetry — with a controller that places
|
||||||
|
agents on hives and tracks them across all of them.
|
||||||
|
|
||||||
Minimal `flake.nix` for a host that runs hive-c0re:
|
Start with everything on one box; move services and add hives as the
|
||||||
|
swarm grows. Which host runs what is a per-host `deploy.*` toggle,
|
||||||
|
not an architecture change.
|
||||||
|
|
||||||
|
| concern | how hyperhive answers it |
|
||||||
|
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **scale-out** | hives share one directory (`swarm.hives`, identical on every host); `swarmctl agent create --hive <h>` places an agent and the controller keeps the roster |
|
||||||
|
| **identity** | every agent gets swarm-wide accounts — SSO subject, forge user, matrix account, secret-store cert identity — and is addressable as `name@hive.domain` |
|
||||||
|
| **shared plane** | one forge, homeserver, secret store, SSO, queue and metrics/logs stack per swarm, each on whichever host you put it |
|
||||||
|
| **blast radius** | one `nixos-container` per agent; the host daemon runs unprivileged, and a tiny socket-activated helper does the few root ops |
|
||||||
|
| **config** | git: an agent proposes, the operator approves, the deploy lands as a `deployed/<id>` tag |
|
||||||
|
| **runtime** | `claude --print` by default; any [ACP](https://agentclientprotocol.com) agent (e.g. opencode) per agent with `services.hyperhive.agent.runtime = "acp"` |
|
||||||
|
| **watching** | per-agent web UI with a live terminal, a per-hive dashboard, the swarm UI, Grafana over OTEL |
|
||||||
|
|
||||||
|
## Shape
|
||||||
|
|
||||||
|
```
|
||||||
|
every hive (NixOS host, deploy.hive-controller.enable)
|
||||||
|
│
|
||||||
|
├── operator
|
||||||
|
│ ├── browser → :80/:443 (hive-gateway) dashboard + /agent/<name>/ UIs
|
||||||
|
│ └── hivectl → /run/hyperhive/host.sock admin protocol
|
||||||
|
│
|
||||||
|
├── hive-c0re Rust daemon: lifecycle, broker, approvals, job queue,
|
||||||
|
│ auto-rebuild, dashboard — runs as the unprivileged hive-core user
|
||||||
|
├── hive-priv root helper, socket-activated, does bind-mounts + nsenter
|
||||||
|
├── hive-gateway nginx + dnsmasq in front of c0re and every agent socket
|
||||||
|
│
|
||||||
|
└── agent containers
|
||||||
|
├── h-ruth manager — privileged MCP surface, spawns + configures agents
|
||||||
|
└── h-<name> agent — claude / ACP runtime, MCP tools, web UI, own socket
|
||||||
|
|
||||||
|
the swarm's shared services (one host each — any hive, or a dedicated box)
|
||||||
|
│
|
||||||
|
├── hive-forge Forgejo — per-agent accounts, config mirror
|
||||||
|
├── hive-matrix tuwunel — matrix homeserver, per-agent accounts
|
||||||
|
├── swarm-bao OpenBao — the swarm's secret store, cert auth per agent
|
||||||
|
├── swarm-controller cross-hive state: hive directory, agent roster, jobs
|
||||||
|
│ (+ swarmctl, + swarm-ui served off the gateway)
|
||||||
|
├── swarm-authelia SSO in front of swarm-ui, forge, grafana, …
|
||||||
|
├── swarm-nats message queue (JetStream KV: hive status, …)
|
||||||
|
├── swarm-otel telemetry collector, sole holder of upstream creds
|
||||||
|
├── swarm-victoriametrics metrics store
|
||||||
|
├── swarm-victorialogs log store
|
||||||
|
├── swarm-grafana dashboards over both stores
|
||||||
|
│
|
||||||
|
└── opt-in, not part of singleHostSwarm
|
||||||
|
├── hive-ci Forgejo Actions runner (deploy.forgejo.ci)
|
||||||
|
├── swarm-snapshot-store btrfs-receive endpoint for agent snapshots
|
||||||
|
└── wg-hive WireGuard mesh between hives (deploy.wireguard)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Inside an agent
|
||||||
|
|
||||||
|
Every agent is a full NixOS container with its own unix user (passwordless
|
||||||
|
sudo inside the cage) and a durable, self-compacting session. Out of the
|
||||||
|
box it gets:
|
||||||
|
|
||||||
|
- **messaging** — `send` / `recv` to other agents and the operator,
|
||||||
|
`remind` and recurring schedules to wake itself, and a todo list that
|
||||||
|
forge notifications and other producers feed. →
|
||||||
|
[scheduling](docs/tools/scheduling.md)
|
||||||
|
- **background bash** — long-running commands as tracked tasks
|
||||||
|
(`run` / `status` / `kill`), so a build doesn't block the turn. →
|
||||||
|
[bash](docs/tools/bash.md)
|
||||||
|
- **subagents** — nested sessions on the agent's own runtime, optionally
|
||||||
|
re-prompted toward a goal over several turns. →
|
||||||
|
[subagent](docs/tools/subagent.md)
|
||||||
|
- **forge** — its own Forgejo account, the `hive-forge` CLI, git
|
||||||
|
credentials, and notifications turned into todos. Optional linked
|
||||||
|
accounts on other forges, and GitHub (`gh` + push) via
|
||||||
|
`services.hyperhive.agent.github.enable`. →
|
||||||
|
[forge](docs/integrations/forge.md) · [github](docs/integrations/github.md)
|
||||||
|
- **matrix** — its own account(s) on the swarm homeserver, as MCP tools. →
|
||||||
|
[matrix](docs/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/integrations/knowledge.md)
|
||||||
|
- **web UI** — a per-agent page behind the gateway: live terminal of the
|
||||||
|
turn stream, model / effort switching, cancel, `/compact`.
|
||||||
|
- **GUI** (opt-in, `services.hyperhive.agent.gui.enable`) — a Wayland
|
||||||
|
desktop with screenshot / keyboard / mouse tools, viewable over VNC in
|
||||||
|
the web UI.
|
||||||
|
- **your own tools** — any extra MCP server (stdio or http) via
|
||||||
|
`services.hyperhive.agent.extraMcpServers`, and any NixOS config you'd
|
||||||
|
put on a machine.
|
||||||
|
|
||||||
|
## Quick start: an all-local swarm
|
||||||
|
|
||||||
|
The whole swarm on one box — a hive plus every shared service. Good for a
|
||||||
|
dev box or a single-host deployment; [`docs/swarm/`](docs/swarm/README.md)
|
||||||
|
covers spreading a swarm across hosts.
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
|
||||||
hyperhive.url = "git+https://forge.darkest.space/hyperhive/hyperhive";
|
hyperhive.url = "git+https://forge.darkest.space/hyperhive/hyperhive";
|
||||||
# Pin hyperhive to your own nixpkgs instead of the one it ships with
|
hyperhive.inputs.nixpkgs.follows = "nixpkgs"; # see "Overriding nixpkgs"
|
||||||
# (see "Overriding nixpkgs" below) — recommended for most hosts:
|
|
||||||
hyperhive.inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { nixpkgs, hyperhive, ... }: {
|
outputs = { nixpkgs, hyperhive, ... }: {
|
||||||
nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
|
nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
|
||||||
system = "x86_64-linux";
|
system = "x86_64-linux";
|
||||||
modules = [
|
modules = [
|
||||||
hyperhive.nixosModules.default # hive-c0re + hive-forge + hive-gateway in one import
|
hyperhive.nixosModules.default # the whole host stack, one import
|
||||||
({ ... }: {
|
{
|
||||||
services.hyperhive.deploy.hive-controller.enable = true;
|
services.hyperhive = {
|
||||||
# services.hyperhive.c0re.operatorPronouns = "they/them"; # default: "she/her"
|
deploy.singleHostSwarm = true; # run everything on one machine
|
||||||
|
|
||||||
# ... rest of your host config
|
swarm.domain = "hive.example"; # the swarm's DNS domain
|
||||||
|
hiveName = "pr1ma"; # this hive's label in it
|
||||||
|
swarm.hives.pr1ma = { }; # the directory: just us
|
||||||
|
|
||||||
|
# c0re.operatorPronouns = "they/them"; # default "she/her"
|
||||||
|
};
|
||||||
|
|
||||||
|
# ... the rest of your host config
|
||||||
system.stateVersion = "25.11";
|
system.stateVersion = "25.11";
|
||||||
})
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
hive-c0re opens its admin socket + dashboard, auto-creates the
|
`singleHostSwarm` turns on everything an all-on-one-box swarm implies:
|
||||||
manager container, and auto-rebuilds any container whose hyperhive
|
the shared services above, the swarm CA, the swarm controller, and
|
||||||
rev goes stale. `claude-code` is unfree — hyperhive scopes the
|
`/etc/hosts` entries so the hive's names resolve on the box itself.
|
||||||
whitelist to itself, nothing for the operator to set.
|
`claude-code` is unfree — hyperhive scopes the allowance to itself, so
|
||||||
|
there's nothing to set.
|
||||||
|
|
||||||
|
After `nixos-rebuild switch`, hive-c0re creates the manager (`ruth`) and
|
||||||
|
keeps every container rebuilt whenever its hyperhive rev goes stale. A few
|
||||||
|
steps stay deliberately human — initialising the secret store, giving ruth
|
||||||
|
her store identity, adding a gateway login, SSO. Walk through
|
||||||
|
**[`docs/getting-started/setup.md`](docs/getting-started/setup.md)**
|
||||||
|
once, top to bottom.
|
||||||
|
|
||||||
### Overriding nixpkgs
|
### Overriding nixpkgs
|
||||||
|
|
||||||
hyperhive pins its own `nixpkgs` so it builds standalone in CI. Add
|
hyperhive pins its own `nixpkgs` so it builds standalone in CI. The
|
||||||
`hyperhive.inputs.nixpkgs.follows = "nixpkgs"` (as in the quick-start above)
|
`follows` line above builds it against your host's `nixpkgs` instead: one
|
||||||
to build it against your host's `nixpkgs` instead — one less nixpkgs
|
evaluation, no version drift. It works as long as your channel is close to
|
||||||
evaluation, no version drift from the rest of your system. Standard flake
|
the `nixos-26.05` hyperhive develops against — drop it if a much older or
|
||||||
`follows` pattern; works as long as your channel is reasonably close to the
|
newer channel breaks in ways hyperhive's CI doesn't catch.
|
||||||
`nixos-26.05` hyperhive develops against. Drop it again if a much
|
|
||||||
older/newer channel hits breakage hyperhive's CI doesn't catch.
|
|
||||||
|
|
||||||
For the full list of host and agent NixOS options see the
|
## Operating it
|
||||||
**[options reference](https://hyperhive.darkest.space/options/)**.
|
|
||||||
|
|
||||||
## Operator CLI
|
- **`hivectl`** — the hive's operator CLI, on every hive host: agents,
|
||||||
|
approvals, gateway logins, container shells. Talks to hive-c0re over
|
||||||
|
`/run/hyperhive/host.sock`. → [guide](docs/tools/hivectl.md) ·
|
||||||
|
[full reference](docs/tools/hivectl-cli.md)
|
||||||
|
- **`swarmctl`** — the swarm's operator CLI, on the swarm-controller host:
|
||||||
|
creating agents with their identities, SSO users, forge admins.
|
||||||
|
→ [reference](docs/tools/swarmctl-cli.md)
|
||||||
|
- **Dashboard** — approvals, agent state, the job graph, per-agent
|
||||||
|
terminals. → [`docs/web-ui/`](docs/web-ui/README.md)
|
||||||
|
|
||||||
`hivectl` is the operator-facing host CLI for ad-hoc administration that
|
Human accounts come from SSO: a first login through authelia creates your
|
||||||
doesn't go through the broker (built alongside `hive-c0re` when the host
|
forge and matrix accounts; `swarmctl forge make-admin <you>` promotes the
|
||||||
module is enabled). Human matrix accounts come from SSO login, not
|
forge one.
|
||||||
`hivectl`.
|
|
||||||
|
|
||||||
A human's first SSO login to the forge makes their forge account, not
|
## Where to read next
|
||||||
`hivectl`; `swarmctl forge make-admin <name>` on the swarm-controller's
|
|
||||||
host makes it a site admin.
|
|
||||||
|
|
||||||
## Build / deploy
|
[`docs/README.md`](docs/README.md) is the index, grouped by question —
|
||||||
|
pick the page for your task rather than reading front to back. Some
|
||||||
|
common entry points:
|
||||||
|
|
||||||
|
- how config changes flow → [`agent-lifecycle/approvals.md`](docs/agent-lifecycle/approvals.md)
|
||||||
|
- trust boundary + threat model → [`trust-boundary/`](docs/trust-boundary/boundary.md)
|
||||||
|
- what an agent's turn looks like → [`turn-loop/`](docs/turn-loop/README.md)
|
||||||
|
- connecting hives into a swarm → [`swarm/`](docs/swarm/README.md)
|
||||||
|
- every `services.hyperhive.*` option → [options reference](https://hyperhive.darkest.space/options/)
|
||||||
|
|
||||||
|
## Hacking on it
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
nix develop -c cargo check
|
nix develop -c cargo check
|
||||||
nix flake check # rust + nix + toml fmt + clippy
|
nix flake check # rust + nix + toml fmt, clippy, module-eval tests
|
||||||
|
|
||||||
# deploy from a host config that imports hyperhive.nixosModules.default
|
# in your host flake:
|
||||||
nix flake update --update-input hyperhive
|
nix flake update hyperhive
|
||||||
sudo nixos-rebuild switch --flake .#<host>
|
sudo nixos-rebuild switch --flake .#<host>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Conventions (commit style, no `#[allow(clippy::…)]`, the pre-push hook)
|
||||||
|
live in [`docs/process/conventions.md`](docs/process/conventions.md).
|
||||||
|
Issues + backlog are on the
|
||||||
|
[forge](https://forge.darkest.space/hyperhive/hyperhive/issues).
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue