Skip to content

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

Open
bbingz wants to merge 3 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 3 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 branch is rebased onto e5efbc9ff; all three branch commits are range-diff equivalent to their pre-rebase commits.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 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 is concise and matches the main PR focus on Codex auth config and rate-limit handling.
Description check ✅ Passed The description follows the template and includes summary, screenshots, testing, AI review, security, 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants