diff --git a/CLAUDE.md b/CLAUDE.md index 9b52b3f4..37322c3a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -32,8 +32,9 @@ hand-maintained per-file tree drifts out of sync with the code. the meta flake, lifecycle (`nixos-container` shellouts), gateway / forge / matrix provisioning, per-container stats, and the axum operator dashboard (`dashboard.rs`). Largest crate. -- **`hive-ag3nt/`** — in-container harness; one `hive` binary for every - agent. Turn-loop *policy* layer (`turn.rs`) over the `hive-claude` +- **`hive-ag3nt/`** — in-container harness; three sibling binaries for + every agent (`hive-agent` serve loop, `hive-agent-mcp`, + `hive-agent-wake`). Turn-loop *policy* layer (`turn.rs`) over the `hive-claude` driver, embedded MCP server (`mcp.rs`) + its claude launch-config layer (`mcp_config.rs`: tool-group/capability → `--allowedTools`, `--mcp-config` render), per-agent web UI (`web_ui/` module dir), event + turn-stats diff --git a/docs/agent-hierarchy.md b/docs/agent-hierarchy.md index a11ac9a6..038a52c3 100644 --- a/docs/agent-hierarchy.md +++ b/docs/agent-hierarchy.md @@ -214,7 +214,8 @@ nspawn agent. Open questions, not yet wired: ## Harness systemd unit shape -One harness binary (`hive`), one `harness-base.nix` template, one +One harness serve binary (`hive-agent`, with its `hive-agent-mcp` / +`hive-agent-wake` siblings), one `harness-base.nix` template, one service unit (`systemd.services.hive-ag3nt`) for all agents. There is no longer a separate manager service name or role distinction in the harness — privilege differences live server-side in the broker @@ -259,7 +260,8 @@ bit set` regardless of `hyperhive.user.passwordlessSudo`. ### `serviceConfig` highlights -- `ExecStart = pkgs.hyperhive/bin/hive serve` — single binary. +- `ExecStart = pkgs.hyperhive/bin/hive-agent` — same binary for + every agent. - `Restart = on-failure`, `RestartSec = 2` — keeps the harness resilient across transient crashes without thundering retries. - `RuntimeDirectory = "hive-config"` → `/run/hive-config/` owned by diff --git a/docs/turn-loop.md b/docs/turn-loop.md index 30b5390f..2a16037e 100644 --- a/docs/turn-loop.md +++ b/docs/turn-loop.md @@ -5,7 +5,8 @@ claude has access to in return. ## The loop -Each agent harness (`hive serve` — one binary for all agents) runs: +Each agent harness (`hive-agent` — one serve-loop binary for all +agents) runs: 1. Long-poll `Recv` on its socket. The host-side broker (`broker.rs::recv_blocking_batch`) returns immediately if there's @@ -51,38 +52,37 @@ Each agent harness (`hive serve` — one binary for all agents) runs: ## Harness binary shape -One `hive` binary for all agents. The earlier split into -`hive-ag3nt` + `hive-m1nd` was collapsed because the privilege -boundary lives server-side at the broker socket -(`/run/hive/mcp.sock`): `ManagerRequest` calls are refused by the -standard agent socket regardless of who sends them. +Three sibling binaries out of the one `hive-ag3nt` crate, all +role-agnostic. (The earlier split into `hive-ag3nt` + `hive-m1nd` +was collapsed because the privilege boundary lives server-side at +the broker socket (`/run/hive/mcp.sock`): `ManagerRequest` calls are +refused by the standard agent socket regardless of who sends them.) -Three subcommands: - -- `serve` — long-running harness loop (the inbox poll + +- `hive-agent` — long-running harness loop (the inbox poll + claude-pump + ack/requeue cycle described above). -- `mcp` — MCP server. Default: stdio child claude spawns via - `--mcp-config` per turn. With `--http `, runs as a persistent - streamable-HTTP daemon instead (used by the `hive-mcp-http` - systemd unit when `hyperhive.mcp.httpPort` is set). -- `wake --from --body ` — push a message into our own - inbox so the next turn fires with the given body. Used by - co-process daemons (matrix bridge, scraper, webhook listeners) - to nudge claude on external events. `--body -` reads from stdin. +- `hive-agent-mcp` — MCP server. Default: stdio child claude spawns + via `--mcp-config` per turn (the serve loop renders the config to + point at this sibling of its own `/proc/self/exe`). With + `--http `, runs as a persistent streamable-HTTP daemon + instead (used by the `hive-mcp-http` systemd unit when + `hyperhive.mcp.httpPort` is set). +- `hive-agent-wake --from --body ` — push a message into + our own inbox so the next turn fires with the given body. Used by + co-process helpers (scrapers, webhook listeners) to nudge claude on + external events. `--body -` reads from stdin. ### `Surface` trait + zero-sized type tags `AgentRequest` / `AgentResponse` (= `ManagerRequest` / `ManagerResponse` — type aliases) are the wire types. There is one role: agent. -`bin/hive.rs` factors the turn loop through a `Surface` trait with one -zero-sized impl (`AgentSurface`) wrapping: +`bin/hive-agent.rs` factors the turn loop through a `Surface` trait +with one zero-sized impl (`AgentSurface`) wrapping: - One async method per wire op: `ack_turn`, `requeue_inflight`, - `inbox_unread`, `post_turn_counts`, `send_to_parent`, - `recv_next`, `wake_external`. + `inbox_unread`, `post_turn_counts`, `send_to_parent`, `recv_next`. `main()` calls `serve_main::` for all roles. The turn -loop (`serve_loop` / `handle_turn` / `wake`) has no per-role branches. +loop (`serve_loop` / `handle_turn`) has no per-role branches. ### Boot wiring diff --git a/docs/turn-loop/mcp.md b/docs/turn-loop/mcp.md index 02d707ed..2552e64a 100644 --- a/docs/turn-loop/mcp.md +++ b/docs/turn-loop/mcp.md @@ -138,7 +138,7 @@ External MCP servers (and any other in-container process) can inject a wake-up event into the agent's inbox via the per-agent socket at `/run/hive/mcp.sock`. Two equivalent paths: -- **Shell out to `hive wake --from