feat(codex): add account picker lifecycle settings - #1019
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR adds Codex account-picker visibility controls, durable account mutations before catalog refresh, normalized refresh status, deterministic catalog convergence, GUI and CLI feedback, and exact-secret redaction. ChangesCodex account picker, catalog lifecycle, and response privacy
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant AccountAPI
participant OcxConfig
participant CatalogConvergence
participant Catalog
Client->>AccountAPI: create, delete, or complete OAuth login
AccountAPI->>OcxConfig: persist account and selector bindings
AccountAPI->>CatalogConvergence: converge catalog
CatalogConvergence->>Catalog: build and merge observed catalog state
Catalog-->>CatalogConvergence: catalog disposition
CatalogConvergence-->>AccountAPI: catalogRefreshPending
AccountAPI-->>Client: mutation result and refresh status
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fb44b7d353
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/server/management-api.ts`:
- Around line 105-109: Update refreshCodexCatalogStrict and auth-api’s
refreshAccountNamespaceCatalog to inspect the refresh result and reject when
catalogExists is false, while preserving successful refresh handling. Ensure the
existing retry and catalogRefreshPending flow receives this failure, and add a
regression covering a non-throwing incomplete refresh.
In `@tests/settings-stream-mode.test.ts`:
- Around line 359-367: Update the response assertions in the settings
stream-mode test to decode the response body once, reuse it for the existing
field checks, and assert that its serialized payload does not contain “private
refresh failure detail” in any field. Keep the existing status and refresh-count
assertions unchanged.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 7040a690-d68b-483f-83f6-82f68682bbfd
📒 Files selected for processing (19)
src/codex/account-lifecycle.tssrc/codex/account-namespaces.tssrc/codex/auth-api.tssrc/codex/catalog-refresh-status.tssrc/codex/catalog/account-models.tssrc/config.tssrc/server/management-api.tssrc/server/management/config-routes.tssrc/server/management/context.tssrc/types.tsstructure/02_config-and-codex-home.mdstructure/03_catalog-and-subagents.mdstructure/05_gui-and-management-api.mdtests/codex-account-namespaces.test.tstests/codex-auth-api.test.tstests/config.test.tstests/native-model-toggle.test.tstests/router.test.tstests/settings-stream-mode.test.ts
fb44b7d to
eae13eb
Compare
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs-site/src/content/docs/ja/reference/management-api.md`:
- Line 204: Update the table row for GET, POST, DELETE /api/codex-auth/accounts
to add the missing trailing pipe and replace the redundant 「することができます」 phrasing
with the concise equivalent, preserving the row’s meaning and table formatting.
In `@src/codex/account-lifecycle.ts`:
- Around line 73-83: Extend the focused Bun regression coverage for
deleteCodexAccount and its auth-api refresh path: verify enabled pickers with a
stored pool account and matching namespace return true, while disabled pickers
or orphaned namespaces return false. Also verify deleting and re-adding the same
account preserves the namespace and triggers refresh when visibility is enabled,
using the existing lifecycle/catalog test symbols under tests/ rather than
relying only on router.test.ts.
In `@src/codex/auth-api.ts`:
- Around line 1316-1318: Make the deletion flow around deleteCodexAccount and
saveRuntimeConfig atomic: ensure the credential tombstone and runtimeConfig
account removal occur within one mutation critical section, or add compensating
rollback that restores both when saveRuntimeConfig throws
ConfigMutationLockError. Preserve the 503 response while preventing partial
deletion, and add a delete-specific test covering save failure and state
restoration.
In `@src/codex/catalog-refresh-status.ts`:
- Around line 28-36: In the retry loop surrounding refresh, add a short delay
between the failed first attempt and the second attempt, using the existing
retry-delay convention from renameAtomicFile where practical. Keep the current
two-attempt limit, immediate success return, and generic failure handling
unchanged; only pause before retrying after a caught error.
- Around line 32-35: Update the catch block in the catalog refresh retry flow to
bind the caught error and call debugProviderDiagnostic("codex",
"catalog-refresh-failed", ...) for every failed attempt. Extract the error
message explicitly rather than serializing Error directly, sanitize it with
redactSecretString and redactUserPath before recording, and preserve the
existing generic terminal warning.
In `@src/server/management/context.ts`:
- Around line 12-16: Export a shared CodexCatalogRefreshCompletion type from
catalog-refresh-status.ts and use it as the return result type of
refreshCodexCatalog in the management context. Update
assertCodexCatalogRefreshComplete to accept void | CodexCatalogRefreshCompletion
while preserving its existing behavior, and remove the duplicated inline object
shape.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 32d4ce77-5ce2-40da-9ea6-96e424668bb6
📒 Files selected for processing (39)
docs-site/src/content/docs/guides/codex-app-models.mddocs-site/src/content/docs/guides/web-dashboard.mddocs-site/src/content/docs/ja/guides/codex-app-models.mddocs-site/src/content/docs/ja/guides/web-dashboard.mddocs-site/src/content/docs/ja/reference/configuration/providers.mddocs-site/src/content/docs/ja/reference/management-api.mddocs-site/src/content/docs/ko/guides/codex-app-models.mddocs-site/src/content/docs/ko/guides/web-dashboard.mddocs-site/src/content/docs/ko/reference/configuration/providers.mddocs-site/src/content/docs/ko/reference/management-api.mddocs-site/src/content/docs/reference/configuration/providers.mddocs-site/src/content/docs/reference/management-api.mddocs-site/src/content/docs/ru/guides/codex-app-models.mddocs-site/src/content/docs/ru/guides/web-dashboard.mddocs-site/src/content/docs/ru/reference/configuration/providers.mddocs-site/src/content/docs/ru/reference/management-api.mddocs-site/src/content/docs/zh-cn/guides/codex-app-models.mddocs-site/src/content/docs/zh-cn/guides/web-dashboard.mddocs-site/src/content/docs/zh-cn/reference/configuration/providers.mddocs-site/src/content/docs/zh-cn/reference/management-api.mdsrc/codex/account-lifecycle.tssrc/codex/account-namespaces.tssrc/codex/auth-api.tssrc/codex/catalog-refresh-status.tssrc/codex/catalog/account-models.tssrc/config.tssrc/server/management-api.tssrc/server/management/config-routes.tssrc/server/management/context.tssrc/types.tsstructure/02_config-and-codex-home.mdstructure/03_catalog-and-subagents.mdstructure/05_gui-and-management-api.mdtests/codex-account-namespaces.test.tstests/codex-auth-api.test.tstests/config.test.tstests/native-model-toggle.test.tstests/router.test.tstests/settings-stream-mode.test.ts
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eae13eb170
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…-lifecycle-settings
…-lifecycle-settings
…-lifecycle-settings
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/config.ts (1)
1080-1095: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winReject codex account namespace selectors that collide with routing-profile alias prefixes.
src/config.ts:1080buildsconfiguredProviderNamespacesfrom provider, combo, OpenAI, and policy namespaces only, butsrc/codex/account-namespaces.ts:77andsrc/routing/profile-namespace.ts:12treat the prefix before/in an alias likeside/modelas occupied. That letsconfigSchema.safeParseacceptcodexAccountNamespaces: { side: "..." }even whilesrc/routing/profile.ts:163rejects an alias that starts with the samecodexAccountNamespaceprefix. IncluderoutingProfileAliasNamespacePrefixes(config)in the account-namespace collision issue and update the message fromsrc/config.ts:1095to cover configured routing-profile alias prefixes/provided namespaces.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/config.ts` around lines 1080 - 1095, The codex account namespace collision validation around configuredProviderNamespaces must also include the prefixes returned by routingProfileAliasNamespacePrefixes(config), so selectors cannot overlap routing-profile alias prefixes. Update the configured namespace set and the collision message in the accountNamespaces validation to cover both routing-profile alias prefixes and configured provider namespaces, while preserving the existing collision behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs-site/src/content/docs/ja/reference/cli/providers-accounts.md`:
- Around line 167-172: Update the response documentation near the provider
account response definitions to separate the scopes of catalogRefreshPending:
Codex remove responses must always include the boolean, including false, while
completed login-status responses should include the field only when a catalog
refresh remains pending. Ensure the surrounding descriptions match the actual
CLI/API behavior and remove the conflicting claim that the field exists only for
Codex deletion.
In `@src/codex/account-namespaces.ts`:
- Around line 76-85: Update occupiedNamespaces to normalize each value returned
by routingProfileAliasNamespacePrefixes through codexProviderNamespaceKey before
adding it to the set, while preserving the existing provider, combo, and
reserved namespace entries. Add a regression case using the mixed-case routing
profile alias Main/gpt-5.5 and verify the normalized main prefix prevents
allocation of a conflicting default namespace.
In `@src/codex/auth-api.ts`:
- Around line 405-418: In the account-addition flow, define one local predicate
for whether codex account picker configuration is enabled, then reuse it for
both the codexAccountNamespaces clone and the appendDefaultCodexAccountNamespace
call. Update the guards in the try block around addedAccount so the clone and
mutation cannot diverge if the condition changes later.
In `@tests/server-auth.test.ts`:
- Line 2012: In the affected try block of the test, remove the duplicate json
declaration and retain a single response.json() call, reusing that parsed object
for all subsequent assertions. Do not rename the duplicate or read the response
body again, since the response can only be consumed once.
---
Outside diff comments:
In `@src/config.ts`:
- Around line 1080-1095: The codex account namespace collision validation around
configuredProviderNamespaces must also include the prefixes returned by
routingProfileAliasNamespacePrefixes(config), so selectors cannot overlap
routing-profile alias prefixes. Update the configured namespace set and the
collision message in the accountNamespaces validation to cover both
routing-profile alias prefixes and configured provider namespaces, while
preserving the existing collision behavior.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 7f87e603-fc9e-4943-9977-596a93a6512d
📒 Files selected for processing (106)
docs-site/src/content/docs/guides/codex-app-models.mddocs-site/src/content/docs/guides/web-dashboard.mddocs-site/src/content/docs/ja/guides/codex-app-models.mddocs-site/src/content/docs/ja/guides/web-dashboard.mddocs-site/src/content/docs/ja/reference/cli/providers-accounts.mddocs-site/src/content/docs/ja/reference/configuration/providers.mddocs-site/src/content/docs/ja/reference/configuration/routing.mddocs-site/src/content/docs/ja/reference/management-api.mddocs-site/src/content/docs/ko/guides/codex-app-models.mddocs-site/src/content/docs/ko/guides/web-dashboard.mddocs-site/src/content/docs/ko/reference/cli/providers-accounts.mddocs-site/src/content/docs/ko/reference/configuration/providers.mddocs-site/src/content/docs/ko/reference/configuration/routing.mddocs-site/src/content/docs/ko/reference/management-api.mddocs-site/src/content/docs/reference/cli/providers-accounts.mddocs-site/src/content/docs/reference/configuration/providers.mddocs-site/src/content/docs/reference/configuration/routing.mddocs-site/src/content/docs/reference/management-api.mddocs-site/src/content/docs/ru/guides/codex-app-models.mddocs-site/src/content/docs/ru/guides/web-dashboard.mddocs-site/src/content/docs/ru/reference/cli/providers-accounts.mddocs-site/src/content/docs/ru/reference/configuration/providers.mddocs-site/src/content/docs/ru/reference/configuration/routing.mddocs-site/src/content/docs/ru/reference/management-api.mddocs-site/src/content/docs/zh-cn/guides/codex-app-models.mddocs-site/src/content/docs/zh-cn/guides/web-dashboard.mddocs-site/src/content/docs/zh-cn/reference/cli/providers-accounts.mddocs-site/src/content/docs/zh-cn/reference/configuration/providers.mddocs-site/src/content/docs/zh-cn/reference/configuration/routing.mddocs-site/src/content/docs/zh-cn/reference/management-api.mdgui/src/codex-account-mutation.tsgui/src/components/AddCodexAccountModal.tsxgui/src/components/CodexAccountPool.tsxgui/src/components/codex-account-pool-main-card.tsxgui/src/components/use-add-codex-account-oauth.tsgui/src/hooks/useCodexAccountPool.tsgui/src/hooks/useJsonConfigEditor.tsgui/src/hooks/useProviderAccountPools.tsgui/src/i18n/de.tsgui/src/i18n/en.tsgui/src/i18n/ja.tsgui/src/i18n/ko.tsgui/src/i18n/ru.tsgui/src/i18n/zh.tsgui/src/notice-tone.tsgui/src/pages/Providers.tsxgui/src/pages/providers-page-modals.tsxgui/src/pages/use-providers-crud.tsgui/src/pages/use-providers-fetch.tsgui/src/pages/use-providers-oauth.tsgui/src/styles.cssgui/src/ui.tsxgui/tests/add-codex-account-oauth.test.tsxgui/tests/codex-account-pool-behaviour.test.tsxgui/tests/codex-account-pool-toast-tone.test.tsxsrc/cli/account-auth.tssrc/cli/account-catalog-refresh.tssrc/cli/account-extended.tssrc/codex/account-lifecycle.tssrc/codex/account-namespaces.tssrc/codex/auth-api.tssrc/codex/catalog-refresh-status.tssrc/codex/catalog/account-models.tssrc/codex/catalog/sync.tssrc/codex/convergence.tssrc/codex/features.tssrc/codex/warmup.tssrc/config.tssrc/lib/redact.tssrc/routing/profile-namespace.tssrc/routing/profile.tssrc/server/management-api.tssrc/server/management/config-routes.tssrc/server/management/context.tssrc/server/relay.tssrc/server/responses/compact.tssrc/server/responses/core.tssrc/server/responses/passthrough-error.tssrc/types.tsstructure/02_config-and-codex-home.mdstructure/03_catalog-and-subagents.mdstructure/05_gui-and-management-api.mdstructure/08_openai-provider-tiers.mdtests/cli-account.test.tstests/codex-account-namespaces.test.tstests/codex-auth-api.test.tstests/codex-catalog-refresh-status.test.tstests/codex-convergence-account-selectors.test.tstests/codex-convergence-contract.test.tstests/codex-v2-gate.test.tstests/config.test.tstests/helpers/catalog-convergence.tstests/issue-452-empty-503.test.tstests/native-model-toggle.test.tstests/passthrough-headers.test.tstests/provider-workspace-auth.test.tstests/redact.test.tstests/responses-compaction-routing.test.tstests/retry-after-429.test.tstests/route-explainability.test.tstests/router.test.tstests/server-auth.test.tstests/server-combo-failover-e2e.test.tstests/settings-stream-mode.test.tstests/token-guardian.test.tstests/warmup.test.ts
|
Follow-up on the full-review finding outside the diff: The suggested The two valid findings were fixed in b593374. The stale duplicate-JSON finding and mixed-case normalization suggestion were answered on their threads. Validation: 227 focused tests, typecheck, privacy scan, diff hygiene, and the 216-page docs build all pass. |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
Thanks for keeping this current against |
|
Understood — I’ve replaced this umbrella with the dependency-ordered split and will land the slices one at a time against current The first slice is #1096. It is limited to the config schema/default contract and pure effective-state resolver: 6 files, no catalog writers, auth/API, CLI, dashboard, or public docs. After that lands, I’ll open the remaining slices in order:
I’m also dropping the old redaction chain from this series because #1038 already landed the reviewed security extraction. Closing this umbrella now so there is only one reviewable feature slice in flight. |
Summary
codexAccountPickerEnabledlifecycle setting for account-qualified Codex picker entries.policynamespace and slash-qualified routing-profile alias prefixes so picker enable and account add cannot create ambiguous or unloadable combined configs.catalogRefreshPendingwithout exposing internal diagnostics.ocx syncrecovery warning in the dashboard and CLI when an account change succeeds but its catalog refresh remains pending; JSON clients retain the boolean completion field.Dashboard feedback
Verification
bun run typecheckbun run privacy:scancd docs-site && bun install --frozen-lockfile && bun run build(216 pages)git diff upstream/dev...HEAD --checkdevancestor:b3a1d90a. On head1828cf77, the final upstream delta is documentation-only underdevlog/, has no feature-path overlap, and the signed merge has an empty remerge diff. Its repository-hygiene suite passes 11/11. The prior combined validation remains unchanged: 9,172 backend tests with 10 intentional skips and 0 failures, all 609 GUI tests, 313 incremental tests with 1 Windows-only skip, 14 final shadow-call tests, typecheck, privacy scan, GUI lint/build, React Doctor, diff hygiene, and the 216-page docs build. Independent security and code-quality reviews found no PR-specific issues.Checklist
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Review readiness checklist
This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:
All CI tests are green on my local testing.
I pushed my PR to the latest dev commit.
I fixed all correct Codex and CodeRabbit findings.
My PR is ready for review.