Skip to content

fix(codex): align auth config and rate limits - #8293

Open
bbingz wants to merge 7 commits into
stablyai:mainfrom
bbingz:bbingz/split-7950-auth-rate-limits
Open

fix(codex): align auth config and rate limits#8293
bbingz wants to merge 7 commits into
stablyai:mainfrom
bbingz:bbingz/split-7950-auth-rate-limits

Conversation

@bbingz

@bbingz bbingz commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • force file-backed Codex auth in managed/runtime base config and every profile-v2 overlay, preserving UTF-8 BOM placement
  • rewrite profile-relative path settings into the managed home without letting an overlay restore keyring/auto auth
  • mark generated profile overlays with a versioned body hash and remove only stale, unmodified Orca-managed copies after source rename/delete
  • publish overlay replacements with same-directory stage/quarantine and no-clobber hard links, preserving concurrent or non-regular targets for recovery
  • resolve chatgpt_base_url from top-level TOML, including BOM-prefixed configs, for custom-backend rate-limit requests
  • map app-server rate-limit windows using the reported windowDurationMins and retain additional by-ID buckets
  • keep Codex preferred session/weekly meters visible in the status bar when dynamic buckets are present

This is the focused auth/config/rate-limit replacement extracted from #7950. It intentionally excludes hooks/status, startup delivery, and session/native-chat changes.

Refs #7950

Screenshots

No visual redesign; Codex status-bar usage can now retain session/weekly while exposing additional meters in the tooltip.

Testing

  • changed-test-file Vitest with the repository config: 11 files / 255 tests
  • focused current follow-up Vitest: 3 files / 56 tests
  • Node 24 pnpm typecheck (node, CLI, web)
  • pnpm lint (passes with repository-existing warnings)
  • targeted oxlint
  • targeted oxfmt --check
  • pnpm check:max-lines-ratchet
  • git diff --check origin/main...HEAD
  • exact three-commit git range-diff after rebase onto e5efbc9ff
  • RED-to-GREEN coverage for ownership marker/BOM handling, stale cleanup, hard-link capability failure, no-clobber restore/publish races, profile auth, backend URL parsing, exact RPC window duration, and Codex dynamic-bucket rendering
  • full repository Vitest
  • Electron/E2E/GUI
  • physical Windows/WSL managed-account and filesystem exercise

AI Review Report

The first independent gate found four blockers: profile overlays could override file auth, rate-limit durations were rounded as though they were remaining time, Codex dynamic buckets hid the weekly meter, and a BOM could hide the first-line backend URL. Each was reproduced and fixed before submission.

A separate three-round hard gate reviewed stale-overlay ownership and concurrent filesystem behavior. It found and drove tests for no-clobber stale restore, post-quarantine symlink type changes, and active-publish replacement races. The final implementation removed the earlier manifest/fd/inode/copy/symlink-reconstruction design and split active publishing into one concrete module.

A current-head CodeRabbit review then identified that a final hard-link failure could strand the previous overlay in quarantine. The finding was independently confirmed and severity-calibrated, then fixed with a pre-quarantine hard-link capability probe plus best-effort no-clobber restore for non-EEXIST final failures. Two new RED-to-GREEN tests cover permanent preflight failure and a one-shot final publish failure. Final independent verdict: Spec PASS / Quality APPROVED, with no confirmed blocker.

Cross-platform review covered macOS, Linux, and Windows path/type behavior: paths use Node utilities, rename/link operations stay within one directory, Windows overlay names compare case-insensitively, the existing writer retains Windows ACL repair, and no UI shortcut/label/Electron-specific behavior changes.

Security Audit

  • file-backed auth remains confined to the selected managed/runtime CODEX_HOME; no credential value crosses a new channel
  • custom backend URLs come from the user's selected Codex config and continue through existing authenticated fetch behavior
  • generated overlays carry a versioned SHA-256 marker over the final rewritten body; the marker proves cleanup ownership/integrity, not authentication
  • stale cleanup deletes only marked, hash-matching regular files; unmarked legacy overlays and user-modified copies are restored
  • active symlink/directory targets are skipped; ambiguous type changes and concurrent-target conflicts retain a quarantine artifact and warn instead of overwriting
  • existing targets are not quarantined until same-directory hard-link capability succeeds; transient final failures attempt a no-clobber restore, while EEXIST preserves the concurrent target
  • no new dependency, command execution path, unrestricted IPC, or secret logging

Compatibility

TOML handling preserves BOM placement and rewrites platform paths through existing path utilities. Status rendering changes only the Codex bucket branch; Gemini's bucket-only compact behavior remains unchanged.

The no-clobber protocol preflights same-directory hard links before moving an existing target. A filesystem or share without hard-link support therefore fails closed with a warning and leaves the existing overlay at its original path. If a transient final publish and subsequent no-clobber restore both fail, the previous regular file remains under an explicit quarantine name for manual recovery.

