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 68.7%
  • Nix 15.7%
  • JavaScript 8.4%
  • CSS 3.7%
  • TypeScript 1.9%
  • Other 1.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
atlas 1db3cc32a1 job_queue: retire the now-off-wire step sub-step label
The `step` label was taken off the wire in #2661, when each deploy phase
became a first-class DAG node. Since then it has been written but never
read: `NodeRuntime` derives only `Debug, Default, Clone` — no serde — so
the field could not reach any client, and the only reads of it were the
dedup checks inside its own setters. This deletes the machinery.

Removed:

- `NodeRuntime.step`, `set_step`, `set_step_running`, and the
  `rt.step = None` clear in `complete_node`. `NodeRuntime` keeps its
  remaining `build_log_id` field (deliberately still a struct — collapsing
  it to a bare `Option<i64>` would churn every call site for no gain).
- `Ctx::step` and its ~15 call sites in `job_queue/exec.rs`. `Ctx` itself
  stays: it is the build-log sink, which `run_prebuild` and `run_swap`
  still use.
- `Coordinator::set_queue_step` and its 11 callers in `actions.rs`.
- `JobQueue::running_node_of`, reachable only from `set_queue_step`.
- `swap_update`'s `on_step` parameter and its one body call.
- The `set_step_only_on_running_and_signals_change` test.

Dropping the calls orphaned parameters, which are removed with their call
sites: `ctx` on ten executors that used it only as a step sink, and
`queue_entry_id` on `run_deploy_merge_verify` / `run_deploy_apply` /
`run_finalize_deploy` plus both `coord` and `queue_entry_id` on
`prepare_applied_target`. `run_deploy_tail` KEEPS its `queue_entry_id` —
that one has a genuine surviving use (the build-log link in the failure
comment posted to the PR).

One behavioural change, called out so it is not mistaken for a dropped
dashboard refresh: `Ctx::step` and `set_queue_step` each emitted a
`rebuild_queue_changed` snapshot when the label changed, and those
emissions go away with them. This is safe — the snapshot payload has no
step field, so those pushes carried nothing a client could observe. Real
state transitions still emit from the scheduler's claim and completion
paths, from `submit`, and from the three `actions.rs` sites. Net effect is
strictly fewer redundant SSE pushes.

Docs: `docs/coordinator.md` still listed `step` as a `NodeView` wire field
and `docs/web-ui/dashboard.md` documented a cyan `↳ <step>` sub-line under
each queue row. Neither has existed since #2661 — both corrected here, plus
the `job_queue/model.rs` module doc.

Not touched: `frontend/packages/dashboard/src/system-sections.css` has a
dead `.rqe-step` rule with no JS referencing it. Left for the frontend
owner rather than deleted here.

