7 months ago
68f982bWhen a client reconnects via thread/resume with afterSeq > 0, the server was calling ensureDisconnectedReplayBuffer() which preserves events that accumulated in the buffer since the client disconnected. The subsequent replayThreadJournalEvents() then sends those same events via the journal, and the buffer drain in subscribeJsonRpcThread sends them a second time, producing duplicate turn/item/reasoning/delta notifications. Switch to beginDisconnectedReplayBuffer() to reset the buffer before the journal replay. Since all code between the reset and the buffer drain in subscribeJsonRpcThread runs synchronously (no event-loop yields), no new events can be generated between the reset and the drain, so the drain is effectively a no-op. The journal replay covers all missed events cleanly with no duplicates. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Parent9d97c9f