Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/hive-subagent-mcp
Repository files (latest commit first)
Filename Latest commit message Latest commit date
atlas 89013b5408 agent permissions: hold hive-c0re's stored grant until the agent's own read
Until its first successful read of its key, the harness read its
permissions as the default set, `execution` included. So did the
subagent daemon. An agent the operator had narrowed ran wider than
granted after every restart while the queue was unreachable, and in the
gap before the first 10 s poll. During the meta-repo import, every
non-ruth key is still unset, and the agent read that as the default too,
for as long as the import stayed pending.

mara picked option (a) on #5293: "a, removal of the old path as a follow
up in 1w".

hive-c0re now writes each agent's entry from
swarm-agent-permissions.json into the agent's runtime dir as
swarm-permissions.json (/run/hive in the container), together with
whether the import is still pending. It writes the file at every start
(write_dropins) and after every 30 s pass of the permissions worker. The
harness and the subagent daemon hold that stored list until their own
first read succeeds. While the import is pending, an unset key keeps
the stored list rather than reverting it to the default. A queue that
is down never blocks a start: the agent runs on the stored grant.

The decision lives in swarm_queue_client::agent_permissions::HiveCopy,
shared by both readers.

Part of #5170.
2026-10-15 18:01:40 +02:00
..
src agent permissions: hold hive-c0re's stored grant until the agent's own read 2026-10-15 18:01:40 +02:00
tests subagent: keep runs at +1000 when their cgroup is unavailable 2026-10-13 12:25:27 +02:00
Cargo.toml agent permissions: one set, tool groups included, set at agent creation 2026-10-15 18:01:40 +02:00
README.md subagent: give each run its own signal URL, and drop the name argument 2026-09-14 22:24:51 +02:00

hive-subagent-mcp

Per-agent daemon (hive-subagent-daemon) that spawns nested headless claude sessions on request and serves the tool surface (start/continue/status/interrupt, plus a separate subagent-facing goal_reached/need_help route, one per-session URL) directly over streamable-http. No stdio bridge, no per-turn respawn — an agent's claude reconnects to the same stable URL every turn.

Independent of hive-bash-mcp — a subagent spawns a full nested claude session, a much heavier capability than a bash command, worth its own deployable/restartable unit.

Shape

One bin (hive-subagent-daemon, src/main.rs) built from the crate's own lib (src/lib.rs):

  • session.rs — the actual claude-facing logic: Claude::spawn + RunningClaude::wait/cancel_handle (not InfiniteSession::run, which has no cancel handle to reach in — see the module doc for the v1 scope this trades away), the turn-continuation loop a goal switches on, and the in-memory maps that are the only state this daemon keeps (no task files — a restart stops whatever's running; the actual claude session is the durable store, found again by name via hive_claude::SessionStore).
  • mcp.rs — the rmcp tool routers (the parent's start/continue/status/interrupt on /mcp, the subagent's goal_reached/need_help on /signal/mcp/<token>) + serve_http. Neither signal tool takes a session name: the token in the path is minted per run and resolved to a session before dispatch, so a subagent has no way to name — and therefore no way to signal — a sibling. One route with a path parameter, because the Router is built once at startup and sessions come and go for the daemon's whole life.
  • paths.rs — the in-agent todo-socket path.