Closes: #2664
2026-07-26 15:24:35 +02:00
.forgejo/workflows docs: stop claiming tracker-tag/comment-block lint are non-required 2026-07-23 00:10:59 +02:00
branding docs(#1182): remove component-diagram.svg; trim README; link to website + options 2026-06-03 19:06:06 +02:00
docs job_queue: retire the now-off-wire step sub-step label 2026-07-26 15:24:35 +02:00
frontend dashboard: move infra container logs to dedicated INFRA tab 2026-07-26 15:24:33 +02:00
hive-agent feat: pause an agent's turn loop without stopping its container 2026-07-26 03:11:33 +02:00
hive-agent-mcp fix(#2635): close review nits on the questions mirror (inc2 pt2) 2026-07-26 02:07:33 +02:00
hive-agent-sock feat(#2635): wire harness-local questions mirror (inc2 pt2) 2026-07-26 02:07:33 +02:00
hive-bash-mcp feat(#2659): serve hive-bash-mcp over persistent streamable-http, drop stdio bridge 2026-07-23 18:01:20 +02:00
hive-c0re job_queue: retire the now-off-wire step sub-step label 2026-07-26 15:24:35 +02:00
hive-claude refactor(#2359): bare Deserialize derive + clarify error to_string scan 2026-07-10 20:43:58 +02:00
hive-core-agent-sock docs(#2627): add READMEs for the remaining infra crates 2026-07-23 13:16:29 +02:00
hive-forge fix(#2624): make hive-forge failures unmistakable on stderr 2026-07-26 02:44:41 +02:00
hive-host-sock feat: per-agent CPU and memory limits 2026-07-26 14:15:05 +02:00
hive-jobq docs(#2627): add READMEs for hive-jobq + the socket wire crates 2026-07-23 12:34:22 +02:00
hive-matrix-mcp feat(#2659): serve hive-matrix-mcp over persistent streamable-http, drop stdio bridge 2026-07-24 12:44:39 +02:00
hive-metric docs(#2627): add READMEs for the remaining infra crates 2026-07-23 13:16:29 +02:00
hive-priv hive-priv: redact password-bearing lines before logging forgejo admin output 2026-07-26 15:24:32 +02:00
hive-priv-sock docs(#2627): add READMEs for hive-jobq + the socket wire crates 2026-07-23 12:34:22 +02:00
hive-screen-mcp docs(#2627): add README for hive-screen-mcp 2026-07-23 14:17:47 +02:00
hive-sh4re feat(dashboard): show jobq node tree in build queue 2026-07-26 03:14:52 +02:00
hive-types docs(#2627): add READMEs for the remaining infra crates 2026-07-23 13:16:29 +02:00
hivectl feat: per-agent CPU and memory limits 2026-07-26 14:15:05 +02:00
nix remove hive-agent-wake — no shipped consumer 2026-07-25 20:05:32 +02:00
scripts docs: stop claiming tracker-tag/comment-block lint are non-required 2026-07-23 00:10:59 +02:00
.gitignore fix(review): drop libnull.rlib artifact + add Errors doc to ensure_config_pr_webhook 2026-07-11 12:19:52 +02:00
.mailmap chore(#2165): add damocles@pr1ma + lexis@pr1ma mailmap entries 2026-07-04 13:50:16 +02:00
.prettierignore fix(#1997): exclude docs/tools/forge.md from prettier (list-item continuations) 2026-07-02 23:33:11 +02:00
.prettierrc temp: add prettier configs 2026-07-02 23:33:11 +02:00
Cargo.lock remove hive-agent-wake — no shipped consumer 2026-07-25 20:05:32 +02:00
Cargo.toml remove hive-agent-wake — no shipped consumer 2026-07-25 20:05:32 +02:00
CLAUDE.md remove hive-agent-wake — no shipped consumer 2026-07-25 20:05:32 +02:00
clippy.toml hivectl: wireguard mesh setup verbs (#1756) 2026-06-19 14:37:50 +02:00
flake.lock nix flake update 2026-07-13 13:58:53 +02:00
flake.nix remove hive-agent-wake — no shipped consumer 2026-07-25 20:05:32 +02:00
README.md docs: shorten Overriding nixpkgs section 2026-07-16 00:06:17 +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 / 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 → :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)
│
├── optional containers
│   ├── hive-gateway   nginx — proxies :80 → c0re dashboard + per-agent sockets
│   ├── hive-forge     Forgejo — per-agent accounts, config mirror (agent-configs/)
│   └── hive-matrix    tuwunel — Matrix homeserver + per-agent accounts
│
└── agent containers
    ├── h-ruth     manager (privileged MCP surface, approval gating)
    └── h-<name>   sub-agent (claude + MCP tools + per-agent web UI + unix socket)

→ website · → options reference

Depth lives in docs/ — pick the one matching your task:

reading path doc
dashboard layout + endpoints docs/web-ui.md (shape · dashboard · agent)
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
nginx vhost map + sub-domain routing docs/gateway.md
NixOS / nspawn gotchas docs/gotchas.md

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.

Agent configuration

Per-agent config lives in each agent's agent.nix (proposed, operator-approved, deployed as git commits). Key options:

Multi-account Matrix support

hyperhive.matrixAccounts declares additional matrix accounts for an agent, beyond the hive-internal one. Each entry is keyed by account name and specifies:

  • tokenFile — path to the matrix bearer token (provisioned out-of-band)
  • sessionDir — path to the per-account matrix-sdk sqlite state (crypto keys + cache)
  • homeserver — optional homeserver URL (defaults to hyperhive.matrix.url)

Example:

hyperhive.matrixAccounts = {
  external-public = {
    tokenFile = "/agents/myagent/state/matrix-token-external";
    sessionDir = "/agents/myagent/state/matrix-sdk-state-external";
    homeserver = "https://matrix.org";
  };
};

The hive-internal account is always named main (synthesized from hyperhive.matrix.url + agent state). This option only declares extras; the main name is reserved and cannot be used here. Requires hyperhive.matrix.enable = true.

For more details see docs/matrix.md.

GitHub account

Every agent gets a managed GitHub identity — a gh CLI wrapper and git push over HTTPS — on by default (hyperhive.github.enable), inert until a PAT is provisioned. There is nothing per-agent to declare: paste an operator-supplied personal access token into the agent's dashboard credentials tab (or hivectl github set-token <agent> --token-stdin) and it works. The gh wrapper + git credential helper read the token live (git auths as x-access-token + the PAT; github.com only), so a rotated PAT takes effect with no rebuild.

Turn the integration off for the whole hive with the host option:

services.hyperhive.github.enable = false;

The PAT value is never in nix — only the enable flag. For more details see docs/github.md.

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 agent names (i.e., a Coordinator::agent_state_root(name) exists), hivectl persists the resulting token to the agent's state dir like the boot sweep does. For non-agent names (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>