Notes

Validation used the repository-declared Node 24.18.0. The three branch commits were range-diff equivalent when rebased onto origin/main@e5efbc9ff; the branch has since been rebased again.

ELI5

Managed Codex auth config and overlays could drift (keyring vs file auth, stale overlays, path issues), which broke rate limits and account switching. Auth is forced file-backed in managed homes, overlays are versioned and cleaned carefully, and rate-limit handling stays aligned.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Codex managed-home synchronization now enforces cli_auth_credentials_store = "file", rewrites additional path-valued settings, and mirrors profile overlay files. Codex rate-limit requests resolve custom backend URLs from top-level configuration and map RPC responses into primary windows plus extra buckets. Tests cover configuration transformations, backend routing, bucket mapping, and reported durations. Status-bar rendering keeps Codex session and weekly windows authoritative while displaying extra meters.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.90% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title matches the core Codex auth and rate-limit changes, though it omits overlay-specific details.
Description check ✅ Passed The description follows the required template and covers summary, screenshots, testing, AI review, security audit, and notes.

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.

@AmethystLiang AmethystLiang self-assigned this Jul 11, 2026
@AmethystLiang
AmethystLiang self-requested a review July 11, 2026 16:47
@bbingz
bbingz force-pushed the bbingz/split-7950-auth-rate-limits branch from 45bd811 to 7a0bfda Compare July 12, 2026 02:22
@bbingz

bbingz commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

Final stale-overlay cleanup follow-up is now on the rebased current head 7a0bfda53.

The implementation uses a versioned body marker plus same-directory stage/quarantine and no-clobber hard-link publication. It removes only unmodified Orca-managed stale overlays; unmarked/user-modified files, non-regular type changes, and concurrent targets are preserved or quarantined with a warning. The earlier manifest/fd/inode/copy/symlink-reconstruction design was removed.

Three independent hard-gate rounds closed the stale-restore, quarantined-symlink, and active-publish races; final verdict is Spec PASS / Quality APPROVED. Post-rebase verification: 11 changed test files / 253 tests, focused 3 files / 76 tests, node/CLI/web typecheck, lint/format/max-lines/diff, and exact two-commit range-diff all pass under Node 24.18.0. Electron/E2E and physical Windows filesystem exercise were not run.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/main/rate-limits/codex-backend-base-url.ts (2)

29-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate top-level TOML line-scanning loop.

The isTomlStructuralLinegetTomlTableHeader/break → match → updateTomlLineScanState loop in parseTopLevelTomlString (Lines 69-81) mirrors the same scan pattern in codex-config-auth-store.ts (Lines 23-39). Both files already share the low-level helpers from config-toml-line-scan.ts; extracting a generic "find/replace top-level key line" iterator there would remove the duplicated control flow and centralize future fixes (e.g. the CRLF edge case flagged in the sibling file).

// e.g. in config-toml-line-scan.ts
export function findTopLevelTomlLine(
  lines: string[],
  predicate: (line: string) => boolean
): number | null {
  let scanState = createTomlLineScanState()
  for (let index = 0; index < lines.length; index += 1) {
    const line = lines[index] ?? ''
    if (isTomlStructuralLine(scanState)) {
      if (getTomlTableHeader(line)) return null
      if (predicate(line)) return index
    }
    scanState = updateTomlLineScanState(scanState, line)
  }
  return null
}

Also applies to: 63-83


37-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Unreachable || url.origin fallback.

${url.origin}${...} is always a non-empty string (url.origin is never falsy for a successfully parsed URL), so || url.origin never triggers.

🧹 Proposed cleanup
-    return `${url.origin}${path === '/' ? '' : path}` || url.origin
+    return `${url.origin}${path === '/' ? '' : path}`

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c47d8768-98e0-4e56-bce6-7f535ef8553c

📥 Commits

Reviewing files that changed from the base of the PR and between 45bd811 and 7a0bfda.

📒 Files selected for processing (24)
  • config/tsconfig.cli.json
  • src/main/codex-accounts/runtime-home-service.test.ts
  • src/main/codex-accounts/service.test.ts
  • src/main/codex-accounts/service.ts
  • src/main/codex/codex-config-auth-store.ts
  • src/main/codex/codex-config-mirror.test.ts
  • src/main/codex/codex-config-mirror.ts
  • src/main/codex/codex-config-path-reference-rewrite.ts
  • src/main/codex/codex-profile-config-overlay-active-publish.ts
  • src/main/codex/codex-profile-config-overlay-mirror.test.ts
  • src/main/codex/codex-profile-config-overlay-mirror.ts
  • src/main/codex/config-settings-promotion.test.ts
  • src/main/rate-limits/codex-backend-base-url.test.ts
  • src/main/rate-limits/codex-backend-base-url.ts
  • src/main/rate-limits/codex-fetcher-backend.test.ts
  • src/main/rate-limits/codex-fetcher-buckets.test.ts
  • src/main/rate-limits/codex-fetcher.test.ts
  • src/main/rate-limits/codex-fetcher.ts
  • src/main/rate-limits/codex-rpc-rate-limit-mapping.ts
  • src/renderer/src/components/status-bar/StatusBar.tsx
  • src/renderer/src/components/status-bar/status-bar-provider-menu-focus.test.tsx
  • src/renderer/src/components/status-bar/tooltip.test.ts
  • src/renderer/src/components/status-bar/tooltip.tsx
  • src/shared/rate-limit-types.ts
