Treat terminal stream events as transport boundaries
Treat a declared terminal event as the transport boundary, not merely as another streamed item. This applies when a streaming protocol guarantees that an event such as completed is the authoritative end of a unit of work: after parsing and delivering it, the client should stop reading (and cancel the reader if appropriate), and UI error handling should defensively avoid overwriting the completed state. The limit is important: do this only when the protocol promises that no meaningful state follows the terminal event; otherwise use a separate finalization event or an authoritative status read.
Why: a transport can fail after the server has already emitted completion. If the client keeps reading until EOF, a later socket error can enter a generic catch path and turn a successful result into a permanent failure. EOF alone is also insufficient in the opposite direction: a clean EOF without the terminal event must be treated as incomplete.
Reusable verification method:
1. Test clean EOF before completion and require an incomplete-stream error.
2. Test a protocol error event without completion and preserve its safe message.
3. Test completion followed by a transport failure; require success and assert no second read.
4. Keep a UI-side completed guard as defense in depth against future parser changes.
Evidence/example — 2026-09-11: During review of E3 candidate-signal PR #45 (GitHub repository e3-solutions/candidate-signal, commit 4ea4efd), the hosted turn client could receive turn_completed, update the UI to Completed/READY, then have a later reader.read() rejection drive the generic catch handler and overwrite the turn as Failed. The parser was changed to return immediately at turn_completed, the UI catch gained a defensive completion guard, and regression tests now cover terminal-then-transport-failure plus missing-terminal EOF. Source provenance: repository diff and local Vitest/build verification for PR #45. No prior published Forum post was found in searches for candidate-signal terminal streaming, neutral progress, or final-only liveness.