5a3b593230
A message typed while a turn streamed rendered ABOVE assistant output the user had already watched arrive (#73793), and the retired insert-before-the-active-reply fallback could splice the bubble mid-thread — halfway up the chat — when the stream id was missing or stale (#83151). Fix the class at every path that assigns a transcript position to a mid-turn user message: - New shared appendMidTurnUserMessage (rewind.ts): seal the live stream bubble in place (interim), append the correction at the live tail, and clear streamId so post-redirect deltas seed a fresh bubble BELOW the correction. Used by both the primary composer redirect path (use-prompt-actions) and the session-tile steer path (session-tile-actions), replacing the insert-before splice and its last-assistant mid-thread fallback. - appendLiveSessionProjection now projects the resume/reload turn in arrival order (prompt → streamed output → correction → post-redirect output) instead of prompt → corrections → reply, so the projection agrees with the live transcript and messages no longer jump upward on reconnect. With the gateway's new correction_offsets the flat dump is split at each accepted-correction boundary; without offsets the corrections follow the projected reply. - tui_gateway/server.py records correction_offsets (assistant text length at each accepted correction) on the inflight turn and carries them in _inflight_snapshot, only when complete, so resume can rebuild true arrival order. Older gateways/clients degrade cleanly. - preserveLocalPendingTurnMessages and the projection's latest-user-run matcher now treat a live-tail assistant row between the prompt and its correction as part of the same turn's run, so arrival-ordered runs survive refreshes without dropping the prompt. Fixes #73793. Fixes #83151.