Client or integration
Codex CLI
Area
Authentication and account pool
Summary
An authenticated flagship model refusal is remembered for six hours under account ID and model ID, without credential generation. Reauthenticating the same internal account can leave the previous credential's denial active, avoiding an account that now has access. Expected: evidence from the old credential stops influencing the replacement, and late old replies cannot create or clear replacement evidence.
The release owner explicitly deferred this to the next round's first item. Compared with the earlier repeated-400 behavior, the current routing is an improvement; empty-filter restoration prevents a hard outage. A generation-aware change and its late-response races should be reviewed without release pressure.
Reproduction
Static, constructible trace at a0f611d; not a claimed live reproduction:
- With no roster cached, a pool account receives an authenticated unsupported-model refusal for gpt-5.6-sol. tests/codex-integration/codex-model-denial-evidence.test.ts:52 covers recording without roster evidence.
- src/codex/observed-model-denials.ts:51-80 stores account/model plus a six-hour expiry, without credential generation.
- Reauthenticate the same pool account. src/codex/auth-api/login-flow.ts:192 and :374 reuse the internal ID and write the replacement. src/codex/account-store.ts:160 increments generation; model-entitlements.ts:565 resolves pool:generation:upstream-account identity.
- Existing-account reauth keeps pickerVisibilityChanged false (login-flow.ts:350), so catalog convergence returns without refresh (:158).
- The only production account-wide forget call is model-entitlements.ts:884, inside a condition requiring an OLD cached roster with changed identity (:877-884). With no prior roster it cannot run.
- cachedDeniedCodexAccountIdsForModel unions the unversioned refusal (:1300). A later positive roster removes the account from the returned denied set (:1292) but does not delete the six-hour record. After the five-minute roster expires, the old denial can reappear.
Fix direction: bind evidence to the credential identity captured from the dispatched auth context; validate against current identity after the exclusion-read fence. Make both denial writes and successful-response clears generation-aware. Required race: an in-flight generation-G refusal or success arrives after G+1 is saved and must neither overwrite nor clear G+1 evidence. Keep cache-only routing, no extra upstream fetch, current TTL/entry bound, positive-roster precedence and empty-filter restoration.
Version
2.59.0 dev, a0f611d
Operating system
Cross-platform logic; static source audit on macOS. No local runtime reproduction was run.
Provider and model
OpenAI / ChatGPT Codex account pool; gpt-5.6-sol and other entitlement-preferred flagship models
Logs or error output
No local runtime logs: this release-audit lane forbids local tests, builds, typecheck, installs and proxy execution. Evidence is static source/control-flow tracing, not a claim of executed reproduction.
Screenshots and supporting files
Observed denial store
Conditional invalidation
Same-ID login flow
Denial union and positive grants
Related: #4921, #4906. No credentials or actual account identifiers are included.
Redacted configuration
{"defaultProvider":"openai","providers":{"openai":{"adapter":"openai-responses","baseUrl":"https://chatgpt.com/backend-api/codex","authMode":"forward"}}}
Checks
Client or integration
Codex CLI
Area
Authentication and account pool
Summary
An authenticated flagship model refusal is remembered for six hours under account ID and model ID, without credential generation. Reauthenticating the same internal account can leave the previous credential's denial active, avoiding an account that now has access. Expected: evidence from the old credential stops influencing the replacement, and late old replies cannot create or clear replacement evidence.
The release owner explicitly deferred this to the next round's first item. Compared with the earlier repeated-400 behavior, the current routing is an improvement; empty-filter restoration prevents a hard outage. A generation-aware change and its late-response races should be reviewed without release pressure.
Reproduction
Static, constructible trace at a0f611d; not a claimed live reproduction:
Fix direction: bind evidence to the credential identity captured from the dispatched auth context; validate against current identity after the exclusion-read fence. Make both denial writes and successful-response clears generation-aware. Required race: an in-flight generation-G refusal or success arrives after G+1 is saved and must neither overwrite nor clear G+1 evidence. Keep cache-only routing, no extra upstream fetch, current TTL/entry bound, positive-roster precedence and empty-filter restoration.
Version
2.59.0 dev, a0f611d
Operating system
Cross-platform logic; static source audit on macOS. No local runtime reproduction was run.
Provider and model
OpenAI / ChatGPT Codex account pool; gpt-5.6-sol and other entitlement-preferred flagship models
Logs or error output
No local runtime logs: this release-audit lane forbids local tests, builds, typecheck, installs and proxy execution. Evidence is static source/control-flow tracing, not a claim of executed reproduction.
Screenshots and supporting files
Observed denial store
Conditional invalidation
Same-ID login flow
Denial union and positive grants
Related: #4921, #4906. No credentials or actual account identifiers are included.
Redacted configuration
{"defaultProvider":"openai","providers":{"openai":{"adapter":"openai-responses","baseUrl":"https://chatgpt.com/backend-api/codex","authMode":"forward"}}}
Checks