Two paths ended a streaming advance without a terminal `state`/`error`
frame, leaving the SSE client stalled to the deadline with a stale held
version -> its next action 409s:
1. advance_session published the terminal `state` frame outside the
try/finally and unguarded. If the post-advance view projection
(get_session_view -> read_graph) or the publish itself raised after a
SUCCESSFUL advance, the exception escaped and no terminal frame was
sent. Guard it and fall back to a terminal `error` frame.
2. submit_action_stream emitted a terminal `state` frame on settle only
for `message`. `update_model` also settles synchronously while bumping
the version, so it now emits one too -- otherwise the FE keeps the old
version and 409s on its next action.
Adds regression tests for both (projection-failure -> error frame;
update_model -> state frame).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>