✅ Files skipped from review due to trivial changes (1)
  • src/shared/rate-limit-types.ts
🚧 Files skipped from review as they are similar to previous changes (17)
  • src/main/codex-accounts/service.ts
  • src/main/codex/config-settings-promotion.test.ts
  • src/renderer/src/components/status-bar/StatusBar.tsx
  • src/main/rate-limits/codex-fetcher.test.ts
  • src/renderer/src/components/status-bar/tooltip.test.ts
  • src/main/rate-limits/codex-fetcher-backend.test.ts
  • src/main/codex/codex-config-path-reference-rewrite.ts
  • src/renderer/src/components/status-bar/tooltip.tsx
  • src/renderer/src/components/status-bar/status-bar-provider-menu-focus.test.tsx
  • src/main/rate-limits/codex-rpc-rate-limit-mapping.ts
  • src/main/rate-limits/codex-fetcher-buckets.test.ts
  • src/main/codex-accounts/runtime-home-service.test.ts
  • src/main/codex/codex-config-mirror.test.ts
  • src/main/codex/codex-config-mirror.ts
  • src/main/rate-limits/codex-backend-base-url.test.ts
  • src/main/rate-limits/codex-fetcher.ts
  • src/main/codex-accounts/service.test.ts

Comment thread src/main/codex/codex-profile-config-overlay-active-publish.ts
@bbingz
bbingz force-pushed the bbingz/split-7950-auth-rate-limits branch from 7a0bfda to 880ad9e Compare July 12, 2026 02:46
@bbingz

bbingz commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

Current-head review-body nitpick dispositions:

  • Removed the unreachable || url.origin fallback in 880ad9e2f; successful URL parsing always produces a non-empty origin-based result.
  • Did not add a generic top-level TOML iterator. The two callers share the stateful low-level scanner already, but one mutates a matched line while the other parses a quoted value and stops at a table. Abstracting their short control flow would add callback/generalization surface to this focused PR without fixing a demonstrated bug; CRLF/BOM and multiline structural cases remain covered by the existing scanner/tests.

The branch was rebased again onto current main e5efbc9ff with an exact three-commit range-diff. Changed-test-file Vitest is now 11 files / 255 tests.

@bbingz

bbingz commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@bbingz
bbingz force-pushed the bbingz/split-7950-auth-rate-limits branch from fb5dcc4 to 29d041e Compare July 14, 2026 00:29

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/main/codex/codex-config-auth-store.ts (1)

42-46: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Preserve Windows line endings when prepending the configuration.

When prepending the setting to an existing configuration that uses Windows \r\n line endings, the newly added line uses \n, resulting in mixed line endings. While TOML parsers typically accept this, detecting the line ending from the existing content ensures strict formatting consistency.

🛠️ Proposed refactor
-  return restoreBom(
-    content.length === 0
-      ? `${FILE_AUTH_CREDENTIALS_STORE_LINE}\n`
-      : `${FILE_AUTH_CREDENTIALS_STORE_LINE}\n${content}`
-  )
+  const fallbackLineEnding = content.includes('\r\n') ? '\r\n' : '\n'
+  return restoreBom(
+    content.length === 0
+      ? `${FILE_AUTH_CREDENTIALS_STORE_LINE}${fallbackLineEnding}`
+      : `${FILE_AUTH_CREDENTIALS_STORE_LINE}${fallbackLineEnding}${content}`
+  )

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: af035d94-08ab-44c6-aa68-34dc9337848e

📥 Commits

Reviewing files that changed from the base of the PR and between fb5dcc4 and 29d041e.

