remove request_next_turn: same-turn continuation is always worse than an external wake

This commit is contained in:
damocles 2026-07-27 22:07:40 +02:00 committed by mara
commit fffe0a2c29
8 changed files with 103 additions and 253 deletions

View file

@ -12,10 +12,8 @@ agents) runs:
loop does nothing but re-stat it every 5 s — no broker poll, no
claude process. Because step 1 is never reached, messages stay
queued and unacked, so a resume drains the backlog instead of
losing it; reminders and todo wakes buffer in their channels. The
check runs before the self-continue slot is consumed, so a pending
`request_next_turn` survives the pause. Set it with
`hivectl agent <name> pause` or the dashboard toggle; see
losing it; reminders and todo wakes buffer in their channels. Set
it with `hivectl agent <name> pause` or the dashboard toggle; see
[persistence](persistence.md#-harnesspaused-per-agent).
1. Long-poll `Recv` on its socket. The host-side broker
(`broker.rs::recv_blocking_batch`) returns immediately if there's
@ -141,21 +139,17 @@ only complete output silence for the window trips it. The harness sets the
window from `HIVE_TURN_IDLE_SECS` (`0` disables) and maps the driver's
`Error::IdleTimeout` onto `TurnError::ApiStall`.
After the outcome handler, the stats sink records a row and the
`hyperhive-continue` sentinel (dropped by the `request_next_turn`
MCP tool) is consumed if present. `handle_turn` reports the result
to `serve_loop` via `TurnControl { auth_failed, continue_requested,
pending }`. When a continue was requested, the turn did not
auth-fail, and the inbox is empty (`pending == 0`), `serve_loop`
drives the next turn in-process with a synthetic
`{ from: "self", body: "continue" }` message (`synthetic_continue`)
— it never goes through the broker, so the self-continue doesn't
persist to sqlite or show up as a recv'able inbox message. If real
messages are already pending the continue is dropped: those messages
drive the next turn(s) via `recv_next`, so an explicit self-wake
isn't needed (this is the `request_next_turn` contract — "no effect
if a new inbox message arrives before this turn ends"). The
`should_self_continue` predicate encodes exactly that decision.
After the outcome handler, the stats sink records a row. `handle_turn`
reports the result to `serve_loop` via `TurnControl { auth_failed }`
on auth failure the loop parks in `wait_for_login`; otherwise it loops
straight back to the idle wait (step 1). There is no same-turn
self-continue tool (removed — see forge #2777): every multi-step
continuation rides an external wake instead — a new inbox message, a
`remind`, or an in-container todo wake (bash-task completion, forge
notification, matrix activity). Ending the turn and letting one of
those drive the next one is strictly better than parking in-process:
it checkpoints the session and observes wakes that only reach the
harness between turns.
## Sub-pages