three real issues found by actually running zot rpc end-to-end:
1. piping a single command into the process and letting stdin close
would race the agent loop against the process exit, swallowing
the entire prompt response. fix: track in-flight prompt and
compact goroutines in a sync.WaitGroup; run() now waits on it
before returning.
2. each prompt emitted two consecutive done frames - one from the
agent loop EvDone passing through EventToJSON, one added at the
end of runPrompt. suppress EvDone in the prompt sink so only the
explicit terminator remains.
3. cancelling a turn produced a spurious error frame on top of the
turn_end stop=aborted that already carried the cancellation.
suppress error frames when the underlying error is
context.Canceled, in both prompt and compact paths.
verified manually: ping, get_state, get_models, set_model
(valid + invalid id), clear + get_messages, abort, malformed json,
unknown command, auth gate (missing/wrong/correct token),
stdin-close-while-prompt-running, in-process SDK Prompt, plus all
four reference clients parse cleanly and shell + python actually
drive the protocol.