Skip to content

feat(codex): preserve signed-in quota across duplicate pool entries - #7144

Merged
lidge-jun merged 9 commits into
devfrom
feat/7100-preserve-signed-in-account
Oct 15, 2026
Merged

lidge-jun merged 9 commits into
devfrom
feat/7100-preserve-signed-in-account

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Oct 15, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Closes [Feature]: Prefer other Codex pool accounts to preserve the signed-in ChatGPT account #7100. Add opt-in ocx account preserve-signed-in openai [on|off|status] [--apply-to-bound] [--json], backed by codexPreserveSignedInAccount and authenticated GET/PUT /api/codex-auth/preserve-signed-in.
  • Prefer other eligible Codex identities before native main and ordinary pool entries matching its selected ChatGPT workspace/account and normalized member email. Workspace membership alone never groups different members. Effective priority bands preserve existing custom order; disabling restores that order. All four strategies, previews and priority preemption use the same rule.
  • Identity comes from existing owned physical-login observations, never the incoming bearer. Routing reads only the in-memory observation during native-profile drain. Pool credential replacement is re-evaluated, transient/conflicting observations retain prior verified evidence, and confirmed native transitions retire stale evidence until the next owned observation.
  • Healthy bindings and manual pins remain by default; exact-account model routes override the preference. Explicit --apply-to-bound saves the policy before releasing only affected bindings/manual preferences/pins for the next request. In-flight requests retain their captured account. Existing optional priority failback keeps its independent conditions and is reported in status.
  • Status reports affected entries, identity-evidence availability, the actual next unbound choice, fallback spending and pin/binding semantics. Linked pause remains the exclusion alternative. Fallback can consume signed-in quota under all existing eligibility, quota, model, hard-lock and paid-credit-consent guards. This does not unlock a disabled desktop composer. No GUI, hard-lock (feat(codex): route hard-locked main-account traffic to a configured fallback model #7123), provider preset or dependency changes.
  • Explicit maintainer security review is required by MAINTAINERS.md for the identity/account-management changes. Independent read-only agent review passed after fixing transient-read evidence invalidation; that does not substitute for maintainer security approval.

Verification

All runtime tests used temporary OPENCODEX_HOME/CODEX_HOME; no real account files or upstream inference. Bun 1.4.3 was downloaded only into ignored worktree scratch for the repository's pinned-runner tooling check; no global installation changed.

  • bun install — pass, 105 installs checked, no lockfile changes.
  • bun test tests/codex-integration/codex-preserve-signed-in.test.ts tests/cli/cli-account-preservation.test.ts — 39 pass / 0 fail, Bun 1.4.3, latest implementation. Covers all four strategies, duplicated identity, extreme custom priorities, fallback and eligibility, bound/pin opt-in transition, unrelated bindings, login/pool credential changes, unknown/conflicting evidence, drain read fencing, API validation/persistence rollback and CLI method/body/invalid operands.
  • bun test tests/codex-integration/codex-preserve-signed-in.test.ts tests/cli/cli-account-preservation.test.ts tests/codex-integration/codex-linked-account-pause.test.ts tests/codex-integration/codex-pool-rotation.test.ts tests/codex-integration/codex-priority-failback.test.ts tests/codex-integration/main-account-policy-binding-wait.test.ts tests/codex-integration/codex-entitlement-identity-read-fence.test.ts — 204 pass / 0 fail before the final two focused rollback/conflicting-evidence cases; those are included in the 39-pass run above.
  • bun test tests/test-layout.test.ts tests/test-layout-tooling.test.ts tests/ci-workflows/file-size-ratchet.test.ts tests/server/management-route-registry.test.ts tests/cli/cli-capabilities.test.ts tests/cli/cli-capabilities-arguments.test.ts tests/ci-workflows/skill-ocx.test.ts tests/ci-workflows/skill-ocx-generated.test.ts — initially 105 pass / 1 fail on host Bun 1.4.0: the tooling subprocess explicitly required repository-pinned Bun 1.4.3. With PATH and OCX_TEST_RUNNER_BUN pointing to the scratch Bun 1.4.3 binary, bun test tests/test-layout-tooling.test.ts passed 25 / 0. The other seven files passed in the first run.
  • bun test tests/ci-workflows/file-size-ratchet.test.ts — 9 pass / 0 fail after additions; no baseline raised.
  • bun run typecheck — pass, latest code/tests.
  • bun run structure:check — pass (new files staged, as the guard validates the git index).
  • bun run privacy:scan — pass, latest code/tests.
  • bun run skill:surface — generated the management/account capability map; generated-surface tests passed.
  • Regression sensitivity: restoring the old per-ID selection lookup makes the four strategy preservation cases fail (0 pass / 4 fail). Restoring transient-read invalidation makes its regression fail (0 pass / 1 fail); restored implementation passes.

Full local suites (bun run test, bun run prepush, whole tests directory) were explicitly prohibited on this shared host. Broad Ubuntu, cross-platform and docs-build coverage is left to hosted CI. No live desktop/composer acceptance or maintainer security approval is claimed. PR exact-head checks will be inspected, then the full ci.yml workflow_dispatch with lane=all will be dispatched on this branch after PR checks pass. CI polling reached the approximately 60-minute stage cap (2026-10-15 07:35–08:35 UTC, across the initial and final heads). Final head: 6ce501cc4eed059cc99e9ffa97407a21057a342b. The current PR CI run remains queued: changes and select windows runner have no executed steps. Catalog async contracts (ubuntu-latest), resolve-pr, label, hygiene, and react-doctor are also queued. CodeRabbit status is SUCCESS, which is not test execution or maintainer security approval. No current-head Actions test result exists yet.

The final cross-platform dispatch is NOT RUN because the required preceding PR checks have not passed. After they pass, run gh workflow run ci.yml --repo lidge-jun/opencodex --ref feat/7100-preserve-signed-in-account -f lane=all, confirm its head SHA, and inspect all jobs/logs. The obsolete own-branch initial-head CI/hygiene runs were cancelled to release workflow concurrency; no other branches or current-head runs were cancelled and no cancelled result is counted as passing. This PR remains draft pending hosted validation and explicit maintainer security review.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. Agent review and privacy checks passed; explicit maintainer security review is still required before merge.

@coderabbitai

coderabbitai Bot commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the enhancement New feature or request label Oct 15, 2026
…ned-in-account

# Conflicts:
#	scripts/test-layout/layout.json
#	tests/fixtures/test-layout-expected.json
…ned-in-account

# Conflicts:
#	scripts/test-layout/layout.json
Resolve routes.ts by keeping both the preserve-signed-in and use-remaining routes. Regenerate the ocx skill surface (338 capabilities across both sides). Move the preserve-signed-in section into structure/providers/openai-signed-in-preservation.md so openai-accounts.md stays inside the 600-line doc budget.
…ned-in-account

# Conflicts:
#	structure/gui-and-management-api.md
…ned-in-account

# Conflicts:
#	structure/INDEX.md
#	structure/gui-and-management-api.md
# Conflicts:
#	scripts/test-layout/layout.json
#	structure/INDEX.md
#	tests/fixtures/test-layout-expected.json
@lidge-jun

Copy link
Copy Markdown
Owner Author

Maintainer integration into dev (MAINTAINERS.md dev maintainer-integration policy; batch integration authorized by @lidge-jun on 2026-10-15).

  • Head: 3784d66bf93a0a1e6cacfcaf6cb15413fd971746 (tree 3fa165221628c5dc3127dc73103a5d70662a3b95) = this branch merged with origin/dev 243bf2cca6. Integration note: auto-resolved union conflicts: scripts/test-layout/layout.json structure/INDEX.md tests/fixtures/test-layout-expected.json.
  • Exact-head evidence: GitHub-hosted Actions for this account have not been assigning runners since 2026-10-15 13:30 UTC, so by owner decision the evidence is a full bun run test (Bun 1.4.3 test runner, root and GUI dependencies installed, GUI built) of this exact tree on a maintainer host (Linux x86_64): exit 1, 7 min, 28 failing test(s), each also failing in the same host's baseline run of dev 60bf4c7 (environment-only): Codex shim install readiness > a refused install exits unsuccessfully and preserves its re, Codex shim install readiness > keeps install advisory when the Codex config cannot be read, Codex shim install readiness > the install command surfaces readiness warnings without lea, GUI pairing client > sends one bodyless origin-bound capability and redacts rejected bodie, Node launcher PATH fallback activation > broken bundle reaches validated PATH Bun, Node launcher PATH fallback activation > inspection bundle reaches validated PATH Bun, Node launcher PATH fallback activation > missing bundle reaches validated PATH Bun, bundledBunPath / durableBunPath > PATH-selected process provenance survives durable select, ….
  • Local gates on the same tree: bun run typecheck, file-size ratchet, test-layout and structure:check.
  • Security review: independent agent security review PASS at 6ce501c; later commits are a dev merge only.
  • Hosted CI checks for this head may still be queued; they are not claimed as evidence.

@lidge-jun
lidge-jun marked this pull request as ready for review October 15, 2026 20:24
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner October 15, 2026 20:24
@lidge-jun
lidge-jun merged commit b6dffa0 into dev Oct 15, 2026
5 of 6 checks passed
@lidge-jun
lidge-jun deleted the feat/7100-preserve-signed-in-account branch October 15, 2026 20:24

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3784d66bf9

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +13 to +16
for (const account of config.codexAccounts ?? []) {
if (!isSelectableCodexPoolAccount(account)) continue;
const credential = getCodexAccountCredential(account.id);
if (sameCodexLogin(main, codexLoginIdentity(credential?.chatgptAccountId, account.email))) ids.add(account.id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Load the credential store only once per selection

When this opt-in is enabled with multiple pool accounts, every selection pass calls getCodexAccountCredential once per row. That function reaches readCodexAccountRecord, which reloads, parses, and normalizes the entire credential store for each ID, so an N-account pool performs N synchronous full-store reads (and O(N²) parsing work) on Bun's request path; routing can perform several such selection passes for one request. Load one loadCodexAccountRecordSnapshot() before this loop and resolve every account from that snapshot instead.

Useful? React with 👍 / 👎.

Comment thread structure/manifest.json
"tier": 4,
"title": "Preserve Signed-In Codex Quota",
"scope": "Opt-in effective priority bands that spend other pool accounts before the signed-in identity, its identity observation and management API.",
"documents": ["src/codex/account-preservation.ts", "src/codex/signed-in-identity.ts", "src/codex/auth-api/account-preservation.ts", "src/cli/account-preservation.ts"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Map the account identity helper to its preservation contract

Add src/codex/account-identity.ts to this document's documents list and name it in the document itself. The newly added helper owns linkedCodexAccountIds, including the workspace-and-email matching rule described by this preservation document, but the generated source-to-doc index omits that relationship and instead attributes the behavior only to the other modules; future changes to the matching logic therefore will not fan out to its authoritative contract.

AGENTS.md reference: structure/AGENTS.md:L39-L42

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-15T20:28:41.810532Z 3784d66 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

MarcTCruz added a commit to MarcTCruz/opencodex that referenced this pull request Oct 19, 2026
…for the in-memory store (lidge-jun#2999)

The in-memory store adopts only complete ChatGPT credentials (access and refresh token), as a real
Codex login always is. codex-preserve-signed-in (lidge-jun#7144) and native-ultrafast-picker (lidge-jun#7050) wrote
logins without a refresh token, so the product saw no login. Their fixtures now include one, and the
cases that rewrite auth.json mid-test call the store's observe step, which the watcher runs in
production. No assertion changed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant