mirror of
https://github.com/block/buzz.git
synced 2026-10-29 21:41:33 +00:00
Step 2 of PLANS/BUZZ_OPERATIONS_MIGRATION.md. Behaviour is unchanged: the existing stop_hook and real_dev_mcp integration tests pass without modification, which is the point of this step. BuzzStopVetoOperation replaces the inline stop_veto() branch. The loop now runs the gate a second time when a round wants to end, which is where the operation applies -- it declines unless the last message ends the turn, so the top-of-round call is a no-op for it. Two things move rather than change: - The block cap was a loop-local u32 in run_turn; objections now carry a metadata note and the cap counts them since kickoff. run_turn is per session/prompt, so both are turn-scoped -- same three-strikes behaviour, but now a pure function of the conversation, which is why goose tags its own denials the same way. - MAX_STOP_BLOCKS was declared in both loop_drive and hooks with the same value. Dropped the loop_drive copy. Deliberately not goose's StopHookOperation: it drives goose's private HookManager plugin system, while buzz's hook is an MCP tool that can see buzz-dev-mcp's in-process todo state. It also emits a user-facing notification per denial, which in buzz would post 'stop hook blocked ending this turn' into a channel every time an agent had an open todo. The objection reaches the model, not the room. 65 unit + 21 integration green, handtest --all 18/18. Signed-off-by: Michael Neale <michael.neale@gmail.com> Co-authored-by: Michael Neale <michael.neale@gmail.com>