Watch
0
0
Fork
You've already forked hyperhive
0

drop the host side of the agent broker send

Remove the agent-side Send and AckUntil requests, their hive-c0re handlers
(handle_send with its 4 KiB size cap, handle_ack_until) and Broker::ack_until.
Everything that existed only for them goes with them: the OkWarn response
(its sole producer was Send's reserved-name warning), Recv's max parameter
and RECV_BATCH_MAX (the harness never asked for more than one message),
OPERATOR_SEND_REFUSAL, and the MESSAGE_MAX_BYTES / check_size limit (the
reminder timer keeps its own copy of the cap, so its comment is reworded).

Messages.remaining stays on the wire (default on read) because a harness
built before this change still requires it. Update the conventions docs.
This commit is contained in:
damocles 2026-11-08 02:35:34 +01:00 • committed by mara
commit 1c3b5e52cf

View file

@ -94,11 +94,9 @@ name validation rejects any character outside `[a-z0-9_-]`, so the
angle-bracket and asterisk shapes below are structurally safe.
- `*` — broadcast: deliver to every running agent except the sender
(`socket_server::handle_send` fans out via `Coordinator::broadcast_send`).
(`Coordinator::broadcast_send`, used by hive-c0re's own system broadcasts).
- `operator` — the human at the dashboard. Reserved so no agent can take
the name, and refused as a recipient: the broker answers a `send` to it
with `OPERATOR_SEND_REFUSAL` (`hive-sh4re/src/manager.rs`). It appears
only as the sender of operator-authored messages.
the name. It appears only as the sender of operator-authored messages.
The broker stores the recipient exactly as the agent passed it.
@ -115,14 +113,10 @@ in `hive-c0re::dashboard_events::DashboardEvent`.
### Broker delivery + ack cycle
`AgentRequest::Recv` is the only path that delivers messages to an
agent. Always returns a list (`Messages { messages }`) — empty when
nothing's pending, single-pop when `max = None` (default 1, the
single-message behaviour), batched up to `max` when caller asks for
more (server-side cap is 5; values above clamp silently). The wire
request still carries an optional `wait_seconds` (long-poll the first
message, once one arrives — or one is already pending — the call
drains up to `max` in total): the harness's own turn-driving loop
uses it internally (`hive-agent`'s `recv_next`, 180s). The
agent. It returns a list (`Messages { messages }`) of zero or one
message: empty when nothing is pending. The request carries an optional
`wait_seconds` (long-poll for the next message); the harness's own
turn-driving loop uses it (`hive-agent`'s `recv_next`, 180s). The
agent-facing MCP surface has no `recv` tool at all.
Per-row bookkeeping inside the broker:
@ -153,21 +147,9 @@ each id in a per-recipient in-memory set so the next `Recv` can tag
the row with `redelivered: true`. Idempotent + cheap when there's
nothing in flight, so the at-boot fire is unconditional.
`AgentRequest::AckUntil { up_to }` is the agent-facing bulk-triage
escape hatch (`mcp__hyperhive__ack_until`). Unlike `AckTurn` **it's**
visible to claude: each recv row and wake prompt carries a
`[msg #<id>]` marker (the broker row id; transient pings show no
marker — their sentinel id 0 has nothing to ack), and
`ack_until(up_to: n)` marks every one of the agent's rows with
`id <= n` handled in a single UPDATE — pending and delivered alike.
This bounds the redelivered-flood cost after a restart: instead of
popping dozens of already-handled messages one turn at a time, the
agent notes the highest id it has seen and acks up to it.
Recipient-scoped (an agent can only ack its own rows); also drains
the in-memory `unacked_ids` / `requeued_ids` bookkeeping below the
cutoff so a later `AckTurn` doesn't double-update and a stale
redelivery tag can't outlive its row. The operator-side sibling is
the dashboard's "mark all read" (unbounded, per-agent).
Agents have no bulk-ack of their own: the harness acks a turn's message
with `AckTurn`. The operator-side bulk action is the dashboard's "mark all
read" (unbounded, per-agent).
### Loose-ends wire shape