The retry was capped at 12 attempts (~20s of exponential backoff capped at 2s). Two back-to-back nspawn restarts in #324 left the previous socket holding the port longer than that budget; once the cap fired, the web-UI task returned an error and silently died for the rest of the process lifetime — the agent kept running fine otherwise (MCP, turn loop), but the operator's dashboard click hit nothing. Genuine port collisions are preflighted host-side (lifecycle::{spawn,rebuild}) and surfaced as a port-conflict banner, so at this layer a persistent AddrInUse always reflects a recoverable stale socket. Drop the cap, keep retrying forever with the same 2s-capped backoff. WARN for the first dozen attempts so a normal restart-race is visible; INFO after that to avoid spamming the journal during a long stale-socket hold. Logs a one-line INFO on success when we did have to retry, so post-mortems can find the attempt count. Closes #324. |
||
|---|---|---|
| branding | ||
| docs | ||
| hive-ag3nt | ||
| hive-c0re | ||
| hive-fr0nt | ||
| hive-sh4re | ||
| nix | ||
| scripts | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CLAUDE.md | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
| TODO.md | ||
hyperhive
a swarm of claude-code agents, each in its own nspawn cage, gossiping over unix sockets. config changes flow as git commits, the operator approves them in a browser, every deploy is a tag. cyberpunk-themed 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/ask/answer/remind) - config = git (manager proposes, operator approves, deploys land as tagged commits)
- blast radius = container
host (NixOS, runs hive-c0re.service)
│
├── operator
│ ├── browser → :7000 hive-c0re dashboard
│ ├── browser → :8000 / :8100-8999 per-agent web UIs
│ └── CLI → /run/hyperhive/host.sock admin protocol
│
├── hive-c0re (Rust daemon: lifecycle / broker / approvals /
│ auto-update / dashboard / sockets)
│
└── nixos-containers
├── hm1nd manager agent (privileged MCP surface)
└── h-<name> sub-agent (vanilla MCP surface + per-agent extras)
Depth lives in docs/ — pick the one matching your task:
| reading path | doc |
|---|---|
| dashboard layout + endpoints | docs/web-ui.md |
| claude turn loop + MCP tools | docs/turn-loop.md |
| config-edit + approval state machine | docs/approvals.md |
| what survives destroy / purge / restart | docs/persistence.md |
| naming, wire protocol, commit style | docs/conventions.md |
| NixOS / nspawn gotchas | docs/gotchas.md |
Host config
Minimal flake.nix for a host that runs hive-c0re:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
hyperhive.url = "git+https://git.berlin.ccc.de/vinzenz/hyperhive";
};
outputs = { nixpkgs, hyperhive, ... }: {
nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
hyperhive.nixosModules.default # hive-c0re + hive-forge in one import
({ ... }: {
services.hive-c0re.enable = true;
# services.hive-c0re.operatorPronouns = "they/them"; # default: "she/her"
# ... rest of your host config
system.stateVersion = "25.11";
})
];
};
};
}
hive-c0re opens its admin socket + dashboard, auto-creates the
manager container, and auto-rebuilds any container whose hyperhive
rev goes stale. claude-code is unfree — hyperhive scopes the
whitelist to itself, nothing for the operator to set.
Agent configuration
Per-agent settings live in each agent's agent.nix and are synced to
the container as environment variables. Common options:
hyperhive.model— Claude model for this agent (default:"haiku"). SetsHIVE_DEFAULT_MODELin the container; the harness applies it at boot and it takes priority over any persisted runtime override. The operator can still switch the model at runtime via the per-agent web UI, but that choice is reset by any rebuild that changes this option.hyperhive.allowedRecipients— List of agent names this agent can message (viasend). If unset, all agents are allowed. Useful to restrict an agent to talking only to the manager.hyperhive.forge.url— Base URL of the hyperhive-managed Forgejo (default:"http://localhost:3000"). Used to configure the agent's tea login at boot; no-op if/state/forge-tokenis missing.hyperhive.forge.keepSubscriptions— Boolean. Iftrue, the agent's forge repo subscriptions are never auto-cleaned during rebuild; useful for agents that want to watch specific repos. Rendered asHIVE_FORGE_KEEP_SUBSCRIPTIONS.hyperhive.forge.skipNotifyReasons— List of forge notificationreasonvalues to suppress (e.g.[ "subscribed" "participating" ]). Notifications matching these reasons are silently dropped; all others including direct mentions and reviews are delivered. Empty list (default) delivers all notifications. Rendered asHIVE_FORGE_NOTIFY_SKIP_REASONS(comma-separated).
See nix/templates/harness-base.nix for the full list of options and
their descriptions.
Build / deploy
nix develop -c cargo check
nix flake check # rust + nix + toml fmt + clippy
# deploy from a host config that imports hyperhive.nixosModules.hive-c0re
nix flake update --update-input hyperhive
sudo nixos-rebuild switch --flake .#<host>