The input no longer closes before the turn has begun. When an earlier turn on the same session was stopped while a background task it started was still running, the CLI on resume first answers that leftover task notification. That answer is a "stamped" result. The bridge took it as "the main assistant is idle" and closed the turn's input before the assistant had even read its opening message. The turn then ran on, sometimes for half an hour, and every message sent to it was refused with turn_ending.
Now a turn's input stays open, and main_state stays working, until the opening message has been taken in: its echo has arrived, or an unstamped result has (for a CLI that does not echo). A stamped result before that is still recorded, but no longer ends anything.
input_closed. The bridge now says when it closes a turn's input while the turn keeps running, instead of revealing it only by refusing:
{"type":"stream","request_id":"…","event":"input_closed","data":{"reason":"idle"}}After it, a turn_input is answered turn_ending. It is advertised as hello.input_closed: true, and servers must accept reasons other than idle. Additive; no protocol bump.
Foreground helpers. A message accepted while the main assistant is blocked on a foreground helper is written at once and read after the helper's call returns. This is now tested against a captured turn and documented in PROTOCOL.md.
Servers on laravel-ai-bridge 0.16.0+ or Engram can move machines to this with desired_bridge_version: "0.25.0".