Repository navigation
fix(server): managed Codex refreshes after sign-out even when a check was interrupted - #14376
Conversation
… was interrupted The managed Codex provider refreshes its snapshot whenever the ChatGPT auth controller settles (idle, succeeded, failed, cancelled). An account check runs its runtime resolution inside the controller's withAccess scope, and sign-out closes those scopes. When sign-out lands while a check is still resolving, that check's refresh fails with an interrupt, the refresh loop's fiber dies with it, and the idle state that sign-out publishes next is never turned into a refresh. The snapshot keeps reporting the signed-out account. This is what made CodexDriver.test.ts time out about one run in four: the startup and sign-in listener checks usually finish before logout, but under load one is still resolving when logout closes its scope. Ignore (and log) a failed refresh inside the listener so the subscription keeps running. The test now interrupts both startup checks deterministically, so it hangs every time without the fix. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — The PR is a small, well-tested fix that keeps the managed Codex authentication snapshot listener alive when sign-out interrupts an in-flight refresh. Because it changes production authentication-state handling, human review is warranted. You can add or adjust custom eligibility rules. Learn more. |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: unavailable · PR result: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
8297ccf
into
t3code/codex-turn-mapping
CodexDriver.test.ts > disconnect refreshes a restored managed account while its auth flow is idletimed out at 120 s about one run in four. The cause is a real production bug, not test-state leakage. When sign-out lands while an account check is still resolving, managed Codex never refreshes its snapshot after sign-out, so it keeps showing the signed-out account.Cause
makeManagedCodexProviderrefreshes the snapshot from a listener on the ChatGPT auth controller (idle/succeeded/failed/cancelled,CodexManagedProvider.ts:210). Each account check resolves the runtime inside the controller'swithAccessscope, andlogoutcloses every such scope (stopOwnedSessions,ProviderAuthFlow.ts). If a check is still resolving when sign-out starts:snapshot.refreshfails with an interrupt. That's the interrupt of thewithAccesschild fiber, surfaced throughFiber.await.Stream.runForEachpropagates that failure, so the forked listener fiber ends for good.idle, but no listener is left to refresh.streamChangesnever emitsunauthenticated, and the test waits forever.I confirmed this with temporary tracing on a hung run:
sub refresh exit Failure Cause([Interrupt])→SUBSCRIPTION ENDEDright afterlogout, then nothing. The startup check and the sign-in listener's initialidlecheck normally finish before logout. Under load one of them is still resolving, and that's the flake. The test is the first in its file, so no earlier test leaks state into it. The session opened before logout (the lead in the brief) isn't involved: the fake factory dies immediately, and itswithAccessscope is already closed.The race code (
ProviderAuthFlow.ts,CodexChatGptAuth.ts,makeManagedServerProvider.ts, and this listener) is identical onmain, somainhas the same latent bug. This PR fixes it only on the V2 branch.Fix
CodexManagedProvider.ts: the listener ignores and logs a failed refresh (Effect.ignoreCause({ log: true })) instead of dying, so the idle that sign-out publishes still refreshes the snapshot.CodexDriver.test.ts: the installation'sacquireinterrupts the two startup checks, and the test waits for both before it continues. This reproduces the race deterministically: without the fix the test hangs 3/3 times, and with it it passes. No timeout was raised and nothing was skipped.Verification
Test timed out).vp test run src/provider/Drivers/CodexDriver.test.ts):cd apps/server && vp exec tsc --noEmit -p .: exit 0, noerror TS.vp linton the two touched files: clean.vp fmt: no changes.vp run knip:check: exit 0.Model: Claude Opus 5.5 (Claude Code)
🤖 Generated with Claude Code