a swarm o 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. 💜
  • Rust 66.1%
  • Nix 18.6%
  • JavaScript 5.7%
  • TypeScript 4.7%
  • CSS 3.4%
  • Other 1.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
atlas d6c8cd5a6f subagent: hand a subagent its parent's built-in tools, and no others
`build_config` spawned a subagent with `--dangerously-skip-permissions`
and no `--tools` at all, so it got claude's entire built-in set —
`SendMessage` and `ListAgents` (message peers, or the operator, as its
parent), `Task*` including `TaskStop`, which takes an *agent* id and so
reaches clean outside the run, `Cron*`, `RemoteTrigger` and
`EnterWorktree`/`ExitWorktree`. None of that is part of "do this bounded
task in this directory", and none of it is something the parent agent
itself can do: the harness has always passed `--tools`.

Pass the same one. The value comes from
`hive_sh4re::permissions::builtin_tools_arg()` — literally the function
the harness resolves its own session with — so the subagent's set is the
parent's set, `HIVE_TOOL_GROUPS` and all. That inheritance is the
requirement, not an implementation detail: a hardcoded subagent list
would hand `WebFetch`/`WebSearch` to the subagent of an agent without the
`web_tools` group, which is a privilege escalation, and would drift from
the parent's list the first time anyone added a tool to either.

`--tools` is the real gate: it holds under
`--dangerously-skip-permissions`, unlike `--allowedTools`, which only
auto-approves prompts. It does not filter MCP tools, so the
`goal_reached`/`need_help` signal surface is deliberately unnamed in it
and survives on `--strict-mcp-config` alone.

`build_config`'s doc comment claimed `strict_mcp_config` was *the* safety
property and that a subagent got "nothing implicit and nothing more".
That was false for built-ins, and is what hid this gap for as long as it
did; it now says which flag covers which half and that neither
substitutes for the other.

An empty `--tools` value parses as *unset* and grants more than omitting
the flag, so an empty resolution can only be a bug — `build_config`
asserts against it and a test pins the non-emptiness alongside the
subset-of-parent property.

