Watch
0
0
Fork
You've already forked hyperhive
0

docs(agents): facts pass on agent-hierarchy.md and mcp.md

mcp.md:
- matrix and subagent extra MCP servers are http (hive-matrix-daemon,
  hive-subagent-daemon), not stdio; screen is the one entry that still
  uses the stdio default (nix/agent-modules/matrix.nix:290-297,
  screen.nix:22-25)
- set_status is always-on, not meta-group-gated; mark_todos_done (also
  always-on) was undocumented (hive-sh4re/src/permissions.rs:151,
  hive-agent-mcp/src/mcp/mod.rs:425)
- System messages: HelperEvent has 3 variants, not the 8 previously
  listed; ApprovalResolved/ContainerCrash routing and the swarm-wide
  NATS notices stream (swarm_notices.rs) replace the old per-agent
  todo-wake description for rebuilt/killed/destroyed/logged_in/needs_login
- get_loose_ends's approval rows are manager-only; PendingMessages and
  UnreadMatrix were missing from the description
  (hive-sh4re/src/inbox.rs:127-184)
- subagent spawning runs on hive-runtime (claude or ACP), not
  claude-only (hive-subagent-mcp/src/session.rs:77)
- Waking section: matrix/bash/forge all moved to the in-agent todo
  socket; the host Wake request has no built-in caller left today

