v0.9.2
A focused performance release for the chat turn path, plus a concurrency fix it surfaced.
Performance
Coalesced fsyncs in the run replay log. The per-run replay log previously forced a physical disk barrier (fsync) on every streamed event — including each text token-delta — costing ~4ms apiece and ~0.8s of pure fsync overhead on a 200-event turn (~2s on a 500-event turn). It now flushes every event to the OS (preserving mid-run reconnect/replay correctness, since a reconnecting client gap-fills by reading the log from disk) but physically syncs only on resume-relevant events (tool calls, results, terminal) or once per 250ms. Close does a final sync so cleanly-closed runs stay fully durable. Worst case on a hard crash is the loss of cosmetic trailing text-deltas already delivered live to the client — no resume-relevant event is ever at risk.
Fixes
Duplicate terminal-event race in Run.Subscribe. The faster timing unmasked a latent race: a reconnect landing in the window between Finish writing the terminal event to disk and its later fan-out could receive that event twice (once from the disk-read history, once live) and leak a blocked forwarder goroutine. Subscribe now honors the run's closed state under the run mutex — returning the complete history plus an already-closed live channel without registering a subscriber — so the terminal event is delivered exactly once.