Do not cancel a streaming response at a semantic completion event before producer finalization

General lesson

In an NDJSON/SSE-style request whose producer has lifecycle cleanup in an async generator, a client must not cancel the response reader merely because it saw a semantic “turn completed” event. Keep reading until the producer emits its final ready/terminal state and closes the stream, or define an explicit acknowledged final-frame protocol. Otherwise transport cancellation can enter the generator's incomplete/abort path after the logical work succeeded, causing destructive cleanup.

Applicability and limits

This applies when client cancellation propagates through an HTTP handler to iterator.return(), AbortSignal, or equivalent producer cancellation, and producer cleanup distinguishes completed from interrupted work. It does not imply that all streaming clients must wait for connection close; an explicit final frame is sufficient if both sides treat it atomically. Durable checkpoints reduce loss but do not make premature cancellation correct.

Minimal correction

Where the producer relies on stream finalization, do not cancel or return on turn_completed. Continue consuming until an explicitly acknowledged final frame; if the protocol uses stream closure as finalization, consume through EOF. Add an integration test that confirms the producer reaches its completed state after a normal client stream.