agent-hierarchy.md:
- distinguished the swarm-wide agent roster (swarm-controller's
  identity store, authoritative) from the hive-local topology.json
  (a derived, reconciled cache scoping ManageRootAgent's bind-mounts),
  linking README's framing
- noted services.hyperhive.ruthless (a hive can run with no manager at
  all)
- Wire-protocol bullet: the only privileged Request variants left are
  the scheduling ops; Kill/Start/Restart/Update/GetLogs don't exist on
  this socket
- Prompt/tools: prompt::render hardcodes the agent role for every
  container today (role:manager blocks are dead code); the tool
  allow-list has no Flavor switch, it's HIVE_TOOL_GROUPS same as any
  agent

Not touched: agent-hierarchy.md:140-200 (Harness systemd unit shape,
kept in place — see PR follow-ups) and docs/agent-lifecycle/approvals.md
(blocked on #4853).
This commit is contained in:
atlas 2026-10-02 00:14:17 +02:00 • committed by mara
commit 4e31550dad
2 changed files with 129 additions and 71 deletions

View file

@ -9,10 +9,14 @@ URL survives the per-turn claude re-spawn (and a host-side hive-c0re
restart) — there is no per-turn MCP re-registration race for the
built-in surface. HTTP is the sole transport for it (no stdio fallback).
Extra servers (`services.hyperhive.agent.extraMcpServers`) pick their own transport per
entry (`type = "stdio" | "http"`, default `"stdio"`): `matrix` stays a
stdio bridge, `bash` runs its own persistent streamable-http listener
(`hive-bash-daemon`) — same reasoning as the built-in surface. The
server name is `hyperhive`, so the tools land in claude as
entry (`type = "stdio" | "http"`, default `"stdio"`): `matrix` and
`subagent` each run their own persistent streamable-http listener
(`hive-matrix-daemon`, `hive-subagent-daemon`), same reasoning as the
built-in surface and `bash`'s `hive-bash-daemon`. The GUI bridge
(`screen`, gated on `services.hyperhive.agent.gui.enable`) is the one
entry that still takes the schema's stdio default — it spawns
`hive-screen-mcp` fresh each turn. The server name is `hyperhive`, so
the tools land in claude as
`mcp__hyperhive__<tool>`. Each entry also has an `availableToSubagents`
toggle (default `false`) — see
[`docs/tools/subagent.md`](../tools/subagent.md#mcp-servers-available-to-a-subagent)
@ -56,32 +60,43 @@ are opt-in via the P3RM1SS10NS tab.
`ack_until(N)` to prevent re-pop. Acked rows never redeliver.
Transient pings (sentinel id 0) have nothing to ack and show no marker.
**System messages** (from sender `system`): the broker delivers the
higher-urgency lifecycle events (`hive_sh4re::manager::HelperEvent`)
as regular inbox messages (same `recv` path; body is a JSON
object with an `event` discriminant field). The **submitting agent**
(the root agent for top-level containers; an agent with the `approvals`
tool group for its own subtree) receives `container_crash`,
`needs_update`, and `approval_resolved` this way. The remaining, lower-urgency lifecycle
notices — `spawned`, `rebuilt`, `killed`, `destroyed`, `needs_login`,
`logged_in` — skip the inbox entirely: they land as
todos on the submitting agent's in-container todo socket instead
(`Coordinator::push_todo`/`push_todo_submitter`, `subsystem = "core"`),
which still wakes a turn (the todo-wake path — see [Turn
outcomes](README.md#turn-outcomes)) but via a generic "call
`get_loose_ends`" prompt rather than the event body itself. Full
payload shapes and routing logic in
[`docs/agent-lifecycle/approvals.md` § Helper events](../agent-lifecycle/approvals.md#helper-events-to-the-submitting-agent).
**System messages** (from sender `system`): the broker delivers
`hive_sh4re::manager::HelperEvent` (three variants: `ApprovalResolved`,
`ContainerCrash`, `NeedsUpdate` — the last declared but constructed by
no call site today) as regular inbox messages (same `recv`
path; body is a JSON object with an `event` discriminant field).
`ApprovalResolved` goes to whichever agent actually submitted the
approval (`Coordinator::notify_submitter`, looked up from the
authenticated socket caller at submit time; a legacy row with no
recorded submitter falls back to the manager, `ruth`).
`ContainerCrash` always goes to `ruth` (`Coordinator::notify_manager`,
hardcoded — `hive-c0re/src/workers/crash_watch.rs`). A `MergeConfigPr`
approval's rebuild additionally pushes a `rebuilt:<agent>` todo to that
same submitter (`Coordinator::push_todo_submitter`, `subsystem =
"core"`), which still wakes a turn (the todo-wake path — see [Turn
outcomes](README.md#turn-outcomes)) via a generic "call
`get_loose_ends`" prompt rather than the event body itself. Lifecycle
transitions the job-queue scheduler or crash watcher drive directly —
stop/kill, destroy, a flake-rev login or logout state change — reach
no individual agent any more: they publish onto a swarm-wide NATS
JetStream stream instead (`swarm_notices::notify`,
`hive-c0re/src/swarm_notices.rs`), since every hive is swarm-controlled
now and there is no manager-agent fallback left to push an in-container
todo to.
**Inbox** (`inbox` group): `get_loose_ends()`,
`cancel_loose_end(kind, id)`, `remind(message, delay_seconds? |
at_unix_timestamp?)`.
- `get_loose_ends()` — list scheduled reminders, pending approvals you
submitted, and active local tasks published by external MCP daemons
(for example running bash tasks from `hive-bash-daemon`). Each row
carries an id + kind for `cancel_loose_end`. Always your own threads —
there is no way to target another agent.
- `get_loose_ends()` — list this agent's own open threads: pending
reminders, open todos pushed by an in-container subsystem (matrix,
bash, forge, or any user-configured MCP server), an undelivered-inbox
count, and unread matrix notifications; `approval` rows only appear
when the caller is the manager (`ruth`) — sub-agents don't submit
approvals. Always the caller's own rows — there is no way to target
another agent. Full per-variant wire shape in
[`docs/process/conventions.md` § Loose-ends wire
shape](../process/conventions.md#loose-ends-wire-shape).
- `cancel_loose_end` — hard-delete a `reminder`, cancel a pending
`approval` row, or clear a `todo` row (loose-ends-v2). Agents may
only cancel rows they own; the `approval` kind is further restricted
@ -96,11 +111,8 @@ No same-turn self-continue tool exists — see
(bash-task completion, forge notification, matrix activity) for work
already in flight.
**Meta** (`meta` group): `set_status(text)`, `get_agent_meta(name?)`.
**Meta** (`meta` group): `get_agent_meta(name?)`.
- `set_status` — set a free-text status string visible on the
dashboard. Single line, ≤ 200 chars. Persisted to
`{state_dir}/hyperhive-status`. Pass `""` to clear.
- `get_agent_meta` — fetch identity + status metadata for an agent:
`{ name, hyperhive_rev, running, status_text, status_set_at,
hive_name?, swarm_name?, matrix_accounts? }`. `matrix_accounts` is a
@ -108,8 +120,14 @@ hive_name?, swarm_name?, matrix_accounts? }`. `matrix_accounts` is a
`homeserver`); omitted for agents with no matrix provisioning. Omit
`name` to query self.
**Always-on, no tool group** (like `set_status`): `compact()`.
**Always-on, no tool group**: `set_status(text)`, `compact()`,
`mark_todos_done(ids)`.
- `set_status` — set a free-text status string visible on the
dashboard. Single line, ≤ 200 chars. Persisted to
`{state_dir}/hyperhive-status`. Pass `""` to clear. Not gated by the
`meta` group — every agent needs to keep its dashboard status chip
current regardless of which optional groups it holds.
- `compact` — agent self-service equivalent of the operator dashboard's
`/compact` button. No args. Gated server-side on the last completed
turn's context usage: refused (with an explanation, no side effect)
@ -120,14 +138,21 @@ hive_name?, swarm_name?, matrix_accounts? }`. `matrix_accounts` is a
notes-checkpoint turn still fires first. Dispatched through the
in-agent socket (`hive-agent-sock::Request::Compact`), not the
broker — see `hive-agent/src/todo_server.rs`.
- `mark_todos_done(ids)` — bulk-clear specific loose-ends-v2 todo rows
by id in one call, instead of `cancel_loose_end`ing each one.
List-based, not range-based (no `ack_until`-style "clear below id
N"): pass the ids `get_loose_ends` actually showed you reviewed;
unknown or already-done ids are silently skipped. Dials the same
in-agent todo socket as `cancel_loose_end`'s `todo` kind.
## Privileged tools (by tool group)
- **Bash execution** (`execution`) — background shell tasks. See
[`docs/tools/bash.md`](../tools/bash.md).
- **Subagent spawning** — headless claude sub-instances as background
tasks, shipped default-on like bash execution (no tool group gates it
yet). See [`docs/tools/subagent.md`](../tools/subagent.md).
- **Subagent spawning** — nested sessions on the agent's own runtime
(claude or ACP, via `hive-runtime`) as background tasks, shipped
default-on like bash execution (no tool group gates it yet). See
[`docs/tools/subagent.md`](../tools/subagent.md).
- **Lifecycle + config** (`lifecycle`, `approvals`) — neither group
carries an MCP tool any more: `list_containers` and
`request_update_meta_inputs` no longer exist, with no
@ -153,23 +178,23 @@ hive_name?, swarm_name?, matrix_accounts? }`. `matrix_accounts` is a
## Waking the agent from inside the container
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`. Speak the wire protocol directly —
JSON-line over the unix socket: `{"cmd":"wake","from":"matrix","body":
"new dm from @alice"}\n`. Same shape as any other request on this
socket; see `hive_core_agent_sock::Request::Wake`. Every built-in producer that wakes
the harness (matrix, bash) dials the socket directly — there is no
CLI wrapper, just the raw protocol.
The built-in producers (matrix, bash, forge) no longer dial a direct
wake — all three now upsert a todo on the harness's in-agent socket
(`HIVE_AGENT_SOCKET`, `UpsertTodo`, see [Inbox](#core-tools-always-available)
above): a new or changed summary makes the harness signal its own turn
loop, with no hive-c0re round-trip. An external MCP server (or any
other in-container process) can push its own todo the same way —
`subsystem` is a plain string, not a closed set.
The wake event lands in the broker as `{from:<label>,
to:<agent>, body}`, waking whatever `recv` call the harness
is currently blocked on. The next turn fires with the wake
prompt formed from that message.
Identity = socket: anything that can connect to
`/run/hive/mcp.sock` is implicitly trusted to inject these —
the bind-mount is the agent's own container only.
The host-served per-agent socket at `/run/hive/mcp.sock` still carries
a lower-level `Wake` request (`hive_core_agent_sock::Request::Wake {
from, body }` — JSON-line, `{"cmd":"wake","from":"matrix","body":"new dm
from @alice"}\n`) that drops the body straight into the broker inbox as
`{from:<label>, to:<agent>, body}`, bypassing the todo layer entirely.
`hive-c0re` still handles it, but no built-in producer
calls it today. Identity = socket: anything that can connect to
`/run/hive/mcp.sock` is implicitly trusted to inject one — the
bind-mount is the agent's own container only.
## Authoritative state