📒 Files selected for processing (24)
  • config/tsconfig.cli.json
  • src/main/codex-accounts/runtime-home-service.test.ts
  • src/main/codex-accounts/service.test.ts
  • src/main/codex-accounts/service.ts
  • src/main/codex/codex-config-auth-store.ts
  • src/main/codex/codex-config-mirror.test.ts
  • src/main/codex/codex-config-mirror.ts
  • src/main/codex/codex-config-path-reference-rewrite.ts
  • src/main/codex/codex-profile-config-overlay-active-publish.ts
  • src/main/codex/codex-profile-config-overlay-mirror.test.ts
  • src/main/codex/codex-profile-config-overlay-mirror.ts
  • src/main/codex/config-settings-promotion.test.ts
  • src/main/rate-limits/codex-backend-base-url.test.ts
  • src/main/rate-limits/codex-backend-base-url.ts
  • src/main/rate-limits/codex-fetcher-backend.test.ts
  • src/main/rate-limits/codex-fetcher-buckets.test.ts
  • src/main/rate-limits/codex-fetcher.test.ts
  • src/main/rate-limits/codex-fetcher.ts
  • src/main/rate-limits/codex-rpc-rate-limit-mapping.ts
  • src/renderer/src/components/status-bar/StatusBar.tsx
  • src/renderer/src/components/status-bar/status-bar-provider-menu-focus.test.tsx
  • src/renderer/src/components/status-bar/tooltip.test.ts
  • src/renderer/src/components/status-bar/tooltip.tsx
  • src/shared/rate-limit-types.ts
🚧 Files skipped from review as they are similar to previous changes (21)
  • src/main/codex/config-settings-promotion.test.ts
  • src/main/rate-limits/codex-fetcher.test.ts
  • src/shared/rate-limit-types.ts
  • src/renderer/src/components/status-bar/StatusBar.tsx
  • src/main/rate-limits/codex-backend-base-url.test.ts
  • src/main/codex-accounts/service.ts
  • src/main/codex/codex-profile-config-overlay-mirror.ts
  • src/renderer/src/components/status-bar/status-bar-provider-menu-focus.test.tsx
  • src/renderer/src/components/status-bar/tooltip.test.ts
  • src/renderer/src/components/status-bar/tooltip.tsx
  • src/main/codex/codex-config-mirror.ts
  • src/main/codex/codex-config-path-reference-rewrite.ts
  • src/main/rate-limits/codex-rpc-rate-limit-mapping.ts
  • src/main/codex-accounts/service.test.ts
  • src/main/rate-limits/codex-fetcher-buckets.test.ts
  • src/main/codex-accounts/runtime-home-service.test.ts
  • src/main/rate-limits/codex-fetcher-backend.test.ts
  • src/main/codex/codex-profile-config-overlay-mirror.test.ts
  • src/main/codex/codex-profile-config-overlay-active-publish.ts
  • src/main/codex/codex-config-mirror.test.ts
  • src/main/rate-limits/codex-fetcher.ts

Comment thread src/main/rate-limits/codex-backend-base-url.ts
Comment thread src/main/rate-limits/codex-backend-base-url.ts
@bbingz
bbingz force-pushed the bbingz/split-7950-auth-rate-limits branch from 29d041e to 7e78a50 Compare July 14, 2026 00:38
@bbingz

bbingz commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto latest origin/main (force-with-lease).

Conflict resolution notes:

  • Merged CLI tsconfig includes with main's expanded codex modules
  • Kept main's real-home test lane helpers; ported file-auth / keyring override coverage
  • Ported custom chatgpt_base_url backend resolution + RPC windowDurationMins/bucket mapping onto main's reset-credit fetcher path
  • Status bar: Codex dynamic buckets no longer hide preferred session/weekly meters (VerboseProviderUsage)
  • Preserved follow-up commits: stale profile overlay cleanup, publish recovery, backend URL query components

@bbingz
bbingz force-pushed the bbingz/split-7950-auth-rate-limits branch 2 times, most recently from 45ff821 to 9a2ffd5 Compare July 24, 2026 08:17
@bbingz

bbingz commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (cda97cec41). One deliberate behavior change worth calling out, since it is not obvious from the diff:

Upstream #10136 (fix(codex): classify rate-limit windows by duration) landed after this PR's base and normalizes near-canonical windows to fixed display durations (300 / 10080). This PR previously preserved the reported 299/10079 values for the preferred session/weekly meters. I yielded to upstream on that point — the preferred meters now use upstream's classification and normalization.

What this PR still contributes on top of upstream: the multi-meter buckets mapping, the auth credentials store, the profile config-overlay mirror (rebased onto upstream's readAgentStateFileSync), and the backend base-URL query-component handling.

One additional commit was needed to adapt to upstream: null-tolerant mapper types plus the buckets test now expecting normalized windows. Happy to restore the original 299/10079 behavior if that was intentional on upstream's side rather than incidental.

@bbingz
bbingz force-pushed the bbingz/split-7950-auth-rate-limits branch from 9a2ffd5 to d5d5a84 Compare July 25, 2026 02:45
bbingz added 2 commits July 25, 2026 10:45
Managed homes inject cli_auth_credentials_store=file so account
switching keeps credentials inside CODEX_HOME; update assertions.
@nwparker nwparker added the bug Something isn't working label Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants