Repository navigation
Sync subscription auth and multi-account substrate #306
Description
Objective
Adopt upstream subscription-auth host abstractions, credential storage improvements, and account protocol substrate without regressing Every Code's multi-account product behavior or loaded-thread credential refresh.
This wave may proceed in parallel with the turn/history wave once the compatibility envelope is merged, but it must preserve all current add, switch, remove, fallback, profile, API-key, device-code, and ChatGPT account invariants.
Finish Line
Codex Lab uses the selected upstream auth/storage substrate while a loaded session can safely add, switch, remove, refresh, and log out accounts with deterministic identity and no stale credentials.
Current Status
State: Complete on #428's candidate.
PR #492 restored immediate loaded-thread account-lease repair on account removal, including safe fallback or explicit signed-out state, compare-and-swap persistence, and websocket-session invalidation. PR #493 restored a debug-only persisted integration keyring so cross-process auth tests remain hermetic and fail closed rather than reaching the host keychain.
Final candidate: PR #465 at a04892bafa27f5b5006e77944a4c36704935b0e1 on July 29, 2026.
Validation passed: 20 execution-account tests, 7 account-catalog tests, loaded-thread authorization regression coverage, 5 persisted-keyring tests, CLI app-server tests, strict config, JSON logging, websocket and plugin startup gates, app-test-support/app-server/CLI release checks, all 274 repository-check Python tests, convergence validation, four independent review lenses, and all 15 checks on PR #493.
Blocked by: none.
Next action: close this plan and activate #307's execution/tools/sandbox/external-agent lane.
Last verified: July 29, 2026.
Scope
- In: auth host abstraction, credential serialization/storage, login/token refresh safety, active-account persistence, account list/add/switch/remove/logout APIs, loaded-thread refresh, migration fixtures, and account-related protocol aliases.
- Out: automatic quota priming or broad routing policy from Classify deferred multi-account routing and quota-priming policy #290, unrelated TUI redesign, and collapsing Every Code multi-account UX into upstream single-account assumptions.
Acceptance Criteria
- API-key, ChatGPT, device-code, and stored-account flows use the selected upstream host/storage primitives where compatible.
- Existing account IDs and active-account state migrate deterministically without accidental identity replacement.
- Loaded threads use refreshed credentials after login, switch, removal fallback, token refresh, and logout without requiring an unintended session restart.
- Add Account preserves distinct accounts and rotates credentials only for the same logical account.
- Account removal selects a safe fallback or explicit signed-out state.
- Strict app-server/Desktop clients receive compatible account/auth shapes through aliases or capability gates.
- Real-home credentials are never touched by automated tests.
- Existing account regression suites plus new migration fixtures pass.
Relationships
- Parent: Sync Codex Lab with current openai/codex substrate #230.
- Completed on: Build upstream snapshot integration and canary branch #428 candidate PR Integrate current upstream Codex snapshot with Every Code contracts #465.
- Contract authority: Define Every Code-owned convergence contracts #126.
- Parallel lane after unblocking: Sync canonical turn, context, history, and recovery substrate #305 history/recovery.
- Related deferred policy: Classify deferred multi-account routing and quota-priming policy #290.
- Blocks: Sync exec, tools, sandbox, and external-agent substrate #307 and Sync TUI, Guardian, and CI substrate #308.
- Prior merged evidence: PRs auth: refresh loaded sessions after credential changes #350/test(app-server): isolate integration keyring state #351.
Validation
- Isolated-home core, login, app-server, and TUI account tests.
- Loaded-thread credential assertions before and after each account mutation.
- Legacy auth-store migration fixtures plus logout/recovery scenarios.
- For any account/auth protocol shape change, run
just write-app-server-schema, provecodex-rs/app-server-protocol/schemais clean, then runjust test -p codex-app-server-protocoland the README Desktop initialize/thread/CLI strict-config gates. - No live-account automation beyond a separately approved bounded manual dogfood proof.
Decisions
- Preserve Every Code multi-account UX as product-owned behavior.
- Reuse upstream auth transport/storage safety wherever it does not erase those semantics.
Open Questions
- None currently.
Activity
cbusillo commentedon Jul 12, 2026
Update 2026-07-12 UTC:
7cc80b39f1without the rejected feature-flag path.local.agefilename and keyring account. Codex auth and MCP OAuth use separate encrypted files and separate OS-keyring accounts, preventing key reuse/collision.AuthDotJsonmirror and credential-bearingauth_accountscatalog, including fail-closed decrypt errors, mocked-keyring migration tests, crash consistency, and preservation of File/Keyring/Auto/Ephemeral plus Every Code add/switch/remove/fallback/reload behavior.Blocked by: none. Partial encryption of only
auth.jsonremains explicitly out of scope.cbusillo commentedon Jul 13, 2026
Update 2026-07-13 UTC:
Blocked by: none. Broad app-server/TUI activation remains a separate follow-up stage.
cbusillo commentedon Jul 28, 2026
Update 2026-07-28 UTC:
17385ebebe34ed3a836d261290cf75c6e02a4761.cargo check -p codex-tui, 13-job blocking CI, and the macOS app build. Four-lens review is clean.Remaining acceptance gap: the hermetic persisted integration-keyring support merged in PR #351 is no longer present in the current candidate tree after upstream convergence. Next action is a focused restoration so debug integration tests fail closed instead of ever reaching the host keychain; this remains required before closing #306.
shiny-code-bot commentedon Jul 29, 2026
Completed on the converged candidate.
17385ebebe34ed3a836d261290cf75c6e02a4761.a04892bafa27f5b5006e77944a4c36704935b0e1.This closes #306 and removes the final prerequisite from #307.