remove hive and agent apis nothing calls: build-log routes, /api/compact, host.sock list, mcp.sock wake
This commit is contained in:
parent
cbfd7b2174
commit
36c7781245
9 changed files with 115 additions and 801 deletions
|
|
@ -152,13 +152,12 @@ Capturing the full stream (rather than a short tail buffer) matters
|
|||
because real eval errors routinely run long — "tried alternatives"
|
||||
blocks alone are often 30+ lines — so a truncated tail would cut off
|
||||
the actual failure and leave only the host journal holding the
|
||||
complete output. With this table the dashboard can surface the entire
|
||||
log.
|
||||
complete output. This table holds the entire log; no HTTP route serves
|
||||
it.
|
||||
|
||||
Three indices:
|
||||
|
||||
- `(agent, started_at)` — backs the per-agent latest-N lookup used
|
||||
by the agent card chip.
|
||||
- `(agent, started_at)` — per-agent lookup by recency.
|
||||
- `(status, finished_at)` — backs the retention sweep that runs
|
||||
as part of the existing hourly vacuum.
|
||||
- `(node_id)` — added by a later migration so a build log row can be
|
||||
|
|
|
|||
|
|
@ -101,10 +101,8 @@ state dirs work as for every other agent.
|
|||
- **Wire-protocol** — `hive-core-agent-sock`'s unified `Request` enum
|
||||
is the same on both socket flavours. Container lifecycle
|
||||
ops (kill/start/restart/rebuild) go through the separate host-admin
|
||||
socket `hivectl` speaks. `Wake` (inject a `from: <X>` message straight
|
||||
into the caller's own inbox) is on this socket too, unprivileged on
|
||||
both flavours; matrix, bash and forge don't call it — their
|
||||
notifications push a todo on the harness's in-agent socket (see
|
||||
socket `hivectl` speaks. Matrix, bash and forge wake the agent by pushing a todo on the
|
||||
harness's in-agent socket (see
|
||||
[`docs/4-implementation/turn-loop/mcp.md`](../turn-loop/mcp.md#waking-the-agent-from-inside-the-container)).
|
||||
- **Storage/mounts** — the `manage_root_agent` permission, which the
|
||||
[`ruth` archetype](../../2-handbook/swarm/archetypes.md#the-built-in-archetypes) grants, gets a container
|
||||
|
|
|
|||
|
|
@ -8,9 +8,8 @@ Its own long-running per-agent daemon (`hive-forge-notify`, a sibling of
|
|||
`hive-bash-daemon` / `hive-matrix-daemon`) — it used
|
||||
to be a background task inside the `hive-agent` serve loop. Polls
|
||||
`GET /api/v1/notifications?all=false` every 30 seconds (Forgejo's
|
||||
unread-only filter), formats each notification as a broker
|
||||
`Wake { from: "forge" }` message, and delivers it to the agent's own
|
||||
inbox so claude's normal turn loop picks it up.
|
||||
unread-only filter), formats each notification as a todo and pushes it to the agent's own
|
||||
in-agent socket so claude's normal turn loop picks it up.
|
||||
|
||||
The daemon waits about ten minutes for the agent's forge token, then exits 0,
|
||||
which its `Restart=on-failure` doesn't restart. A path unit
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ Solution: an `nginx http`-context `map $http_accept $matrix_spa_target { ... }`
|
|||
|
||||
hive-c0re serves exactly two prefixes, so the dashboard routes by **path** — deterministic, where a content-type split would let one URL resolve differently by the caller's `Accept` header:
|
||||
|
||||
- `location /api/` → hive-c0re (`7000`): all dashboard data, actions, and the two SSE streams (`/api/dashboard/stream`, `/api/build-logs/id/{id}/stream`). `proxy_buffering off` and a 1d read timeout keep the streams live.
|
||||
- `location /api/` → hive-c0re (`7000`): all dashboard data, actions, and the SSE stream (`/api/dashboard/stream`). `proxy_buffering off` and a 1d read timeout keep the stream live.
|
||||
- `location /health/` → hive-c0re: liveness and readiness.
|
||||
- `location /` → the dashboard dist (from the `servedFrontend` nix-store path) with `try_files $uri /index.html`.
|
||||
|
||||
|
|
|
|||
|
|
@ -172,12 +172,12 @@ best-effort — a failed checkpoint or `/compact` never fails the turn that
|
|||
already succeeded. An ACP agent gets the same policy; how it compacts is in
|
||||
[`hive-runtime/README.md`](../../../hive-runtime/README.md#acp-backend-compaction).
|
||||
|
||||
The operator can force a compaction any time via `POST /api/compact`. It's
|
||||
**deferred**: the handler sets `Bus::request_compact()` and returns
|
||||
The agent can force a compaction via its `compact` MCP tool. It's
|
||||
**deferred**: the tool sets `Bus::request_compact()` and returns
|
||||
immediately; the harness runs the `/compact` at the next turn boundary
|
||||
(end of the in-flight turn in `drive_turn`, or — when the agent is idle —
|
||||
in `turn::run_pending_compact` on the serve loop's next empty poll). This
|
||||
lets `/api/compact` work mid-turn instead of only when idle, without racing
|
||||
lets the request work mid-turn instead of only when idle, without racing
|
||||
a live claude process.
|
||||
|
||||
To disable proactive compaction for a specific agent, use the nix option:
|
||||
|
|
|
|||
|
|
@ -102,12 +102,12 @@ hive_name?, swarm_name?, matrix_accounts? }`. `matrix_accounts` is a
|
|||
`{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
|
||||
- `compact` — queues a compaction of the current session; the only way to
|
||||
request one. No args. Gated server-side on the last completed
|
||||
turn's context usage: refused (with an explanation, no side effect)
|
||||
unless usage is above 66% of the effective context window. On a
|
||||
pass, queues the same deferred `compact_pending` flag the dashboard
|
||||
button sets — consumed at the end of the current turn, so it never
|
||||
pass, queues the deferred `compact_pending` flag — consumed at the end
|
||||
of the current turn, so it never
|
||||
races a live claude process, and the usual pre-compaction
|
||||
notes-checkpoint turn still fires first. Dispatched through the
|
||||
in-agent socket (`hive-agent-sock::Request::Compact`), not the
|
||||
|
|
@ -159,15 +159,6 @@ 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 any string.
|
||||
|
||||
The host-served per-agent socket at `/run/hive/mcp.sock` 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` handles it; matrix, bash and forge don't call it. 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
|
||||
|
||||
`hive-agent`'s `events::Bus` carries the current turn-loop state in
|
||||
|
|
@ -175,7 +166,7 @@ addition to the broadcast channel and the events history. Variants:
|
|||
|
||||
- `Idle` — sitting on `Recv` waiting for mail.
|
||||
- `Thinking` — `claude --print` is running for a turn.
|
||||
- `Compacting` — operator-triggered `/compact` is in flight.
|
||||
- `Compacting` — a `/compact` is in flight.
|
||||
|
||||
The harness flips state at the relevant transitions
|
||||
(`set_state(Thinking)` before `drive_turn`, `set_state(Idle)`
|
||||
|
|
|
|||
|
|
@ -233,20 +233,19 @@ The state badge's menu carries the actions on the agent's claude:
|
|||
credential files, parks the agent in `needs_login`, and preserves
|
||||
session history (`~/.claude/projects/`).
|
||||
|
||||
`POST /api/compact` sets the deferred `Bus::request_compact()` flag and
|
||||
The agent's `compact` MCP tool sets the deferred `Bus::request_compact()` flag and
|
||||
returns immediately. The harness runs the `/compact` at the next turn
|
||||
boundary (end of the in-flight turn, or `turn::run_pending_compact` when
|
||||
idle); output streams into the live panel, which ends with a `/compact done`
|
||||
or `/compact failed: …` note. It works mid-turn, not only when idle. Nothing
|
||||
on this page calls it now.
|
||||
or `/compact failed: …` note. It works mid-turn, not only when idle.
|
||||
|
||||
## Per-agent endpoints
|
||||
|
||||
Successful POSTs return 200 (no 303 redirects). Error responses
|
||||
use semantic status codes: **400** for missing/malformed input
|
||||
(`/api/todos/mark-done` with no todo ids), **500** only for genuine
|
||||
server/transport failures. `/compact` never conflicts: it queues
|
||||
and runs at the end of the current turn. The matching
|
||||
server/transport failures. A queued `/compact` never conflicts: it
|
||||
runs at the end of the current turn. The matching
|
||||
mutations fire `LiveEvent` variants on the per-agent bus, so the
|
||||
client doesn't refetch `/api/state` on submit — the SSE stream
|
||||
delivers the new state faster anyway.
|
||||
|
|
@ -257,11 +256,6 @@ credentials arrive from the swarm secret store.
|
|||
|
||||
- `POST /api/cancel` — SIGINT the in-flight claude turn and the
|
||||
commands it started. Emits a `LiveEvent::Note`.
|
||||
- `POST /api/compact` — run `/compact` on the persistent session
|
||||
(same MCP config + system prompt + allowed tools as a normal
|
||||
turn — only the stdin payload differs). Flips state to
|
||||
`Compacting` via `Bus::set_state`, which emits
|
||||
`TurnStateChanged`.
|
||||
- `POST /api/new-session` — arm a one-shot for the next turn to
|
||||
drop `--continue`. Emits a `LiveEvent::Note`.
|
||||
- `POST /api/logout` — three-step teardown that re-uses the
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ conflicting agent.
|
|||
|
||||
Passive / rare-interaction state. `kept.js` renders it from the
|
||||
`/api/state` snapshot and keeps it live from the `tombstones_changed`
|
||||
stream event. (The rebuild queue and build logs are dashboard tabs too —
|
||||
stream event. (The rebuild queue is a dashboard tab too —
|
||||
see below.)
|
||||
|
||||
Per-container CPU, memory and disk load isn't shown in the hive UI. The
|
||||
|
|
@ -433,27 +433,6 @@ below — some endpoints aren't in it yet.
|
|||
not yet delivered and sets `acked_at = now`. Returns
|
||||
`{ "marked": N }`. Agent name validated against
|
||||
`[a-z0-9_-]`, 1-63 chars; 400 on bad input.
|
||||
- `GET /api/build-logs?limit=N` — most-recent build log headers across
|
||||
all agents (`limit` defaults to 30).
|
||||
- `GET /api/build-log/{node_id}` and `/api/build-log/{node_id}/raw` — the
|
||||
build log of one job-queue node, as JSON and as `text/plain`.
|
||||
- `GET /api/build-logs/{agent}?limit=N` — most-recent build log
|
||||
headers for one agent, newest first. Returns
|
||||
`Vec<BuildLogHeader>` (JSON): `id`, `agent`, `kind`, `cmdline`,
|
||||
`started_at`, `finished_at`, `status` (`"ok"` / `"fail"` /
|
||||
`null` while in-progress). `limit` defaults to 10, server-side
|
||||
cap at 50. Agent name validated (`[a-z0-9_-]`, 1-63 chars).
|
||||
- `GET /api/build-logs/id/{id}` — full build log by id. Returns
|
||||
`BuildLogFull` (JSON): all header fields plus `stdout` and
|
||||
`stderr` as plain text (newline-terminated lines, utf-8). HTTP
|
||||
404 when the row is missing (vacuum-reaped or stale id).
|
||||
- `GET /api/build-logs/id/{id}/stream` — live SSE stream of
|
||||
stdout+stderr for an in-progress build (newline-delimited JSON
|
||||
frames). The
|
||||
stream closes when the build finishes or errors.
|
||||
- `GET /api/build-logs/id/{id}/raw` — raw concatenated
|
||||
stdout+stderr as `text/plain`. Works on both finished and in-progress
|
||||
build logs.
|
||||
|
||||
- `GET /api/dashboard/stream` — unified live event channel:
|
||||
broker `sent` / `delivered`, plus the mutation events listed
|
||||
|
|
|
|||
|
|
@ -66,24 +66,17 @@ No auth tokens exist on the per-agent unix sockets. The socket
|
|||
bind-mount." A sub-agent only sees its own `/run/hive/mcp.sock`;
|
||||
hive-c0re owns the host admin socket.
|
||||
|
||||
### Wake injection
|
||||
|
||||
`hive_core_agent_sock::Request::Wake { from, body }` is the
|
||||
wake-event-injection surface on the host-served per-agent socket.
|
||||
Recipient is implicit — the agent the socket belongs to — and `from`
|
||||
is caller-chosen so the wake prompt can label the source verbatim
|
||||
(`"matrix: new message in #general"`, `"forge: PR #42 opened"`, etc.). <!-- lint:allow: example strings, not real tags -->
|
||||
`hive-c0re` handles it; matrix, bash and forge don't call it — their
|
||||
notifications upsert a todo on the harness's in-agent socket
|
||||
(`HIVE_AGENT_SOCKET`), which signals the same turn loop without a
|
||||
Matrix, bash and forge wake the agent by upserting a todo on the harness's
|
||||
in-agent socket (`HIVE_AGENT_SOCKET`), which signals the turn loop without a
|
||||
hive-c0re round-trip. See
|
||||
[`docs/4-implementation/turn-loop/mcp.md` § Waking the agent from inside the
|
||||
container](../../4-implementation/turn-loop/mcp.md#waking-the-agent-from-inside-the-container).
|
||||
The host-served `/run/hive/mcp.sock` has no verb that injects a message into
|
||||
the agent's own inbox.
|
||||
|
||||
Identity = socket means anything that can connect to
|
||||
`/run/hive/mcp.sock` is implicitly trusted to inject wakes. That's
|
||||
fine: the bind-mount only exposes the socket inside the agent's own
|
||||
container, so the trust boundary is the container's process
|
||||
Anything that can connect to `/run/hive/mcp.sock` is implicitly trusted to
|
||||
call its verbs. That's fine: the bind-mount only exposes the socket inside the
|
||||
agent's own container, so the trust boundary is the container's process
|
||||
namespace, not the wire surface.
|
||||
|
||||
## Recipient sentinels
|
||||
|
|
|
|||
Loading…
Reference in a new issue