Refs #4416
2026-09-15 17:40:27 +02:00
.forgejo/workflows ci: daily nix flake update workflow 2026-09-13 19:14:10 +02:00
branding swarm-ui: make it installable as a PWA 2026-09-12 11:30:20 +02:00
claude-plugins subagent: make a missed continue the tool call's own error 2026-09-14 20:56:16 +02:00
docs subagent: hand a subagent its parent's built-in tools, and no others 2026-09-15 17:40:27 +02:00
frontend refactor(hive-c0re): drop the request_init_config tool and InitConfig approval 2026-09-14 19:03:44 +02:00
hive-agent permissions: give the built-in tool list one home, next to ToolGroup 2026-09-15 17:40:27 +02:00
hive-agent-mcp refactor(hive-c0re): drop the request_init_config tool and InitConfig approval 2026-09-14 19:03:44 +02:00
hive-agent-sock subagents: fold hive-extra-mcp into hive-agent-sock per mara's rescoping 2026-09-13 13:57:53 +02:00
hive-bash-mcp hive-bash-mcp: drop the redundant output-path line from status's description 2026-09-13 15:56:10 +02:00
hive-c0re matrix: fix stale admin-room comment pointing at closed issue 2026-09-15 17:22:02 +02:00
hive-core-agent-sock refactor(hive-c0re): drop the request_init_config tool and InitConfig approval 2026-09-14 19:03:44 +02:00
hive-forge hive-forge: comments total comes from the comments endpoint, not the issue object 2026-09-13 17:12:16 +02:00
hive-forge-notify hive-forge-notify: fix notify.rs's dangling doc pointer 2026-09-11 09:04:46 +02:00
hive-host-sock host.sock: push a live agent-status stream instead of poll-only 2026-09-07 18:43:47 +02:00
hive-jobq treefmt: apply prettier 2026-09-02 15:25:07 +02:00
hive-jobq-metrics move otel_http_client from swarm-queue-client into swarm-controller 2026-08-29 11:17:24 +02:00
hive-jobq-wire address review: move parse_states/filter_nodes_by_state to hive-jobq-wire, rename placeholder enums, trim core-mirroring framing 2026-08-16 16:59:54 +02:00
hive-matrix-mcp raise mcp streamable-http session keepalive from 5m to 24h 2026-08-31 12:53:07 +02:00
hive-metric docs: restructure into topic subdirectories, collapse duplicated index 2026-09-02 01:55:37 +02:00
hive-priv hive-priv: make the tmpfiles modes assertable 2026-09-11 13:02:22 +02:00
hive-priv-sock docs: restructure into topic subdirectories, collapse duplicated index 2026-09-02 01:55:37 +02:00
hive-screen-mcp treefmt: apply prettier 2026-09-02 15:25:07 +02:00
hive-sh4re permissions: give the built-in tool list one home, next to ToolGroup 2026-09-15 17:40:27 +02:00
hive-sock-client treefmt: apply prettier 2026-09-02 15:25:07 +02:00
hive-subagent-mcp subagent: hand a subagent its parent's built-in tools, and no others 2026-09-15 17:40:27 +02:00
hive-types docs: restructure into topic subdirectories, collapse duplicated index 2026-09-02 01:55:37 +02:00
hivectl refactor(hive-c0re): drop the request_init_config tool and InitConfig approval 2026-09-14 19:03:44 +02:00
nix subagent: give each run its own signal URL, and drop the name argument 2026-09-14 22:24:51 +02:00
scripts ci: add .mjs to check-comment-blocks.sh + check-issue-refs.sh's scope 2026-09-12 13:04:01 +02:00
swagger-ui-theme treefmt: apply prettier 2026-09-02 15:25:07 +02:00
swarm-authelia-bridge check-issue-refs: catch full forge issue URLs too, drop internal links from docs entirely 2026-09-09 21:15:28 +02:00
swarm-authelia-bridge-sock feat(swarm-authelia-bridge): report a heal as its own outcome 2026-08-23 19:00:41 +02:00
swarm-controller swarm: publish each agent's turn-state header on its own subject 2026-09-14 15:12:23 +02:00
swarm-nats-auth swarm-nats-auth: accept the agent suffix it ships as its default 2026-09-12 12:03:54 +02:00
swarm-queue-client swarm-queue-client: expose the announced payload limit 2026-09-13 11:51:18 +02:00
swarm-secret-client swarm-secret-client: a read policy scoped to one agent 2026-09-14 00:58:48 +02:00
swarmctl feat(swarmctl): add agent create, queueing the swarm-controller creation DAG 2026-09-14 19:40:23 +02:00
.gitignore docs: address review — redundancy proof for Passive, wave-2 split, re-enable Contractions 2026-09-07 11:56:31 +02:00
.mailmap chore(#2165): add damocles@pr1ma + lexis@pr1ma mailmap entries 2026-07-04 13:50:16 +02:00
.prettierignore hive-forge: add markdown-docs generator and CI freshness check 2026-09-02 19:38:34 +02:00
.prettierrc temp: add prettier configs 2026-07-02 23:33:11 +02:00
.vale.ini Disable Microsoft.HeadingColons and Microsoft.Percentages, fix Plurals hits 2026-09-07 14:19:24 +02:00
Cargo.lock subagent: hand a subagent its parent's built-in tools, and no others 2026-09-15 17:40:27 +02:00
Cargo.toml subagents: fold hive-extra-mcp into hive-agent-sock per mara's rescoping 2026-09-13 13:57:53 +02:00
CLAUDE.md subagent: give each run its own signal URL, and drop the name argument 2026-09-14 22:24:51 +02:00
clippy.toml hivectl: wireguard mesh setup verbs (#1756) 2026-06-19 14:37:50 +02:00
flake.lock nix flake update 2026-09-14 15:54:18 +02:00
flake.nix nix: wire the independent hive-subagent-daemon systemd unit and MCP server 2026-09-09 23:45:12 +02:00
README.md docs/hive-c0re: fix ask/answer removal doc gaps argus caught on #3741 2026-08-30 03:02:31 +02:00

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 / 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 · → docs · → options reference

Depth lives in docs/ (rendered at hyperhive.darkest.space/docs/) — start at docs/README.md and pick the page matching your task rather than reading front to back.

Quick start

Minimal flake.nix for a host that runs hive-c0re:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
    hyperhive.url = "git+https://forge.darkest.space/hyperhive/hyperhive";
    # Pin hyperhive to your own nixpkgs instead of the one it ships with
    # (see "Overriding nixpkgs" below) — recommended for most hosts:
    hyperhive.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs = { nixpkgs, hyperhive, ... }: {
    nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        hyperhive.nixosModules.default  # hive-c0re + hive-forge + hive-gateway in one import
        ({ ... }: {
          services.hyperhive.enable = true;
          # services.hyperhive.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.

Overriding nixpkgs

hyperhive pins its own nixpkgs so it builds standalone in CI. Add hyperhive.inputs.nixpkgs.follows = "nixpkgs" (as in the quick-start above) to build it against your host's nixpkgs instead — one less nixpkgs evaluation, no version drift from the rest of your system. Standard flake follows pattern; works as long as your channel is reasonably close to the 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 options reference.

Operator CLI

hivectl is the operator-facing host CLI for ad-hoc administration that doesn't go through the broker (built alongside hive-c0re when the host module is enabled):

sudo hivectl forge create-user mara                       # provisions a forge user
sudo hivectl forge create-user mara --password 'hunter2'  # … with a fixed password
sudo hivectl matrix create-user mara                      # provisions a matrix user
sudo hivectl matrix create-user mara --password-stdin     # … reading one line from stdin

For a name that's a managed agent, hivectl persists the resulting token to that agent's state dir, the same as the boot sweep does. For a non-agent name (e.g. the operator's own forge/matrix account), it prints the token to stdout and writes nothing.

Build / deploy

nix develop -c cargo check
nix flake check        # rust + nix + toml fmt + clippy

# deploy from a host config that imports hyperhive.nixosModules.default
nix flake update --update-input hyperhive
sudo nixos-rebuild switch --flake .#<host>