Skip to content

feat(rotation): sequential drain-first account scheduling mode (#509)#510

Merged
ndycode merged 4 commits into
mainfrom
feat/sequential-account-mode
Jun 4, 2026
Merged

feat(rotation): sequential drain-first account scheduling mode (#509)#510
ndycode merged 4 commits into
mainfrom
feat/sequential-account-mode

Conversation

@ndycode
Copy link
Copy Markdown
Owner

@ndycode ndycode commented Jun 3, 2026

Summary

Implements the optional Sequential / Drain-First scheduling mode requested in #509.

By default the runtime proxy spreads requests across all available accounts (hybrid), so multiple accounts drain at a similar pace and tend to hit cooldown together. This adds an opt-in schedulingStrategy: "sequential" that keeps one active account in use until it is fully exhausted, then advances to the next available account. Earlier accounts are reclaimed as soon as their quota window recovers, staggering recovery across the pool for longer uninterrupted sessions.

Resolves the maintainer-confirmed spec from #509:

  • Switches only when the active account is 100 percent exhausted (rate-limited / cooling down / circuit-open). No soft early-switch threshold in v1.
  • A single active account governs all new requests. Sequential mode intentionally ignores per-session affinity, so once the active account changes every subsequent request follows it regardless of which account started a conversation.
  • A manual pin (codex-multi-auth switch) always takes precedence; sequential mode is ignored while a pin is active.

Behavior

  • hybrid (default, unchanged): weighted health/token/freshness selection across all available accounts.
  • sequential: sticky on the current active account; scans forward (wrapping the pool) only when the active account is exhausted, and pins the next available account as the new active one.

Default is hybrid, so existing deployments are unaffected.

Changes

  • lib/accounts.ts: new getCurrentOrNextForFamilySequential selector. Sticky on currentAccountIndexByFamily; advances only on exhaustion; wraps so a recovered earlier account reclaims the active slot. Per ModelFamily, matching the rest of the selection path.
  • lib/runtime-rotation-proxy.ts: chooseAccount branches on strategy. Pin tier runs first (unchanged); sequential skips the affinity tier; the linear-scan fallback is extracted into a shared helper used by both paths.
  • lib/schemas.ts / lib/config.ts: schedulingStrategy enum (hybrid | sequential, default hybrid), getSchedulingStrategy accessor following the existing routingMutex pattern, CODEX_AUTH_SCHEDULING_STRATEGY env override, and a config-explain parity entry.
  • docs/configuration.md, docs/reference/settings.md, docs/development/CONFIG_FIELDS.md: documented the setting and env override per the add-config-field runbook.

Out of scope (v1)

  • TUI settings picker: the backend settings hub has no enum-key type yet (existing enum strategies routingMutex and fastSessionStrategy are also config plus env only). Reachable via settings file and env var.
  • Soft early-switch threshold: requester confirmed 100 percent exhaustion as the default. The accessor pattern leaves room to add a threshold later.
  • In-flight drain: the proxy is stateless with respect to in-flight request counts, so "drain" means no new selections to the account, not waiting for outstanding requests to finish.

Testing

  • npm run typecheck: pass
  • npm run lint:ts: pass
  • npm test: 4387 passed, 3 skipped (pre-existing), 0 failures
  • npm run build: pass

New tests:

  • Sequential selector: sticky across calls, advances on exhaustion, wraps to a recovered earlier account, returns null when all exhausted.
  • Proxy chooseAccount: sequential ignores session affinity, manual pin wins over sequential, advances when the active account is rate-limited.
  • Config accessor: default, explicit config, env override both directions, invalid env fallback.
  • Updated the five strict default-config toEqual assertions in plugin-config.test.ts for the new key.

Closes #509

note: greptile review for oc-chatgpt-multi-auth. cite files like lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.

Greptile Summary

adds schedulingStrategy: "sequential" (drain-first) as an opt-in alternative to the default hybrid account selection mode. the sequential selector sticks to one active account per model family and only advances to the next when the active account is fully exhausted; it wraps the pool so recovered earlier accounts can reclaim the active slot.

  • lib/accounts.ts – new getCurrentOrNextForFamilySequential selector with per-family sticky pointer, policy-block awareness, and wrap-around scan; lib/runtime-rotation-proxy.tschooseAccount branches on strategy, skips session-affinity tier in sequential mode, and chooseLinearScanFallback is extracted as a shared helper with an advanceActivePointer flag that keeps within-request retries from permanently moving the drain-first primary.
  • lib/schemas.ts / lib/config.tsschedulingStrategy enum field, getSchedulingStrategy accessor, and CODEX_AUTH_SCHEDULING_STRATEGY env override following the routingMutex pattern; three doc files updated.
  • two previously-reviewed P1s are addressed: advanceActivePointer=false prevents transient retry failures from advancing the sequential pointer, and blockedIndexes is now passed into the selector so it never anchors to a policy-blocked account.

Confidence Score: 5/5

safe to merge — all three issues caught in the previous review round are fixed, the new selector and proxy branching are correct, and the test suite covers the critical edge cases including the mutex path and transient-failure non-advance regression.

the sequential selector, chooseAccount branching, and routingMutex re-commit skip have all been verified against documented invariants. advanceActivePointer=false correctly prevents within-request retries from permanently moving the drain-first primary, and the blockedIndexes guard prevents the active pointer anchoring on a policy-blocked account. test coverage is thorough across selector unit tests, chooseAccount unit tests, a real-proxy mutex integration test, and config accessor tests. no token safety or windows filesystem risks introduced.

no files require special attention — lib/runtime-rotation-proxy.ts is the most complex change but the advanceActivePointer flag and mutex skip are both well-tested.

Important Files Changed

Filename Overview
lib/accounts.ts adds getCurrentOrNextForFamilySequential — sticky pointer, wrap-around scan, policy-block guard, and consistent lastUsed stamping; isUsable conditions align exactly with getAccountRuntimeSkipReason, making the outer skip-reason check in chooseAccount a safe belt-and-suspenders guard.
lib/runtime-rotation-proxy.ts sequential branch inserted before session-affinity tier; chooseLinearScanFallback extracted with advanceActivePointer flag; mutex hot-path skips markSwitchedLocked re-commit in sequential mode — all three P1 fixes from earlier review round are present and correct.
lib/config.ts new getSchedulingStrategy follows the same resolveStringSetting + known-values-set pattern as getRoutingMutexMode; env override and invalid-value fallback are both handled; CONFIG_EXPLAIN_ENTRIES entry added for parity.
lib/schemas.ts adds schedulingStrategy: z.enum(["hybrid","sequential"]).optional() to PluginConfigSchema; minimal, correct change.
test/accounts.test.ts 10 new sequential-selector cases covering sticky, exhaustion advance, wrap-around, cooldown, circuit-open, 3-account pool, disabled, unset active index, per-family independence, and the policy-blocked P1 regression; clearCircuitBreakers() in beforeEach prevents cross-test breaker leakage.
test/runtime-rotation-proxy.test.ts adds sequential proxy tests: affinity-ignored, manual-pin-wins, advances-on-exhaustion, no-pointer-advance-on-transient-failure (P1 regression), all-exhausted; plus the mutex-path integration test driving the real proxy with routingMutex=enabled + schedulingStrategy=sequential.
test/scheduling-strategy-config.test.ts new file; covers default, explicit config value, env override in both directions, invalid env fallback to config, and invalid persisted config fallback to default — fully matches the routingMutex config-test pattern.
test/plugin-config.test.ts five strict toEqual assertions updated to include schedulingStrategy: "hybrid" — mechanical but necessary, no issues.
docs/configuration.md added CODEX_AUTH_SCHEDULING_STRATEGY to stable env-override table and added the "Sequential / drain-first scheduling" section — correctly placed per the add-config-field runbook.
docs/reference/settings.md added schedulingStrategy row to proxy settings table and CODEX_AUTH_SCHEDULING_STRATEGY to the env-override list — consistent with existing entries.
docs/development/CONFIG_FIELDS.md added schedulingStrategy row to the runtime-only fields table and CODEX_AUTH_SCHEDULING_STRATEGY to the env var inventory — correct location and format.

Reviews (4): Last reviewed commit: "fix(rotation): keep sequential selector ..." | Re-trigger Greptile

Add an optional schedulingStrategy setting (hybrid | sequential). In
sequential mode the runtime proxy routes every new request to one active
account and only advances to the next available account once the current
one is fully exhausted (rate-limited / cooling down / circuit-open).
Earlier accounts are reclaimed as soon as their quota window recovers,
staggering recovery across the pool for longer uninterrupted sessions.

- accounts.ts: getCurrentOrNextForFamilySequential sticky selector that
  stays on the active account and scans forward (wrapping) only on
  exhaustion
- runtime-rotation-proxy.ts: branch chooseAccount on strategy; sequential
  skips per-session affinity, manual pin still takes precedence; shared
  linear-scan fallback extracted
- config.ts/schemas.ts: schedulingStrategy enum (default hybrid),
  getSchedulingStrategy accessor, CODEX_AUTH_SCHEDULING_STRATEGY env
  override, config-explain parity entry
- docs: configuration, settings reference, and config-field inventory
- tests: sequential selector, proxy affinity-override and pin-precedence,
  config accessor, default-config parity
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 3, 2026

📝 Walkthrough

walkthrough

adds a schedulingStrategy config/env and a sequential (drain-first) account selector; schema/config/getSchedulingStrategy updated (lib/schemas.ts:81, lib/config.ts:1891-1920); AccountManager gets a sequential selector (lib/accounts.ts:792-869); runtime proxy threads mode into chooseAccount and routing-mutex (lib/runtime-rotation-proxy.ts:1217-1260, lib/runtime-rotation-proxy.ts:1874-1893). docs and tests added.

changes

sequential account scheduling

Layer / File(s) Summary
schema and configuration foundation
lib/schemas.ts:81, lib/config.ts:255,1891-1920,2271-2275, test/scheduling-strategy-config.test.ts:1-77, test/plugin-config.test.ts:168-246,672-751,816-822
add schedulingStrategy enum to schema; default DEFAULT_PLUGIN_CONFIG.schedulingStrategy = "hybrid"; export getSchedulingStrategy(pluginConfig) and include it in config-explain output; add tests for env override, invalid values, and defaults (test/scheduling-strategy-config.test.ts:1-77).
sequential account selection logic
lib/accounts.ts:792-869, test/accounts.test.ts:4400-4628
add AccountManager.getCurrentOrNextForFamilySequential(family, model?) implementing drain-first stickiness, forward scan/wrap reclamation, pointer updates, lastUsed stamping, and tests for stickiness, advancement, wrap/reclaim, cooldown/circuit behavior, disabled skipping, per-family independence, and exhausted-pool null (test/accounts.test.ts:4400-4628).
runtime rotation proxy integration
lib/runtime-rotation-proxy.ts:26,1166-1181,1217-1260,1309-1356,1375-1379,1574,1874-1893, test/runtime-rotation-proxy.test.ts:8-11,2355-2414,2471-2622
wire getSchedulingStrategy at startup; extend chooseAccount(...) params with schedulingStrategy; add sequential branch that bypasses session affinity and uses the sequential selector; unify fallback linear-scan with advanceActivePointer control; adjust routing-mutex re-commit to skip cursor advancement in sequential mode; add unit and integration tests covering routing-mutex + sequential behavior (test/runtime-rotation-proxy.test.ts:2355-2414,2471-2622).
documentation updates
docs/configuration.md:77,121-129, docs/development/CONFIG_FIELDS.md:68,77-78,226, docs/reference/settings.md:146,211
document CODEX_AUTH_SCHEDULING_STRATEGY env override and schedulingStrategy config with hybrid vs sequential semantics, pin precedence, and affinity interaction (docs/configuration.md:121-129).

sequenceDiagram(s)

sequenceDiagram
  participant client
  participant runtime_rotation_proxy
  participant account_manager
  participant upstream
  client->>runtime_rotation_proxy: http request
  runtime_rotation_proxy->>runtime_rotation_proxy: getSchedulingStrategy(pluginConfig)
  runtime_rotation_proxy->>account_manager: chooseAccount(..., schedulingStrategy)
  account_manager->>account_manager: getCurrentOrNextForFamilySequential(family)
  account_manager->>runtime_rotation_proxy: ManagedAccount | null
  runtime_rotation_proxy->>upstream: forward request to ManagedAccount
Loading

flags

  • concurrency risks: routing-mutex and non-advancing fallback changes need careful concurrency review. see lib/runtime-rotation-proxy.ts:1874-1893 and lib/runtime-rotation-proxy.ts:1309-1356.
  • missing regression tests: no high-concurrency stress tests for routing-mutex + sequential mode. see test/runtime-rotation-proxy.test.ts:2355-2414 for basic integration but no race coverage.
  • windows edge cases: env-var parsing/casing and windows CRLF handling for CODEX_AUTH_SCHEDULING_STRATEGY not explicitly tested. see lib/config.ts:1891-1920 and test/scheduling-strategy-config.test.ts:1-19.

estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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
Title check ✅ Passed Title clearly summarizes the main change: sequential drain-first scheduling mode, follows conventional commits format with feat type, scope (rotation), and lowercase summary under 72 chars.
Linked Issues check ✅ Passed All primary objectives from #509 are met: sequential routing implemented, automatic failover on exhaustion, pool wrapping for recovery, optional and coexisting with hybrid/pin strategies, compatible with health checks.
Out of Scope Changes check ✅ Passed All changes directly support sequential scheduling: config, schemas, account selection logic, proxy routing, docs, and tests. No unrelated alterations detected.
Description check ✅ Passed PR description is comprehensive and well-structured, covering summary, changes, behavior, testing, and out-of-scope items. All required sections are addressed with sufficient detail and context.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sequential-account-mode
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feat/sequential-account-mode

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 and usage tips.

Comment thread lib/runtime-rotation-proxy.ts Outdated
Comment thread test/runtime-rotation-proxy.test.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

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 `@lib/accounts.ts`:
- Around line 816-856: The sequential selection path currently only checks hard
unavailability via isUsable and will keep draining the active account; update
the sequential logic (the isUsable predicate and the forward scan that uses
currentAccountIndexByFamily, cursorByFamily, and account.lastUsed) to also
consult the same health/token/quota-forecasting signals used by the hybrid path
(i.e., add the hybrid path's health checks to isUsable or call the same
helper(s) the hybrid branch uses) so accounts that are forecasted to exhaust or
are unhealthy are treated as unusable and trigger early failover instead of
being drained to hard limits; keep calls to clearExpiredRateLimits,
hasEnabledWorkspaces, isRateLimitedForFamily, isAccountCoolingDown, and
isCircuitAvailable but augment them with the health/forecast check so the loop
will skip and advance the active index earlier.

In `@test/accounts.test.ts`:
- Around line 4400-4476: Add deterministic regression tests to the existing
getCurrentOrNextForFamilySequential suite that exercise the non-rate-limit
exhaustion paths: create tests that (1) simulate a cooling-down account by
setting its cooldown timestamp (e.g., set account.cooldownUntil or
account.rateLimitResetTimes appropriately) then assert the selector advances to
the next account and later reclaims the cooled account; (2) simulate a
workspace-disabled account by toggling the account.workspaceDisabled flag (or
calling the manager method that marks workspace-disabled) and assert the
selector skips it and switches to the next account; and (3) simulate an
open-circuit/failure by toggling whatever flag the implementation uses for
circuit-open (e.g., account.circuitOpen or calling the manager method that opens
the circuit) and verify failover to the next account and later reclamation when
cleared. Implement these new tests in the same describe block using vitest,
using manager.getAccountByIndex, manager.setActiveIndex,
manager.getCurrentOrNextForFamilySequential, and the corresponding manager
methods/flags to mutate account state so tests remain deterministic and cover
cooldown, workspace-disabled, and circuit-open paths.

In `@test/runtime-rotation-proxy.test.ts`:
- Around line 2418-2431: The test uses an unsafe cast ("as never") when
constructing stored for makeManager which bypasses type checks; update
makeManager to produce a properly typed storage object instead: type the stored
variable as AccountStorageV3 (or Partial<AccountStorageV3> with required fields
filled) and/or create a small factory that returns a valid AccountStorageV3
shape, then pass that to new AccountManager in place of the "as never" cast so
the compiler will catch schema mismatches (refer to makeManager, stored, and
AccountManager).
- Around line 2412-2497: Add a sequential-mode pool exhaustion regression test
in the chooseAccount suite to cover the case where every account is unavailable
and the selector returns null. Reuse the existing makeManager helper and
chooseAccount call pattern, but mark all accounts as rate-limited/exhausted
before invoking sequential scheduling so the assertion verifies no account is
selected. Place it alongside the other "chooseAccount sequential mode (issue
`#509`)" tests so it protects the activeIndex/sessionAffinity/pinnedIndex flow
from future regressions.

In `@test/scheduling-strategy-config.test.ts`:
- Around line 58-65: Add a test that asserts an invalid persisted
schedulingStrategy in PluginConfig is rejected and falls back to the default:
create a cfg object (type PluginConfig) spreading DEFAULT_PLUGIN_CONFIG but set
schedulingStrategy = "bogus", call getSchedulingStrategy(cfg), and expect the
result to equal DEFAULT_PLUGIN_CONFIG.schedulingStrategy; reference
getSchedulingStrategy, PluginConfig, and DEFAULT_PLUGIN_CONFIG to locate the
behavior to cover.
- Line 1: Remove the explicit import of Vitest globals and use the built-in
globals instead: delete the import line that imports describe, it, expect,
beforeEach, afterEach from "vitest" in the test file and rely on the globals
(describe, it, expect, beforeEach, afterEach) already provided to
test/scheduling-strategy-config.test.ts so no further changes to the test
functions are required.
🪄 Autofix (Beta)

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7dc4f200-dbf6-450e-9587-ab4f54174457

📥 Commits

Reviewing files that changed from the base of the PR and between f3d4e7c and 1bc7d99.

📒 Files selected for processing (11)
  • docs/configuration.md
  • docs/development/CONFIG_FIELDS.md
  • docs/reference/settings.md
  • lib/accounts.ts
  • lib/config.ts
  • lib/runtime-rotation-proxy.ts
  • lib/schemas.ts
  • test/accounts.test.ts
  • test/plugin-config.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (20)
docs/reference/**/*.md

📄 CodeRabbit inference engine (docs/DOCUMENTATION.md)

Update relevant command/settings/path references in reference documentation when runtime changes occur

New flags/settings/paths must be reflected in docs/reference/*

Files:

  • docs/reference/settings.md
docs/**/*.md

📄 CodeRabbit inference engine (docs/STYLE_GUIDE.md)

docs/**/*.md: User-facing documentation should follow the page template: Title and one-line lead, Quick path commands, Core operational workflow, Troubleshooting or failure handling, and Related links
Use short sections and scan-friendly tables in documentation where they improve clarity
Prefer direct, actionable language in documentation
Use runnable command examples in documentation
Explain expected outcomes after critical commands in documentation
Keep terminology consistent with runtime names in documentation
Avoid speculative language when behavior is deterministic in documentation
Put the user problem in the first paragraph before implementation detail
Use descriptive page titles such as codex-multi-auth Features instead of generic titles on public docs
Do not repeat keyword lists in every section; search terms should appear only where they help a developer understand the page
Canonical command family is codex-multi-auth ...
Canonical runtime root is ~/.codex/multi-auth
Runtime rotation must be described as default-on unless the release policy changes
Legacy command/path references belong only in migration contexts in documentation
Compatibility aliases (codex multi auth, codex multi-auth, codex multiauth) belong only in command reference, troubleshooting, or migration contexts
Keep command flags aligned with runtime usage text in documentation
Avoid non-runnable command snippets in documentation
Avoid conflicting path guidance across documentation
Avoid legacy-first onboarding language in documentation

Documentation files must follow the directory structure and navigation hierarchy defined in the codex-multi-auth documentation portal, with primary sections organized as: Start Here, Daily Use, Release History, Repair, Reference, Maintainer Docs, and Governance

Files:

  • docs/reference/settings.md
  • docs/configuration.md
  • docs/development/CONFIG_FIELDS.md
docs/reference/{commands,settings,storage-paths,public-api,error-contracts}.md

📄 CodeRabbit inference engine (docs/README.md)

Reference documentation must be maintained in the reference/ directory with specific files for: commands.md (commands, flags, and hotkeys), settings.md (dashboard and runtime settings), storage-paths.md (canonical and compatibility storage paths), public-api.md (public API stability and semver contract), and error-contracts.md (CLI, JSON, and helper error semantics)

Files:

  • docs/reference/settings.md
docs/**

⚙️ CodeRabbit configuration file

keep README, SECURITY, and docs consistent with actual CLI flags and workflows. whenever behavior changes, require updated upgrade notes and mention new npm scripts.

Files:

  • docs/reference/settings.md
  • docs/configuration.md
  • docs/development/CONFIG_FIELDS.md
docs/**/{index,getting-started,faq,features,configuration,architecture,privacy}.md

📄 CodeRabbit inference engine (docs/README.md)

Daily-use documentation must include an index landing page (index.md), getting started guide (getting-started.md), frequently asked questions (faq.md), feature overview (features.md), configuration guide (configuration.md), architecture overview (architecture.md), and privacy policy (privacy.md) to support common workflows and quick reference

Files:

  • docs/configuration.md
lib/**/*.ts

📄 CodeRabbit inference engine (lib/AGENTS.md)

lib/**/*.ts: All public exports should flow through lib/index.ts or documented package subpaths
Never import from dist/ in source tests or library code
Never suppress type errors

Files:

  • lib/schemas.ts
  • lib/accounts.ts
  • lib/config.ts
  • lib/runtime-rotation-proxy.ts
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Do not use as any, @ts-ignore, or @ts-expect-error type assertions

Files:

  • lib/schemas.ts
  • test/runtime-rotation-proxy.test.ts
  • lib/accounts.ts
  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
  • lib/config.ts
  • test/plugin-config.test.ts
  • lib/runtime-rotation-proxy.ts
**/*.{ts,js}

📄 CodeRabbit inference engine (AGENTS.md)

Use ESM module syntax exclusively; the project is ESM-only with "type": "module"

Files:

  • lib/schemas.ts
  • test/runtime-rotation-proxy.test.ts
  • lib/accounts.ts
  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
  • lib/config.ts
  • test/plugin-config.test.ts
  • lib/runtime-rotation-proxy.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

**/*.{ts,tsx,js,jsx}: Override storage root using CODEX_MULTI_AUTH_DIR environment variable instead of hardcoding ~/.codex/multi-auth/ paths
Support alternate config file path via CODEX_MULTI_AUTH_CONFIG_PATH environment variable for flexible configuration locations
Implement request timeout override via CODEX_AUTH_FETCH_TIMEOUT_MS and stream stall timeout via CODEX_AUTH_STREAM_STALL_TIMEOUT_MS environment variables
Ensure OAuth callback listener binds to port 1455 and provide clear error messaging when the port is unavailable
Implement health-aware account selection with quota forecasting and automatic failover to prevent pool cooldowns
Use loopback-only runtime rotation proxy for live account rotation inside forwarded Codex CLI/app sessions
Implement proactive refresh staggering to reduce background refresh bursts and prevent rate-limit storms
Store credentials locally in ~/.codex/multi-auth/ (or custom CODEX_MULTI_AUTH_DIR) without patching official Codex app binaries
Implement session affinity and live account sync to maintain consistent account selection across concurrent requests
Disable whole-pool replay by default when every account is rate-limited to prevent infinite retry loops
Trigger a short cooldown instead of continuing aggressive rotation when repeated cross-account 5xx bursts occur
Implement non-destructive settings operations: preview syncs before apply, preserve destination-only accounts, and fail safely on backup filename collisions
Implement bounded outbound request budget for active requests so one prompt cannot walk the full account pool indefinitely
Support Responses background mode via backgroundResponses setting or CODEX_AUTH_BACKGROUND_RESPONSES=1 for callers intentionally sending background: true requests
Enable runtime rotation by default for request-bearing wrapper-launched Codex sessions and self-heal supported packaged Codex app binds during install/update
Perform best-effort daily npm version checks during forwar...

Files:

  • lib/schemas.ts
  • test/runtime-rotation-proxy.test.ts
  • lib/accounts.ts
  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
  • lib/config.ts
  • test/plugin-config.test.ts
  • lib/runtime-rotation-proxy.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (README.md)

Use TypeScript for type-safe account state management, configuration handling, and OAuth token operations

Files:

  • lib/schemas.ts
  • test/runtime-rotation-proxy.test.ts
  • lib/accounts.ts
  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
  • lib/config.ts
  • test/plugin-config.test.ts
  • lib/runtime-rotation-proxy.ts
lib/**

⚙️ CodeRabbit configuration file

focus on auth rotation, windows filesystem IO, and concurrency. verify every change cites affected tests (vitest) and that new queues handle EBUSY/429 scenarios. check for logging that leaks tokens or emails.

Files:

  • lib/schemas.ts
  • lib/accounts.ts
  • lib/config.ts
  • lib/runtime-rotation-proxy.ts
docs/development/**/*.md

📄 CodeRabbit inference engine (docs/DOCUMENTATION.md)

Update development docs when architecture, config flow, or GitHub-facing metadata guidance changes

docs/development/**/*.md: Verify every command snippet in documentation is runnable and cross-check path references against runtime modules
Confirm cross-links are valid in documentation

Files:

  • docs/development/CONFIG_FIELDS.md
docs/development/CONFIG_FIELDS.md

📄 CodeRabbit inference engine (docs/development/RUNBOOK_ADD_CONFIG_FIELD.md)

Update docs/development/CONFIG_FIELDS.md with field inventory details when adding new configuration fields

Maintain full field inventory in docs/development/CONFIG_FIELDS.md

Files:

  • docs/development/CONFIG_FIELDS.md
docs/development/**/{DOCUMENTATION,ARCHITECTURE,CONFIG_FIELDS}.md

📄 CodeRabbit inference engine (docs/development/TESTING.md)

Keep feature matrix in documentation in sync with implemented features

Files:

  • docs/development/CONFIG_FIELDS.md
docs/development/{ARCHITECTURE,GITHUB_DISCOVERABILITY,IA_FINDABILITY_AUDIT_*,CONFIG_FIELDS,CONFIG_FLOW,REPOSITORY_SCOPE,TESTING,TUI_PARITY_CHECKLIST}.md

📄 CodeRabbit inference engine (docs/README.md)

Development and maintainer documentation in the development/ directory must include architectural guidance (ARCHITECTURE.md), GitHub discoverability guidance (GITHUB_DISCOVERABILITY.md), information architecture audits (IA_FINDABILITY_AUDIT_*.md), configuration inventory (CONFIG_FIELDS.md), configuration flow documentation (CONFIG_FLOW.md), repository scope mapping (REPOSITORY_SCOPE.md), testing and validation guidance (TESTING.md), and UI parity checklists (TUI_PARITY_CHECKLIST.md)

Files:

  • docs/development/CONFIG_FIELDS.md
test/**/*.test.ts

📄 CodeRabbit inference engine (test/AGENTS.md)

test/**/*.test.ts: Vitest globals (describe, it, expect) are enabled and should be used without explicit imports
Maintain 80% coverage threshold across statements, branches, functions, and lines
Use removeWithRetry for Windows filesystem cleanup instead of bare fs.rm to handle EBUSY/EPERM/ENOTEMPTY backoff
Use source files in tests, not compiled dist/ files; test the source directly
Do not skip tests without justification; include rationale if a test must be skipped
Relax ESLint rules for test files as specified in eslint.config.js

Files:

  • test/runtime-rotation-proxy.test.ts
  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
  • test/plugin-config.test.ts
test/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Windows filesystem operations must include retry handling for transient EBUSY, EPERM, and ENOTEMPTY errors where tests cover Windows locks

Files:

  • test/runtime-rotation-proxy.test.ts
  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
  • test/plugin-config.test.ts
test/**

⚙️ CodeRabbit configuration file

tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.

Files:

  • test/runtime-rotation-proxy.test.ts
  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
  • test/plugin-config.test.ts
lib/accounts*.ts

📄 CodeRabbit inference engine (lib/AGENTS.md)

Account health is 0-100 and should be updated through the account manager APIs

Files:

  • lib/accounts.ts
lib/runtime-rotation-proxy.ts

📄 CodeRabbit inference engine (lib/AGENTS.md)

lib/runtime-rotation-proxy.ts: Runtime rotation code must preserve pass-through semantics except for auth/provider headers that intentionally change
Runtime proxy client-facing headers must not expose account emails or tokens
Runtime rotation should fail open to normal official Codex forwarding when startup helpers are unavailable
Never add account emails/tokens to runtime proxy client responses

Do not expose account emails or tokens in runtime proxy client response headers or logs

Files:

  • lib/runtime-rotation-proxy.ts
🧠 Learnings (52)
📓 Common learnings
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.0.md:0-0
Timestamp: 2026-06-03T14:30:16.504Z
Learning: Implement Codex-first multi-account OAuth operations for the first stable `codex-multi-auth` release
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.1.10.md:0-0
Timestamp: 2026-06-03T14:31:27.756Z
Learning: Implement `codex auth best` command for forecast-driven active-account switching in CLI
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement health-aware account selection with quota forecasting and automatic failover to prevent pool cooldowns
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{auth,routing,selection}/**/*.{js,ts,tsx} : Implement feature-flagged routing mutex and `SelectionRecord` plumbing for safer concurrent account selection
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{rotation,account,selection}*.{js,ts,jsx,tsx} : Implement minRotationIntervalMs sticky window with a configurable sliding anchor (CODEX_AUTH_MIN_ROTATION_INTERVAL_MS / minRotationIntervalMs, default 60s) to boost the last-served account so back-to-back requests are less likely to present a different OAuth token from the same IP
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.0-beta.0.md:0-0
Timestamp: 2026-06-03T14:30:11.312Z
Learning: Implement the `codex-multi-auth` `codex auth ...` account workflow
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.test.{ts,tsx,js} : Extend `chooseAccount` unit test suite to cover every pinned skip reason returned by `AccountManager.getAccountRuntimeSkipReason`: `rate-limited`, `cooling-down:auth-failure`, `disabled`, `workspace-disabled`, `circuit-open`, `policy-blocked`, `missing`, `already-attempted`
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: Runtime configuration is resolved from unified settings at `~/.codex/multi-auth/settings.json`, optional override files via `CODEX_MULTI_AUTH_CONFIG_PATH` environment variable, and environment variables
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: Settings file at `~/.codex/multi-auth/settings.json` must follow the canonical JSON schema with `version`, `dashboardDisplaySettings`, and `pluginConfig` keys
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: Keep `menuAutoFetchLimits`, `menuSortEnabled`, `liveAccountSync`, `sessionAffinity`, `proactiveRefreshGuardian`, and `preemptiveQuotaEnabled` enabled for most environments
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: Use `CODEX_MULTI_AUTH_DIR` environment variable to override root directory for multi-auth-managed runtime files
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: Use `CODEX_AUTH_MIN_ROTATION_INTERVAL_MS` environment variable (default `60000`) to configure minimum time between global account switches, or set to `0` to disable the rotation-rate throttle
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: Use `CODEX_AUTH_SCHEDULING_STRATEGY` environment variable set to `hybrid` (default) or `sequential` to control account scheduling strategy, where `sequential` mode drains one account before advancing to the next
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: Set `CODEX_AUTH_TOKEN_INVALIDATION_COOLDOWN_MS` (default `300000`, 5 minutes) to configure the cooldown applied when the upstream or token-refresh endpoint explicitly revokes an OAuth token
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: Enable `codexRuntimeRotationProxy` by default or via `CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY=1` to start a localhost-only Responses proxy for forwarded Codex sessions
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: When implementing token-invalidation detection in the proxy, return the error directly to the client instead of rotating to the next account and apply a 5-minute cooldown (`tokenInvalidationCooldownMs`) to the affected account
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: In sequential scheduling mode, route every new request to one active account and only advance to the next available account once the current one is fully exhausted (rate-limited, cooling down, or circuit-open)
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: For `codex app` launches through the wrapper, automatically start a small internal helper so rotation can keep working if the desktop app launcher detaches, and use the same per-session proxy client key as the CLI path
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:44:59.901Z
Learning: Use `codex-multi-auth status`, `codex-multi-auth list`, `codex-multi-auth check`, and `codex-multi-auth forecast --live` commands to validate effective configuration
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:22.033Z
Learning: Use environment variable `CODEX_MULTI_AUTH_DIR` to specify custom root directory for settings, accounts, cache, and logs
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:22.033Z
Learning: Use environment variable `CODEX_MULTI_AUTH_CONFIG_PATH` to specify alternate config file input path
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:22.033Z
Learning: Use environment variable `CODEX_MODE` to toggle Codex mode
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Store dashboard display settings and runtime pluginConfig values in `~/.codex/multi-auth/settings.json` at the top level under `dashboardDisplaySettings` and `pluginConfig` objects
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: When CODEX_MULTI_AUTH_DIR is set, the settings file root moves accordingly from the default ~/.codex/multi-auth/settings.json location
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Configure account list view display behavior using keys: menuShowStatusBadge, menuShowCurrentBadge, menuShowLastUsed, menuShowQuotaSummary, menuShowQuotaCooldown, menuShowFetchStatus, menuShowDetailsForUnselectedRows, menuHighlightCurrentRow, menuSortEnabled, menuSortMode, menuSortPinCurrent, menuSortQuickSwitchVisibleRow, and menuLayoutMode
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Control summary line fields in account rows using menuStatuslineFields with default value 'last-used, limits, status' to specify order and presence
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Use actionAutoReturnMs for delay before returning from action/result screens, actionPauseOnKey to pause on keypress, menuAutoFetchLimits to refresh quota automatically, and menuQuotaTtlMs for quota cache reuse
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Configure color theme using uiThemePreset, uiAccentColor, and menuFocusStyle settings
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Use experimental shortcuts (1 for sync preview, 2 for named backup, 3 for refresh guard, [/- to decrease interval, ]/ + to increase interval, S to save, Q to go back, A to apply) in the experimental settings interface
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: In named backup export, prompt for filename, append .json when omitted, reject separators and traversal paths (..), and reject .rotate., .tmp, and .wal suffixes to fail safely on collisions
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Enable liveAccountSync to watch account storage for external changes, configured with liveAccountSyncDebounceMs (default 250) and liveAccountSyncPollMs (default 2000) for fallback polling
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Use sessionAffinity to keep sessions sticky to recent accounts, configured with sessionAffinityTtlMs (default 1200000) for retention window and sessionAffinityMaxEntries (default 512) for cache size
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Use perProjectAccounts set to true to scope account pools per project when CLI sync is off
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Configure account scheduling strategy using schedulingStrategy set to 'hybrid' (spreads load across accounts) or 'sequential' (drain-first keeps one active until exhausted)
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Enable codexRuntimeRotationProxy to activate the default-on localhost Responses proxy for forwarded official Codex CLI/app sessions
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Configure preemptive quota deferral using preemptiveQuotaEnabled, preemptiveQuotaRemainingPercent5h, preemptiveQuotaRemainingPercent7d, and preemptiveQuotaMaxDeferralMs thresholds
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Configure retry behavior for rate-limited accounts using retryAllAccountsRateLimited, retryAllAccountsMaxWaitMs, and retryAllAccountsMaxRetries
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Configure token refresh behavior using tokenRefreshSkewMs (default 60000) to refresh before expiry
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Enable proactiveRefreshGuardian to run background refresh checks, configured with proactiveRefreshIntervalMs (default 60000) for polling interval and proactiveRefreshBufferMs (default 300000) for refresh-before-expiry buffer
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Enable storageBackupEnabled to write rotating account-storage backups and sessionRecovery to restore recoverable conversation state
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Enable autoResume to automatically resume recoverable sessions
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Configure parallel probing using parallelProbing flag and parallelProbingMaxConcurrency (default 2) to control concurrency cap
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Enable fastSession and configure fastSessionStrategy (default 'hybrid') and fastSessionMaxInputItems (default 30) to cap history items in fast-session mode
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Configure retry behavior for empty/invalid responses using emptyResponseMaxRetries (default 2) and emptyResponseRetryDelayMs (default 1000)
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Configure timeout settings using fetchTimeoutMs (default 60000) for request timeout and streamStallTimeoutMs (default 45000) for stream stall timeout
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Configure cooldown periods using networkErrorCooldownMs (default 6000) after network failures and serverErrorCooldownMs (default 4000) after server failures
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Use environment variables CODEX_MULTI_AUTH_DIR, CODEX_MULTI_AUTH_CONFIG_PATH, CODEX_MODE, CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY, CODEX_MULTI_AUTH_APP_ROTATION_IDLE_MS, CODEX_MULTI_AUTH_APP_BIND_INSTALL, CODEX_MULTI_AUTH_APP_LAUNCHER_INSTALL, CODEX_TUI_V2, CODEX_TUI_COLOR_PROFILE, CODEX_TUI_GLYPHS, CODEX_AUTH_FETCH_TIMEOUT_MS, CODEX_AUTH_STREAM_STALL_TIMEOUT_MS for stable environment overrides
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Expect installed wrappers to perform best-effort daily npm version checks during Codex startup and print 'npm install -g codex-multi-authlatest' if newer version detected without mutating the installed package
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Use advanced and internal environment overrides CODEX_MULTI_AUTH_SYNC_CODEX_CLI, CODEX_MULTI_AUTH_REAL_CODEX_BIN, CODEX_MULTI_AUTH_BYPASS, CODEX_AUTH_SCHEDULING_STRATEGY, CODEX_CLI_ACCOUNTS_PATH, CODEX_CLI_AUTH_PATH, and refresh lease controls for maintainer/debug purposes
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: Enable smart sort, auto-fetch limits, live sync, session affinity, preemptive quota deferral, and proactive refresh guardian for recommended defaults in most environments
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-03T20:45:47.326Z
Learning: After settings changes, validate configuration by running 'codex-multi-auth status', 'codex-multi-auth check', and 'codex-multi-auth forecast --live'
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{rotation,account,selection}*.{js,ts,jsx,tsx} : Implement minRotationIntervalMs sticky window with a configurable sliding anchor (CODEX_AUTH_MIN_ROTATION_INTERVAL_MS / minRotationIntervalMs, default 60s) to boost the last-served account so back-to-back requests are less likely to present a different OAuth token from the same IP

Applied to files:

  • docs/reference/settings.md
  • docs/configuration.md
  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:32:52.933Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.1.md:0-0
Timestamp: 2026-06-03T14:32:52.933Z
Learning: Harden request, auth, account, recovery, storage, settings, UI, and shutdown behavior around rate-limit backoff, token redaction, SSE buffering, account removal, manual-paste state, import size caps, Q hotkeys, OAuth state checks, retry writes, and cleanup idempotency

Applied to files:

  • docs/reference/settings.md
  • docs/configuration.md
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use loopback-only runtime rotation proxy for live account rotation inside forwarded Codex CLI/app sessions

Applied to files:

  • docs/reference/settings.md
  • docs/configuration.md
  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T10:57:53.412Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 0
File: :0-0
Timestamp: 2026-06-03T10:57:53.412Z
Learning: In ndycode/codex-multi-auth, the ordered quota-probe model fallback list is exported as `QUOTA_PROBE_MODEL_CHAIN` from `lib/request/helpers/model-map.ts` (added in commit `3239f71`, PR `#506` round 6). Both `lib/quota-probe.ts` and `lib/runtime/quota-probe.ts` import this single constant so the candidate model order (`DEFAULT_MODEL` / `gpt-5.5`, `gpt-5.4`, `gpt-5.3-codex`, `gpt-5.2-codex`, `gpt-5-codex`) can never drift between manager-side and runtime-side probes.

Applied to files:

  • docs/reference/settings.md
  • docs/development/CONFIG_FIELDS.md
  • test/runtime-rotation-proxy.test.ts
  • lib/accounts.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:31:27.756Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.1.10.md:0-0
Timestamp: 2026-06-03T14:31:27.756Z
Learning: Implement `codex auth best` command for forecast-driven active-account switching in CLI

Applied to files:

  • docs/reference/settings.md
  • docs/configuration.md
📚 Learning: 2026-06-03T14:30:16.504Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.0.md:0-0
Timestamp: 2026-06-03T14:30:16.504Z
Learning: Implement canonical `codex auth ...` command family for account lifecycle management

Applied to files:

  • docs/reference/settings.md
  • docs/configuration.md
  • docs/development/CONFIG_FIELDS.md
📚 Learning: 2026-06-03T14:31:00.082Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.6.md:0-0
Timestamp: 2026-06-03T14:31:00.082Z
Learning: Align Codex CLI sync default paths with `CODEX_HOME` to prevent auth writes from going to a different profile directory.

Applied to files:

  • docs/reference/settings.md
  • docs/development/CONFIG_FIELDS.md
📚 Learning: 2026-06-03T14:30:44.405Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.4.md:0-0
Timestamp: 2026-06-03T14:30:44.405Z
Learning: Stabilize `codex auth switch <index>` command and host auth sync to ensure local account selection remains deterministic while sync failures are reported clearly

Applied to files:

  • docs/reference/settings.md
  • docs/configuration.md
  • docs/development/CONFIG_FIELDS.md
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Validate command configuration after changes with `codex-multi-auth status`, `codex-multi-auth check`, and `codex-multi-auth forecast --live`

Applied to files:

  • docs/reference/settings.md
📚 Learning: 2026-06-03T14:30:11.312Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.0-beta.0.md:0-0
Timestamp: 2026-06-03T14:30:11.312Z
Learning: Implement the `codex-multi-auth` `codex auth ...` account workflow

Applied to files:

  • docs/reference/settings.md
  • docs/configuration.md
📚 Learning: 2026-06-03T14:30:37.477Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.3.md:0-0
Timestamp: 2026-06-03T14:30:37.477Z
Learning: Fixed `codex auth switch <index>` so local account switching remains successful even when Codex host-state sync is unavailable.

Applied to files:

  • docs/reference/settings.md
  • docs/configuration.md
  • docs/development/CONFIG_FIELDS.md
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Support alternate config file path via `CODEX_MULTI_AUTH_CONFIG_PATH` environment variable for flexible configuration locations

Applied to files:

  • docs/reference/settings.md
  • docs/configuration.md
  • docs/development/CONFIG_FIELDS.md
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Keep the official `codex` command owned by OpenAI install path; only use `codex-multi-auth-codex` wrapper when intentionally forwarding to official CLI

Applied to files:

  • docs/reference/settings.md
📚 Learning: 2026-06-03T14:30:16.504Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.0.md:0-0
Timestamp: 2026-06-03T14:30:16.504Z
Learning: Implement Codex-first multi-account OAuth operations for the first stable `codex-multi-auth` release

Applied to files:

  • docs/reference/settings.md
  • docs/configuration.md
📚 Learning: 2026-06-03T14:33:39.172Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Pinned-account 503 (`codex_pinned_account_unavailable`) must carry a structured `reason` field and a full `account_skip_reasons` map keyed by account index, mirroring the existing `writePoolExhausted` shape

Applied to files:

  • docs/configuration.md
  • docs/development/CONFIG_FIELDS.md
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement request timeout override via `CODEX_AUTH_FETCH_TIMEOUT_MS` and stream stall timeout via `CODEX_AUTH_STREAM_STALL_TIMEOUT_MS` environment variables

Applied to files:

  • docs/configuration.md
  • docs/development/CONFIG_FIELDS.md
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{auth,token,cooldown,config}*.{js,ts,jsx,tsx} : Apply a long cooldown (5 minutes / CODEX_AUTH_TOKEN_INVALIDATION_COOLDOWN_MS / tokenInvalidationCooldownMs) on invalidated accounts versus the generic 30-second auth-failure cooldown, using monotonic cooldown that only extends, never shortens

Applied to files:

  • docs/configuration.md
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{rotation,account,failover,fallback}*.{js,ts,jsx,tsx} : Stop cascade rotation on token invalidation - return the 401 directly to the client instead of rotating to the next account when invalidation is detected

Applied to files:

  • docs/configuration.md
  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-03T14:33:12.019Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.10.md:0-0
Timestamp: 2026-06-03T14:33:12.019Z
Learning: Runtime pool exhaustion on `no-account` should reset volatile runtime trackers, reload accounts from disk once, and retry selection even when stale in-memory circuit breakers are open to prevent long-lived proxies from staying wedged after disk state has recovered

Applied to files:

  • docs/configuration.md
  • docs/development/CONFIG_FIELDS.md
  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:32:03.085Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.2.3.md:0-0
Timestamp: 2026-06-03T14:32:03.085Z
Learning: Fix usage-limit cooldown persistence across account state, fallback 429 handling, and quota scheduling without dropping secondary quota state.

Applied to files:

  • docs/configuration.md
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement health-aware account selection with quota forecasting and automatic failover to prevent pool cooldowns

Applied to files:

  • docs/development/CONFIG_FIELDS.md
  • test/runtime-rotation-proxy.test.ts
  • lib/accounts.ts
  • test/accounts.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Override storage root using `CODEX_MULTI_AUTH_DIR` environment variable instead of hardcoding `~/.codex/multi-auth/` paths

Applied to files:

  • docs/development/CONFIG_FIELDS.md
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Store credentials locally in `~/.codex/multi-auth/` (or custom `CODEX_MULTI_AUTH_DIR`) without patching official Codex app binaries

Applied to files:

  • docs/development/CONFIG_FIELDS.md
📚 Learning: 2026-06-03T14:34:33.388Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.0.md:0-0
Timestamp: 2026-06-03T14:34:33.388Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Allow toggling status line with CODEX_MULTI_AUTH_STATUSLINE environment variable

Applied to files:

  • docs/development/CONFIG_FIELDS.md
📚 Learning: 2026-06-03T14:31:07.275Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.7.md:0-0
Timestamp: 2026-06-03T14:31:07.275Z
Learning: Initialize and maintain consolidated codex-multi-auth runtime, TUI, account-management, and documentation surfaces

Applied to files:

  • docs/development/CONFIG_FIELDS.md
📚 Learning: 2026-06-03T14:33:39.172Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.test.{ts,tsx,js} : Extend `chooseAccount` unit test suite to cover every pinned skip reason returned by `AccountManager.getAccountRuntimeSkipReason`: `rate-limited`, `cooling-down:auth-failure`, `disabled`, `workspace-disabled`, `circuit-open`, `policy-blocked`, `missing`, `already-attempted`

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • lib/accounts.ts
  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:33:39.172Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.e2e.{ts,tsx,js} : Add end-to-end regression coverage for pinned-503 rate-limited and cooling-down paths; extend existing disabled-account test to assert the new structured fields

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
  • test/plugin-config.test.ts
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement session affinity and live account sync to maintain consistent account selection across concurrent requests

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • lib/accounts.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:32:44.663Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{auth,routing,selection}/**/*.{js,ts,tsx} : Implement feature-flagged routing mutex and `SelectionRecord` plumbing for safer concurrent account selection

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • lib/accounts.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:32:44.663Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{account,recovery,state}/**/*.{js,ts,tsx} : Implement short-429 retry ordering, active-pointer normalization, and recovery atomic writes in account handling

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • lib/accounts.ts
  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:31:07.275Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.7.md:0-0
Timestamp: 2026-06-03T14:31:07.275Z
Learning: Ensure regression test coverage across account switching, build/test paths, update resilience, auth sync, storage, and wrapper paths

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{session,affinity,routing}*.{js,ts,jsx,tsx} : Clear session affinity on token invalidation so the next request can pick a healthy account

Applied to files:

  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-03T14:34:33.388Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.0.md:0-0
Timestamp: 2026-06-03T14:34:33.388Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Bind rotation proxy and local bridge loopback-only with no opt-out, normalize IPv6 loopback for bind and base URL, and never forward inbound credentials (authorization, x-api-key, cookie, proxy-authorization) upstream

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:34:15.851Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.9.md:0-0
Timestamp: 2026-06-03T14:34:15.851Z
Learning: Applies to docs/releases/**/*cli*/**/*.{js,ts,jsx,tsx} : CLI login flow should exit cleanly after displaying the account limit message when reaching `ACCOUNT_LIMITS.MAX_ACCOUNTS` (20) during explicit-mode account addition, preventing silent restart of sign-in sessions

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • lib/accounts.ts
  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:34:15.851Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.9.md:0-0
Timestamp: 2026-06-03T14:34:15.851Z
Learning: Applies to docs/releases/**/*cli*/**/*.{js,ts,jsx,tsx} : CLI login flow should exit cleanly when user declines 'Add another account?' after successful explicit-mode account addition, preventing re-entry into transport selection

Applied to files:

  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-03T14:33:50.590Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.1.md:0-0
Timestamp: 2026-06-03T14:33:50.590Z
Learning: Applies to docs/releases/**/*account*.{ts,tsx,js} : `formatAccountLabel` must surface the active workspace name to keep same-email accounts in different workspaces distinguishable, using format like `Account 1 ([Personal Plus], usergmail.com, id:g-AAAA)`

Applied to files:

  • lib/accounts.ts
📚 Learning: 2026-06-03T14:32:44.663Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{storage,account}/**/*.{js,ts,tsx} : Implement account pointer cleanup as part of storage management

Applied to files:

  • lib/accounts.ts
  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:31:55.434Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.2.2.md:0-0
Timestamp: 2026-06-03T14:31:55.434Z
Learning: Tightened stable identity reconciliation for guardian refresh outcomes, runtime tracker state, fresh-family selection, and expired CLI cache hydration

Applied to files:

  • lib/accounts.ts
📚 Learning: 2026-06-03T14:33:00.811Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.2.md:0-0
Timestamp: 2026-06-03T14:33:00.811Z
Learning: Applies to docs/releases/**/*.{test,spec}.{js,ts,mjs,mts} : Add regression coverage for explicit no-capture forwarding, explicit capture forwarding, unsupported-model retries, and fixture-pinned `CODEX_HOME` isolation

Applied to files:

  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
  • test/plugin-config.test.ts
📚 Learning: 2026-06-03T14:33:50.590Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.1.md:0-0
Timestamp: 2026-06-03T14:33:50.590Z
Learning: Applies to docs/releases/**/*.{test,spec}.{ts,tsx,js} : Write schema round-trip preservation tests to ensure account metadata schema fields survive load/save cycles

Applied to files:

  • test/accounts.test.ts
  • test/plugin-config.test.ts
📚 Learning: 2026-06-03T14:33:39.172Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.test.{ts,tsx,js} : Add direct unit coverage for `buildPinnedUnavailableErrorBody` across empty-map (`reason: null`), populated-map, null-`pinnedIndex`, and mismatched-pinned-entry shapes

Applied to files:

  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*.{test,spec}.{js,ts,jsx,tsx} : Write unit tests for minRotationIntervalMs sliding-anchor and sticky-window coverage, schema and config coverage for both new knobs (min(0), allows-zero, rejects-string)

Applied to files:

  • test/accounts.test.ts
  • test/scheduling-strategy-config.test.ts
  • test/plugin-config.test.ts
📚 Learning: 2026-06-03T14:33:26.552Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.12.md:0-0
Timestamp: 2026-06-03T14:33:26.552Z
Learning: Applies to docs/releases/**/*.test.{js,ts} : Add regression coverage for literal TOML keys, CRLF preservation, table-like content inside strings and arrays, alternate hook paths, long hook keys, shadow `hooks.json` visibility, and concurrent runtime shadow launches

Applied to files:

  • test/scheduling-strategy-config.test.ts
  • test/plugin-config.test.ts
📚 Learning: 2026-06-03T14:32:44.663Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/*.test.{js,ts,tsx} : Validate staging environment with comprehensive test coverage and real-install smoke testing

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:33:50.590Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.1.md:0-0
Timestamp: 2026-06-03T14:33:50.590Z
Learning: Applies to docs/releases/**/*.{test,spec}.{ts,tsx,js} : Write workspace-load regression tests to lock in the fix for workspace data persistence

Applied to files:

  • test/scheduling-strategy-config.test.ts
  • test/plugin-config.test.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*.{test,spec}.{js,ts,jsx,tsx} : Write unit tests covering eight cases for the invalidation body builder: top-level message, nested error.message, top-level-wins priority, blank-to-nested fallback, non-JSON body, and no-usable-message fallback

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*.{test,spec}.{js,ts,jsx,tsx} : Write unit tests for upstream-401 invalidation that verify it returns 401 to the client, applies the ~5-minute cooldown, clears affinity, and does not rotate; and that generic 401 still rotates

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:33:20.602Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.11.md:0-0
Timestamp: 2026-06-03T14:33:20.602Z
Learning: Applies to docs/releases/**/{test,tests,__tests__,*.test.*,*.spec.*}/**/* : Implement a focused plugin manifest integrity test that validates JSON parsing, package-version parity, and icon path resolution

Applied to files:

  • test/plugin-config.test.ts
📚 Learning: 2026-06-03T14:34:33.388Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.0.md:0-0
Timestamp: 2026-06-03T14:34:33.388Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Remove Atomics.wait sleeps from config-load and logger retry paths to prevent event loop blocking

Applied to files:

  • test/plugin-config.test.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{rotation,account,selection}*.{js,ts,jsx,tsx} : Refresh the minRotationIntervalMs anchor on every successful serve, not only on account change

Applied to files:

  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:34:49.238Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.1.md:0-0
Timestamp: 2026-06-03T14:34:49.238Z
Learning: Applies to docs/releases/**/*routing*.js : Close routing selection races by running selection and cursor commit in a single reentrant mutex acquisition

Applied to files:

  • lib/runtime-rotation-proxy.ts
🔇 Additional comments (11)
docs/configuration.md (1)

77-77: LGTM!

Also applies to: 121-129

docs/development/CONFIG_FIELDS.md (1)

68-68: LGTM!

Also applies to: 77-77, 226-226

docs/reference/settings.md (1)

146-146: LGTM!

Also applies to: 211-211

lib/runtime-rotation-proxy.ts (4)

1217-1253: LGTM!


1303-1357: LGTM!


1545-1545: LGTM!


1845-1845: LGTM!

test/runtime-rotation-proxy.test.ts (4)

8-11: LGTM!


2433-2455: LGTM!

Also applies to: 2457-2476


2478-2497: ⚡ Quick win

request a direct check of accountmanager.setactiveindex return contract

test/runtime-rotation-proxy.test.ts:2480 uses manager.setActiveIndex(0)! as if it returns the managed account; if setActiveIndex ever returns void/undefined, manager.markRateLimited(...) is exercised with the wrong value and the test can fail for the wrong reason (or stop validating rotation behavior).

add a concurrency regression next to the current single-threaded case (test/runtime-rotation-proxy.test.ts:2478-2497): two parallel requests exhausting the same active account should both trigger deterministic advancement (and stay consistent with session-affinity on/off).

also ensure the chooseAccount rotation tests cover every pinned skip reason from AccountManager.getAccountRuntimeSkipReason: rate-limited, cooling-down:auth-failure, disabled, workspace-disabled, circuit-open, policy-blocked, missing, already-attempted.


2439-2439: ⚡ Quick win

fix session affinity remember call arity

  • test/runtime-rotation-proxy.test.ts:2439 calls affinity.remember("session-xyz", 1) with 2 args; match the SessionAffinityStore.remember signature from lib/runtime-rotation-proxy.ts:2241-2244 (if it takes a now/timestamp, pass it explicitly) to avoid nondeterministic affinity behavior across sequential requests.
  • add regression tests for sequential-mode pool exhaustion and concurrent sequential requests, so affinity pin/advancement doesn’t regress when the active account runs out.
proposed fix
-		affinity.remember("session-xyz", 1);
+		affinity.remember("session-xyz", 1, Date.now());

Comment thread lib/accounts.ts
Comment thread test/accounts.test.ts
Comment thread test/runtime-rotation-proxy.test.ts
Comment thread test/runtime-rotation-proxy.test.ts
Comment thread test/scheduling-strategy-config.test.ts
Comment thread test/scheduling-strategy-config.test.ts
…509)

Review found a P1: in sequential mode, when the active account is healthy
but already in attemptedIndexes for the current request (e.g. a transient,
non-exhausting failure that refunds the token with no cooldown), chooseAccount
fell through to chooseLinearScanFallback, which called markSwitched on the
fallback pick and permanently moved currentAccountIndexByFamily. The next
request then stuck to the fallback account even though the primary was never
exhausted, breaking the drain-first guarantee.

- chooseLinearScanFallback gains advanceActivePointer (default true keeps the
  hybrid round-robin advance); sequential passes false so a within-request
  retry finds an account to try without reassigning the primary
- skip the hot-path markSwitchedLocked re-commit in sequential mode under
  routingMutex=enabled; the sequential selector already committed the correct
  active index inside the held mutex

Tests:
- proxy: healthy-but-attempted active account does not move the primary
  (validated to fail without the fix), sequential pool exhaustion returns null
- proxy: sequential sticks to one account across requests under
  routingMutex=enabled (exercises the markSwitchedLocked path)
- selector: cooldown and circuit-open failover plus reclamation on recovery
- config: invalid persisted schedulingStrategy falls back to hybrid
Comment thread lib/runtime-rotation-proxy.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
test/accounts.test.ts (1)

4477-4510: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

add the missing workspace-disabled sequential regression.

this suite now covers rate-limit, cooldown, and circuit-open, but the drain-first selector in lib/accounts.ts:792-859 also treats !hasEnabledWorkspaces(account) as exhaustion. without a case that disables every workspace on the active account, a regression in the workspace-disabled failover path will still stay green here. add a deterministic sequential test that fails over when the active account has no enabled workspaces and then reclaims it after recovery.

As per coding guidelines: test/**: tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior.

🤖 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 `@test/accounts.test.ts` around lines 4477 - 4510, Add a deterministic
sequential test that exercises the "workspace-disabled" exhaustion path: create
an AccountManager, setActiveIndex(0) to make account0 active, then disable all
workspaces for that account (so hasEnabledWorkspaces(account0) would be false),
call getCurrentOrNextForFamilySequential("codex") and assert the selector
advances to index 1 and that getActiveIndexForFamily("codex") is 1; then
re-enable a workspace for account0 (so it no longer fails hasEnabledWorkspaces),
call getCurrentOrNextForFamilySequential("codex") again and assert it reclaims
index 0. Use the existing helpers in the file (AccountManager, setActiveIndex,
getAccountByIndex, getCurrentOrNextForFamilySequential, getActiveIndexForFamily)
and keep the test deterministic with no timing or async 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 `@lib/runtime-rotation-proxy.ts`:
- Around line 1242-1257: The sequential fallback path (chooseLinearScanFallback
called with advanceActivePointer: false) can still cause persistent/mutex-side
active-selection changes; propagate a "temporarySequentialFallback" signal from
chooseLinearScanFallback back to the caller and into persistRuntimeActiveAccount
so that when temporarySequentialFallback is true you skip calling
markSwitchedLocked(...) and skip enqueueing
syncCodexCliActiveSelectionForIndex(account.index); update
getCurrentOrNextForFamilySequential and any callers that call
persistRuntimeActiveAccount to pass the flag through, and guard the branches
that commit the cursor or push CLI sync so they no-op when
temporarySequentialFallback is set (ensuring only true exhaustion advances the
active pointer and triggers CLI sync).

---

Duplicate comments:
In `@test/accounts.test.ts`:
- Around line 4477-4510: Add a deterministic sequential test that exercises the
"workspace-disabled" exhaustion path: create an AccountManager,
setActiveIndex(0) to make account0 active, then disable all workspaces for that
account (so hasEnabledWorkspaces(account0) would be false), call
getCurrentOrNextForFamilySequential("codex") and assert the selector advances to
index 1 and that getActiveIndexForFamily("codex") is 1; then re-enable a
workspace for account0 (so it no longer fails hasEnabledWorkspaces), call
getCurrentOrNextForFamilySequential("codex") again and assert it reclaims index
0. Use the existing helpers in the file (AccountManager, setActiveIndex,
getAccountByIndex, getCurrentOrNextForFamilySequential, getActiveIndexForFamily)
and keep the test deterministic with no timing or async behavior.
🪄 Autofix (Beta)

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 91c95277-be1c-46ce-ac2c-cc5311d22176

📥 Commits

Reviewing files that changed from the base of the PR and between 1bc7d99 and 23cfe24.

📒 Files selected for processing (4)
  • lib/runtime-rotation-proxy.ts
  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (10)
test/**/*.test.ts

📄 CodeRabbit inference engine (test/AGENTS.md)

test/**/*.test.ts: Vitest globals (describe, it, expect) are enabled and should be used without explicit imports
Maintain 80% coverage threshold across statements, branches, functions, and lines
Use removeWithRetry for Windows filesystem cleanup instead of bare fs.rm to handle EBUSY/EPERM/ENOTEMPTY backoff
Use source files in tests, not compiled dist/ files; test the source directly
Do not skip tests without justification; include rationale if a test must be skipped
Relax ESLint rules for test files as specified in eslint.config.js

Files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Do not use as any, @ts-ignore, or @ts-expect-error type assertions

Files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
  • lib/runtime-rotation-proxy.ts
**/*.{ts,js}

📄 CodeRabbit inference engine (AGENTS.md)

Use ESM module syntax exclusively; the project is ESM-only with "type": "module"

Files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
  • lib/runtime-rotation-proxy.ts
test/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Windows filesystem operations must include retry handling for transient EBUSY, EPERM, and ENOTEMPTY errors where tests cover Windows locks

Files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

**/*.{ts,tsx,js,jsx}: Override storage root using CODEX_MULTI_AUTH_DIR environment variable instead of hardcoding ~/.codex/multi-auth/ paths
Support alternate config file path via CODEX_MULTI_AUTH_CONFIG_PATH environment variable for flexible configuration locations
Implement request timeout override via CODEX_AUTH_FETCH_TIMEOUT_MS and stream stall timeout via CODEX_AUTH_STREAM_STALL_TIMEOUT_MS environment variables
Ensure OAuth callback listener binds to port 1455 and provide clear error messaging when the port is unavailable
Implement health-aware account selection with quota forecasting and automatic failover to prevent pool cooldowns
Use loopback-only runtime rotation proxy for live account rotation inside forwarded Codex CLI/app sessions
Implement proactive refresh staggering to reduce background refresh bursts and prevent rate-limit storms
Store credentials locally in ~/.codex/multi-auth/ (or custom CODEX_MULTI_AUTH_DIR) without patching official Codex app binaries
Implement session affinity and live account sync to maintain consistent account selection across concurrent requests
Disable whole-pool replay by default when every account is rate-limited to prevent infinite retry loops
Trigger a short cooldown instead of continuing aggressive rotation when repeated cross-account 5xx bursts occur
Implement non-destructive settings operations: preview syncs before apply, preserve destination-only accounts, and fail safely on backup filename collisions
Implement bounded outbound request budget for active requests so one prompt cannot walk the full account pool indefinitely
Support Responses background mode via backgroundResponses setting or CODEX_AUTH_BACKGROUND_RESPONSES=1 for callers intentionally sending background: true requests
Enable runtime rotation by default for request-bearing wrapper-launched Codex sessions and self-heal supported packaged Codex app binds during install/update
Perform best-effort daily npm version checks during forwar...

Files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
  • lib/runtime-rotation-proxy.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (README.md)

Use TypeScript for type-safe account state management, configuration handling, and OAuth token operations

Files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
  • lib/runtime-rotation-proxy.ts
test/**

⚙️ CodeRabbit configuration file

tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.

Files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
lib/**/*.ts

📄 CodeRabbit inference engine (lib/AGENTS.md)

lib/**/*.ts: All public exports should flow through lib/index.ts or documented package subpaths
Never import from dist/ in source tests or library code
Never suppress type errors

Files:

  • lib/runtime-rotation-proxy.ts
lib/runtime-rotation-proxy.ts

📄 CodeRabbit inference engine (lib/AGENTS.md)

lib/runtime-rotation-proxy.ts: Runtime rotation code must preserve pass-through semantics except for auth/provider headers that intentionally change
Runtime proxy client-facing headers must not expose account emails or tokens
Runtime rotation should fail open to normal official Codex forwarding when startup helpers are unavailable
Never add account emails/tokens to runtime proxy client responses

Do not expose account emails or tokens in runtime proxy client response headers or logs

Files:

  • lib/runtime-rotation-proxy.ts
lib/**

⚙️ CodeRabbit configuration file

focus on auth rotation, windows filesystem IO, and concurrency. verify every change cites affected tests (vitest) and that new queues handle EBUSY/429 scenarios. check for logging that leaks tokens or emails.

Files:

  • lib/runtime-rotation-proxy.ts
🧠 Learnings (43)
📓 Common learnings
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: lib/accounts.ts:816-856
Timestamp: 2026-06-04T06:13:32.801Z
Learning: In ndycode/codex-multi-auth, `AccountManager.getCurrentOrNextForFamilySequential` (lib/accounts.ts) intentionally uses 100% exhaustion before advancing to the next account in the pool. Health-aware early failover (quota forecasting, health scores) is deliberately excluded from the sequential path because the confirmed v1 spec from issue `#509` requires full drain before switch to achieve staggered-recovery behavior. A soft `schedulingDrainThresholdPercent`-style knob was explicitly deferred to a future release. The hybrid mode (default) retains full health-aware selection for users who want it.
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{rotation,account,selection}*.{js,ts,jsx,tsx} : Implement minRotationIntervalMs sticky window with a configurable sliding anchor (CODEX_AUTH_MIN_ROTATION_INTERVAL_MS / minRotationIntervalMs, default 60s) to boost the last-served account so back-to-back requests are less likely to present a different OAuth token from the same IP
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.e2e.{ts,tsx,js} : Add end-to-end regression coverage for pinned-503 rate-limited and cooling-down paths; extend existing disabled-account test to assert the new structured fields
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{account,recovery,state}/**/*.{js,ts,tsx} : Implement short-429 retry ordering, active-pointer normalization, and recovery atomic writes in account handling
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{rotation,account,failover,fallback}*.{js,ts,jsx,tsx} : Stop cascade rotation on token invalidation - return the 401 directly to the client instead of rotating to the next account when invalidation is detected
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement health-aware account selection with quota forecasting and automatic failover to prevent pool cooldowns
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{auth,routing,selection}/**/*.{js,ts,tsx} : Implement feature-flagged routing mutex and `SelectionRecord` plumbing for safer concurrent account selection
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 0
File: :0-0
Timestamp: 2026-06-03T10:57:53.412Z
Learning: In ndycode/codex-multi-auth, the ordered quota-probe model fallback list is exported as `QUOTA_PROBE_MODEL_CHAIN` from `lib/request/helpers/model-map.ts` (added in commit `3239f71`, PR `#506` round 6). Both `lib/quota-probe.ts` and `lib/runtime/quota-probe.ts` import this single constant so the candidate model order (`DEFAULT_MODEL` / `gpt-5.5`, `gpt-5.4`, `gpt-5.3-codex`, `gpt-5.2-codex`, `gpt-5-codex`) can never drift between manager-side and runtime-side probes.
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Pinned-account 503 (`codex_pinned_account_unavailable`) must carry a structured `reason` field and a full `account_skip_reasons` map keyed by account index, mirroring the existing `writePoolExhausted` shape
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.2.2.md:0-0
Timestamp: 2026-06-03T14:31:55.434Z
Learning: Realigned account-pool health handling across success healing, guardian penalties, circuit-breaker penalties, reason-scoped rate limiting, and stale cooldown metadata
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use loopback-only runtime rotation proxy for live account rotation inside forwarded Codex CLI/app sessions
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.0.md:0-0
Timestamp: 2026-06-03T14:34:33.388Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Make the account store atomic and self-healing using checksummed WAL with temp-and-rename pattern, and retry transient-lock taxonomy errors (EBUSY/EPERM/ENOTEMPTY/EACCES/EAGAIN) across all writes
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.test.{ts,tsx,js} : Extend `chooseAccount` unit test suite to cover every pinned skip reason returned by `AccountManager.getAccountRuntimeSkipReason`: `rate-limited`, `cooling-down:auth-failure`, `disabled`, `workspace-disabled`, `circuit-open`, `policy-blocked`, `missing`, `already-attempted`
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement session affinity and live account sync to maintain consistent account selection across concurrent requests
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.10.md:0-0
Timestamp: 2026-06-03T14:33:12.019Z
Learning: Runtime pool exhaustion on `no-account` should reset volatile runtime trackers, reload accounts from disk once, and retry selection even when stale in-memory circuit breakers are open to prevent long-lived proxies from staying wedged after disk state has recovered
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:04.016Z
Learning: Runtime configuration is resolved from unified settings (`~/.codex/multi-auth/settings.json`), optional override files (`CODEX_MULTI_AUTH_CONFIG_PATH`), and environment variables in a specific precedence order
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:04.016Z
Learning: Environment variable `CODEX_MULTI_AUTH_DIR` overrides the root directory for multi-auth-managed runtime files
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:04.016Z
Learning: Environment variable `CODEX_MULTI_AUTH_CONFIG_PATH` loads configuration from an alternate path when unified settings are absent or invalid
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:04.016Z
Learning: Stable environment overrides including `CODEX_MODE`, `CODEX_TUI_V2`, `CODEX_AUTH_FETCH_TIMEOUT_MS`, and `CODEX_AUTH_STREAM_STALL_TIMEOUT_MS` are safe for most operators and should be used for day-to-day workflow configurations
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:04.016Z
Learning: Recommended defaults should keep `menuAutoFetchLimits`, `menuSortEnabled`, `liveAccountSync`, `sessionAffinity`, `proactiveRefreshGuardian`, and `preemptiveQuotaEnabled` enabled for most environments
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:04.016Z
Learning: The runtime rotation proxy preserves request bodies and streaming responses, replaces outbound auth headers with selected managed account tokens, and implements token-invalidation detection with a configurable cooldown (default 5 minutes via `CODEX_AUTH_TOKEN_INVALIDATION_COOLDOWN_MS`)
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:04.016Z
Learning: The `schedulingStrategy` configuration option supports two modes: `hybrid` (default, spreads load across accounts) and `sequential` (drain-first, exhausts one account before advancing to next)
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:04.016Z
Learning: Package install/update self-heal operations should repair packaged Codex app bind when `CODEX_MULTI_AUTH_APP_BIND_INSTALL` is enabled, install user-level launcher routing when `CODEX_MULTI_AUTH_APP_LAUNCHER_INSTALL` is enabled, and check for newer npm versions daily
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: When `schedulingStrategy` is set to `hybrid` (default), the runtime proxy must keep weighted health/token/freshness selection that spreads load across all available accounts
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: When `schedulingStrategy` is set to `sequential`, the runtime proxy must drain-first by sticking to one active account and only advancing to the next available account once the current one is fully exhausted
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: When `backgroundResponses` is enabled, Responses API `background: true` requests must become stateful (`store=true`) instead of following default stateless Codex routing
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: Support environment variable `CODEX_MULTI_AUTH_DIR` to allow custom root directory for settings, accounts, cache, and logs
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: Support environment variable `CODEX_MULTI_AUTH_CONFIG_PATH` to allow alternate config file input path
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: Support environment variable `CODEX_MODE` to toggle Codex mode at runtime
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: Support environment variable `CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY` to toggle localhost Responses proxy for forwarded Codex sessions with values `1`/`true` to enable or `0`/`false` to disable
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: Support environment variable `CODEX_AUTH_SCHEDULING_STRATEGY` to override account scheduling strategy per-process with values `hybrid` or `sequential`/drain-first
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: Support environment variables `CODEX_AUTH_FETCH_TIMEOUT_MS` and `CODEX_AUTH_STREAM_STALL_TIMEOUT_MS` to override timeout values at runtime
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: Storage writes must use temp-file + rename semantics to ensure atomic writes
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: Cross-process refresh coordination must rely on lease/state files; avoid manually editing those files while the CLI is running
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: Live account sync must combine `fs.watch` with polling fallback to handle Windows watcher edge cases
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: Runtime rotation shadow-home sync must use a lock directory and state metadata to avoid overwriting newer official Codex state after concurrent helper sessions
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:29.621Z
Learning: If shadow-home lock owner metadata cannot be written, the wrapper must remove the orphaned lock before surfacing the failure so later sync-back attempts are not skipped silently
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:41.351Z
Learning: Use `CODEX_MULTI_AUTH_DIR` environment variable to override the default settings file location
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:41.351Z
Learning: After changes to settings, validate using `codex-multi-auth status`, `codex-multi-auth check`, and `codex-multi-auth forecast --live` commands
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T06:12:41.351Z
Learning: Named backup export should reject separators, traversal patterns (`..`), and `.rotate.`, `.tmp`, `.wal` suffixes in filenames
📚 Learning: 2026-06-03T14:33:39.172Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.test.{ts,tsx,js} : Extend `chooseAccount` unit test suite to cover every pinned skip reason returned by `AccountManager.getAccountRuntimeSkipReason`: `rate-limited`, `cooling-down:auth-failure`, `disabled`, `workspace-disabled`, `circuit-open`, `policy-blocked`, `missing`, `already-attempted`

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-04T06:13:32.801Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: lib/accounts.ts:816-856
Timestamp: 2026-06-04T06:13:32.801Z
Learning: In ndycode/codex-multi-auth, `AccountManager.getCurrentOrNextForFamilySequential` (lib/accounts.ts) intentionally uses 100% exhaustion before advancing to the next account in the pool. Health-aware early failover (quota forecasting, health scores) is deliberately excluded from the sequential path because the confirmed v1 spec from issue `#509` requires full drain before switch to achieve staggered-recovery behavior. A soft `schedulingDrainThresholdPercent`-style knob was explicitly deferred to a future release. The hybrid mode (default) retains full health-aware selection for users who want it.

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-04T06:14:24.975Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: test/runtime-rotation-proxy.test.ts:2478-2491
Timestamp: 2026-06-04T06:14:24.975Z
Learning: In ndycode/codex-multi-auth test files (e.g. `test/*.test.ts`), when creating V3 storage fixtures for accounts, it’s an intentional convention to use `as never` for deliberately minimal stored-account objects that only include `refreshToken`, `addedAt`, and `lastUsed`. Do not treat `as never` here as a type-safety problem: optional/other fields are expected to be populated by the runtime during execution, and the cast is used solely to keep the fixture minimal and consistent across existing tests.

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:33:39.172Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.e2e.{ts,tsx,js} : Add end-to-end regression coverage for pinned-503 rate-limited and cooling-down paths; extend existing disabled-account test to assert the new structured fields

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:33:50.590Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.1.md:0-0
Timestamp: 2026-06-03T14:33:50.590Z
Learning: Applies to docs/releases/**/*.{test,spec}.{ts,tsx,js} : Write schema round-trip preservation tests to ensure account metadata schema fields survive load/save cycles

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-04T06:14:18.093Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: test/scheduling-strategy-config.test.ts:1-1
Timestamp: 2026-06-04T06:14:18.093Z
Learning: In ndycode/codex-multi-auth, do not flag explicit imports from "vitest" (e.g., describe, it, expect, beforeEach/afterEach, etc.) in test files as issues—even if the Vitest config sets `globals: true`. The repo’s established convention is to keep these imports for consistency with neighboring tests; removing them would make files outliers.

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:31:07.275Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.7.md:0-0
Timestamp: 2026-06-03T14:31:07.275Z
Learning: Ensure regression test coverage across account switching, build/test paths, update resilience, auth sync, storage, and wrapper paths

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-03T14:33:00.811Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.2.md:0-0
Timestamp: 2026-06-03T14:33:00.811Z
Learning: Applies to docs/releases/**/*.{test,spec}.{js,ts,mjs,mts} : Add regression coverage for explicit no-capture forwarding, explicit capture forwarding, unsupported-model retries, and fixture-pinned `CODEX_HOME` isolation

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:32:44.663Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{account,recovery,state}/**/*.{js,ts,tsx} : Implement short-429 retry ordering, active-pointer normalization, and recovery atomic writes in account handling

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement health-aware account selection with quota forecasting and automatic failover to prevent pool cooldowns

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:31:20.214Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.9.md:0-0
Timestamp: 2026-06-03T14:31:20.214Z
Learning: Harden rollback and regression coverage for concurrent persistence, flagged-account recovery, malformed-token rows, and shared-workspace edge cases

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-03T14:34:15.851Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.9.md:0-0
Timestamp: 2026-06-03T14:34:15.851Z
Learning: Applies to docs/releases/**/*cli*/**/*.{js,ts,jsx,tsx} : CLI login flow should exit cleanly after displaying the account limit message when reaching `ACCOUNT_LIMITS.MAX_ACCOUNTS` (20) during explicit-mode account addition, preventing silent restart of sign-in sessions

Applied to files:

  • test/accounts.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:33:12.019Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.10.md:0-0
Timestamp: 2026-06-03T14:33:12.019Z
Learning: Runtime pool exhaustion on `no-account` should reset volatile runtime trackers, reload accounts from disk once, and retry selection even when stale in-memory circuit breakers are open to prevent long-lived proxies from staying wedged after disk state has recovered

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:34:33.388Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.0.md:0-0
Timestamp: 2026-06-03T14:34:33.388Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Make the account store atomic and self-healing using checksummed WAL with temp-and-rename pattern, and retry transient-lock taxonomy errors (EBUSY/EPERM/ENOTEMPTY/EACCES/EAGAIN) across all writes

Applied to files:

  • test/accounts.test.ts
  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-03T14:31:55.434Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.2.2.md:0-0
Timestamp: 2026-06-03T14:31:55.434Z
Learning: Realigned account-pool health handling across success healing, guardian penalties, circuit-breaker penalties, reason-scoped rate limiting, and stale cooldown metadata

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use loopback-only runtime rotation proxy for live account rotation inside forwarded Codex CLI/app sessions

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{rotation,account,selection}*.{js,ts,jsx,tsx} : Implement minRotationIntervalMs sticky window with a configurable sliding anchor (CODEX_AUTH_MIN_ROTATION_INTERVAL_MS / minRotationIntervalMs, default 60s) to boost the last-served account so back-to-back requests are less likely to present a different OAuth token from the same IP

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:32:44.663Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{auth,routing,selection}/**/*.{js,ts,tsx} : Implement feature-flagged routing mutex and `SelectionRecord` plumbing for safer concurrent account selection

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement session affinity and live account sync to maintain consistent account selection across concurrent requests

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*.{test,spec}.{js,ts,jsx,tsx} : Write unit tests for upstream-401 invalidation that verify it returns 401 to the client, applies the ~5-minute cooldown, clears affinity, and does not rotate; and that generic 401 still rotates

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:32:44.663Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{storage,account}/**/*.{js,ts,tsx} : Implement account pointer cleanup as part of storage management

Applied to files:

  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-03T14:33:50.590Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.1.md:0-0
Timestamp: 2026-06-03T14:33:50.590Z
Learning: Applies to docs/releases/**/*schema*.{ts,tsx,js} : Account `workspaces` and `currentWorkspaceIndex` fields must survive a load round-trip and be declared in the strict V3 storage schema (`AccountMetadataV3Schema`) to prevent Zod from stripping them on read

Applied to files:

  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-03T14:34:49.238Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.1.md:0-0
Timestamp: 2026-06-03T14:34:49.238Z
Learning: Applies to docs/releases/**/*storage*.js : Preserve pinnedAccountIndex/affinityGeneration through combined transaction clone to prevent doctor restore from erasing manual pins

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*.{test,spec}.{js,ts,jsx,tsx} : Write unit tests for refresh-endpoint invalidation that verify it returns code: 'token_invalidated' and routes through the shared body builder

Applied to files:

  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*.{test,spec}.{js,ts,jsx,tsx} : Write unit tests covering eight cases for the invalidation body builder: top-level message, nested error.message, top-level-wins priority, blank-to-nested fallback, non-JSON body, and no-usable-message fallback

Applied to files:

  • test/runtime-rotation-proxy.test.ts
  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{session,affinity,routing}*.{js,ts,jsx,tsx} : Clear session affinity on token invalidation so the next request can pick a healthy account

Applied to files:

  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-03T10:57:53.412Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 0
File: :0-0
Timestamp: 2026-06-03T10:57:53.412Z
Learning: In ndycode/codex-multi-auth, the ordered quota-probe model fallback list is exported as `QUOTA_PROBE_MODEL_CHAIN` from `lib/request/helpers/model-map.ts` (added in commit `3239f71`, PR `#506` round 6). Both `lib/quota-probe.ts` and `lib/runtime/quota-probe.ts` import this single constant so the candidate model order (`DEFAULT_MODEL` / `gpt-5.5`, `gpt-5.4`, `gpt-5.3-codex`, `gpt-5.2-codex`, `gpt-5-codex`) can never drift between manager-side and runtime-side probes.

Applied to files:

  • test/runtime-rotation-proxy.test.ts
📚 Learning: 2026-06-03T14:33:26.552Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.12.md:0-0
Timestamp: 2026-06-03T14:33:26.552Z
Learning: Applies to docs/releases/**/*.test.{js,ts} : Add regression coverage for literal TOML keys, CRLF preservation, table-like content inside strings and arrays, alternate hook paths, long hook keys, shadow `hooks.json` visibility, and concurrent runtime shadow launches

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*.{test,spec}.{js,ts,jsx,tsx} : Write unit tests for minRotationIntervalMs sliding-anchor and sticky-window coverage, schema and config coverage for both new knobs (min(0), allows-zero, rejects-string)

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:32:44.663Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/*.test.{js,ts,tsx} : Validate staging environment with comprehensive test coverage and real-install smoke testing

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:33:50.590Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.1.md:0-0
Timestamp: 2026-06-03T14:33:50.590Z
Learning: Applies to docs/releases/**/*.{test,spec}.{ts,tsx,js} : Write workspace-load regression tests to lock in the fix for workspace data persistence

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:32:09.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.2.4.md:0-0
Timestamp: 2026-06-03T14:32:09.943Z
Learning: Applies to docs/releases/**/*.test.{js,ts,jsx,tsx} : Restore `fs.readFile` spies from `finally` blocks rather than inline returns in test cleanup

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:34:33.388Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.0.md:0-0
Timestamp: 2026-06-03T14:34:33.388Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Remove Atomics.wait sleeps from config-load and logger retry paths to prevent event loop blocking

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:33:26.552Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.12.md:0-0
Timestamp: 2026-06-03T14:33:26.552Z
Learning: Applies to docs/releases/**/*.{js,ts} : Link duplicated TOML block scanner helpers in production and test code to reduce future drift

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:33:39.172Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.test.{ts,tsx,js} : Add direct unit coverage for `buildPinnedUnavailableErrorBody` across empty-map (`reason: null`), populated-map, null-`pinnedIndex`, and mismatched-pinned-entry shapes

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:30:37.477Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.3.md:0-0
Timestamp: 2026-06-03T14:30:37.477Z
Learning: Add regression coverage to lock local-switch behavior when Codex sync writes return unavailable/failure.

Applied to files:

  • test/scheduling-strategy-config.test.ts
📚 Learning: 2026-06-03T14:34:33.388Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.0.md:0-0
Timestamp: 2026-06-03T14:34:33.388Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Bind rotation proxy and local bridge loopback-only with no opt-out, normalize IPv6 loopback for bind and base URL, and never forward inbound credentials (authorization, x-api-key, cookie, proxy-authorization) upstream

Applied to files:

  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:34:02.943Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{rotation,account,failover,fallback}*.{js,ts,jsx,tsx} : Stop cascade rotation on token invalidation - return the 401 directly to the client instead of rotating to the next account when invalidation is detected

Applied to files:

  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-04T06:14:24.975Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: test/runtime-rotation-proxy.test.ts:2478-2491
Timestamp: 2026-06-04T06:14:24.975Z
Learning: In ndycode/codex-multi-auth, using `as never` for stored-account fixtures in test files (e.g. `test/accounts.test.ts`, `test/runtime-rotation-proxy.test.ts`) is the established convention for deliberately minimal V3 storage fixtures that only include `refreshToken`, `addedAt`, and `lastUsed`. Optional fields are filled in by the runtime. Do not flag this pattern as a type-safety issue; it is intentional and consistent across ~30 usages in `accounts.test.ts`.

Applied to files:

  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:30:44.405Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.4.md:0-0
Timestamp: 2026-06-03T14:30:44.405Z
Learning: Stabilize `codex auth switch <index>` command and host auth sync to ensure local account selection remains deterministic while sync failures are reported clearly

Applied to files:

  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:33:12.019Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.10.md:0-0
Timestamp: 2026-06-03T14:33:12.019Z
Learning: Pinned-account hard-fail behavior must remain preserved: unavailable pinned accounts should return the explicit pinned-account error instead of silently rotating

Applied to files:

  • lib/runtime-rotation-proxy.ts
📚 Learning: 2026-06-03T14:34:49.238Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.1.md:0-0
Timestamp: 2026-06-03T14:34:49.238Z
Learning: Applies to docs/releases/**/*routing*.js : Close routing selection races by running selection and cursor commit in a single reentrant mutex acquisition

Applied to files:

  • lib/runtime-rotation-proxy.ts
🔇 Additional comments (3)
test/scheduling-strategy-config.test.ts (1)

67-76: LGTM!

test/runtime-rotation-proxy.test.ts (2)

2355-2413: LGTM!


2559-2621: LGTM!

Comment thread lib/runtime-rotation-proxy.ts
Add deterministic cases for the drain-first selector that the original
2-account tests could not exercise:

- 3-account drain chain (A->B->C) with wrap to a recovered earlier account,
  proving the forward scan wraps rather than just toggling two accounts
- disabled active account is skipped and the selector advances
- unset/negative activeIndex falls through to the first usable account
- per-ModelFamily isolation: exhausting one family's active account does not
  move another family's cursor

Also add a scoped beforeEach(clearCircuitBreakers) to the sequential describe.
The global beforeEach resets trackers but not circuit breakers, so the
circuit-open case leaked an open breaker into later cases (latent order
dependence); the new cases surfaced it.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@test/accounts.test.ts`:
- Around line 4546-4555: The test is currently validating pointer normalization
because setAccountEnabled(0, false) can move the active pointer before
selection; instead directly mutate the account fixture to simulate an unusable
active account so the sequential-skip logic in
AccountManager.getCurrentOrNextForFamilySequential is exercised. Change the test
to keep the active index at 0, set manager.getAccountByIndex(0)!.enabled = false
(do not call setAccountEnabled), then call
getCurrentOrNextForFamilySequential("codex") and expect index 1; add a second
variant where the account.enabled remains true but all workspaces are disabled
(toggle workspace flags on the same account fixture) to cover
hasEnabledWorkspaces behavior.
🪄 Autofix (Beta)

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 447963dd-506e-4a63-b212-c9877122b923

📥 Commits

Reviewing files that changed from the base of the PR and between 23cfe24 and cbec056.

📒 Files selected for processing (1)
  • test/accounts.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (7)
test/**/*.test.ts

📄 CodeRabbit inference engine (test/AGENTS.md)

test/**/*.test.ts: Vitest globals (describe, it, expect) are enabled and should be used without explicit imports
Maintain 80% coverage threshold across statements, branches, functions, and lines
Use removeWithRetry for Windows filesystem cleanup instead of bare fs.rm to handle EBUSY/EPERM/ENOTEMPTY backoff
Use source files in tests, not compiled dist/ files; test the source directly
Do not skip tests without justification; include rationale if a test must be skipped
Relax ESLint rules for test files as specified in eslint.config.js

Files:

  • test/accounts.test.ts
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Do not use as any, @ts-ignore, or @ts-expect-error type assertions

Files:

  • test/accounts.test.ts
**/*.{ts,js}

📄 CodeRabbit inference engine (AGENTS.md)

Use ESM module syntax exclusively; the project is ESM-only with "type": "module"

Files:

  • test/accounts.test.ts
test/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Windows filesystem operations must include retry handling for transient EBUSY, EPERM, and ENOTEMPTY errors where tests cover Windows locks

Files:

  • test/accounts.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

**/*.{ts,tsx,js,jsx}: Override storage root using CODEX_MULTI_AUTH_DIR environment variable instead of hardcoding ~/.codex/multi-auth/ paths
Support alternate config file path via CODEX_MULTI_AUTH_CONFIG_PATH environment variable for flexible configuration locations
Implement request timeout override via CODEX_AUTH_FETCH_TIMEOUT_MS and stream stall timeout via CODEX_AUTH_STREAM_STALL_TIMEOUT_MS environment variables
Ensure OAuth callback listener binds to port 1455 and provide clear error messaging when the port is unavailable
Implement health-aware account selection with quota forecasting and automatic failover to prevent pool cooldowns
Use loopback-only runtime rotation proxy for live account rotation inside forwarded Codex CLI/app sessions
Implement proactive refresh staggering to reduce background refresh bursts and prevent rate-limit storms
Store credentials locally in ~/.codex/multi-auth/ (or custom CODEX_MULTI_AUTH_DIR) without patching official Codex app binaries
Implement session affinity and live account sync to maintain consistent account selection across concurrent requests
Disable whole-pool replay by default when every account is rate-limited to prevent infinite retry loops
Trigger a short cooldown instead of continuing aggressive rotation when repeated cross-account 5xx bursts occur
Implement non-destructive settings operations: preview syncs before apply, preserve destination-only accounts, and fail safely on backup filename collisions
Implement bounded outbound request budget for active requests so one prompt cannot walk the full account pool indefinitely
Support Responses background mode via backgroundResponses setting or CODEX_AUTH_BACKGROUND_RESPONSES=1 for callers intentionally sending background: true requests
Enable runtime rotation by default for request-bearing wrapper-launched Codex sessions and self-heal supported packaged Codex app binds during install/update
Perform best-effort daily npm version checks during forwar...

Files:

  • test/accounts.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (README.md)

Use TypeScript for type-safe account state management, configuration handling, and OAuth token operations

Files:

  • test/accounts.test.ts
test/**

⚙️ CodeRabbit configuration file

tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.

Files:

  • test/accounts.test.ts
🧠 Learnings (18)
📓 Common learnings
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: lib/accounts.ts:816-856
Timestamp: 2026-06-04T06:13:32.801Z
Learning: In ndycode/codex-multi-auth, `AccountManager.getCurrentOrNextForFamilySequential` (lib/accounts.ts) intentionally uses 100% exhaustion before advancing to the next account in the pool. Health-aware early failover (quota forecasting, health scores) is deliberately excluded from the sequential path because the confirmed v1 spec from issue `#509` requires full drain before switch to achieve staggered-recovery behavior. A soft `schedulingDrainThresholdPercent`-style knob was explicitly deferred to a future release. The hybrid mode (default) retains full health-aware selection for users who want it.
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.e2e.{ts,tsx,js} : Add end-to-end regression coverage for pinned-503 rate-limited and cooling-down paths; extend existing disabled-account test to assert the new structured fields
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{rotation,account,selection}*.{js,ts,jsx,tsx} : Implement minRotationIntervalMs sticky window with a configurable sliding anchor (CODEX_AUTH_MIN_ROTATION_INTERVAL_MS / minRotationIntervalMs, default 60s) to boost the last-served account so back-to-back requests are less likely to present a different OAuth token from the same IP
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement health-aware account selection with quota forecasting and automatic failover to prevent pool cooldowns
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.2.md:0-0
Timestamp: 2026-06-03T14:34:02.943Z
Learning: Applies to docs/releases/**/*{rotation,account,failover,fallback}*.{js,ts,jsx,tsx} : Stop cascade rotation on token invalidation - return the 401 directly to the client instead of rotating to the next account when invalidation is detected
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{account,recovery,state}/**/*.{js,ts,tsx} : Implement short-429 retry ordering, active-pointer normalization, and recovery atomic writes in account handling
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{auth,routing,selection}/**/*.{js,ts,tsx} : Implement feature-flagged routing mutex and `SelectionRecord` plumbing for safer concurrent account selection
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.test.{ts,tsx,js} : Extend `chooseAccount` unit test suite to cover every pinned skip reason returned by `AccountManager.getAccountRuntimeSkipReason`: `rate-limited`, `cooling-down:auth-failure`, `disabled`, `workspace-disabled`, `circuit-open`, `policy-blocked`, `missing`, `already-attempted`
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 0
File: :0-0
Timestamp: 2026-06-03T10:57:53.412Z
Learning: In ndycode/codex-multi-auth, the ordered quota-probe model fallback list is exported as `QUOTA_PROBE_MODEL_CHAIN` from `lib/request/helpers/model-map.ts` (added in commit `3239f71`, PR `#506` round 6). Both `lib/quota-probe.ts` and `lib/runtime/quota-probe.ts` import this single constant so the candidate model order (`DEFAULT_MODEL` / `gpt-5.5`, `gpt-5.4`, `gpt-5.3-codex`, `gpt-5.2-codex`, `gpt-5-codex`) can never drift between manager-side and runtime-side probes.
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use loopback-only runtime rotation proxy for live account rotation inside forwarded Codex CLI/app sessions
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.10.md:0-0
Timestamp: 2026-06-03T14:33:12.019Z
Learning: Runtime pool exhaustion on `no-account` should reset volatile runtime trackers, reload accounts from disk once, and retry selection even when stale in-memory circuit breakers are open to prevent long-lived proxies from staying wedged after disk state has recovered
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement session affinity and live account sync to maintain consistent account selection across concurrent requests
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.0.md:0-0
Timestamp: 2026-06-03T14:34:33.388Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Make the account store atomic and self-healing using checksummed WAL with temp-and-rename pattern, and retry transient-lock taxonomy errors (EBUSY/EPERM/ENOTEMPTY/EACCES/EAGAIN) across all writes
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Override root directory for multi-auth-managed runtime files using `CODEX_MULTI_AUTH_DIR` environment variable
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Load configuration from alternate path using `CODEX_MULTI_AUTH_CONFIG_PATH` environment variable instead of unified settings when unified settings are absent or invalid
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Use `CODEX_MODE=0/1` to disable or enable Codex mode at runtime
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Use `CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY=0/1` to opt out or enable live Codex Responses routing through the localhost account-rotation proxy
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Override idle shutdown time for the wrapper-launched Codex app helper using `CODEX_MULTI_AUTH_APP_ROTATION_IDLE_MS=<ms>`
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Control packaged Codex app bind self-heal during install/update or rotation enable with `CODEX_MULTI_AUTH_APP_BIND_INSTALL=0/1`
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Control supported user-level launcher routing during install/update or rotation enable with `CODEX_MULTI_AUTH_APP_LAUNCHER_INSTALL=0/1`
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Use `CODEX_TUI_V2=0/1` to disable or enable TUI v2
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Select color profile using `CODEX_TUI_COLOR_PROFILE=truecolor|ansi256|ansi16`
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Select glyph mode using `CODEX_TUI_GLYPHS=ascii|unicode|auto`
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Override HTTP request timeout using `CODEX_AUTH_FETCH_TIMEOUT_MS=<ms>`
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Override stream stall timeout using `CODEX_AUTH_STREAM_STALL_TIMEOUT_MS=<ms>`
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Configure minimum time between global account switches using `CODEX_AUTH_MIN_ROTATION_INTERVAL_MS=<ms>` (default 60000) to reduce the rate at which different OAuth tokens appear from the same IP
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Set account scheduling strategy using `CODEX_AUTH_SCHEDULING_STRATEGY=hybrid/sequential` (default hybrid) to control how the proxy picks an account for each request
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: Configure token invalidation cooldown using `CODEX_AUTH_TOKEN_INVALIDATION_COOLDOWN_MS=<ms>` (default 300000, 5 minutes) applied when upstream or token-refresh endpoint explicitly revokes OAuth token
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: In hybrid scheduling mode (default), spread load across all available accounts using a weighted health/token/freshness score so both accounts tend to consume quota at a similar pace
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: In sequential drain-first scheduling mode, route every new request to one active account and only advance to the next available account once the current one is fully exhausted (rate-limited, cooling down, or circuit-open)
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:16:38.423Z
Learning: When token-invalidation detection is triggered, return the error directly to the client instead of rotating to the next account, and apply token invalidation cooldown instead of generic 30-second auth-failure cooldown
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: `schedulingStrategy` should support `hybrid` (default, weighted selection) and `sequential` (drain-first) modes, overridable via `CODEX_AUTH_SCHEDULING_STRATEGY` environment variable
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: `backgroundResponses` setting should remain disabled for stateless pipelines and only enabled for callers that intentionally send `background: true` requests and can accept forced `store=true`
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Environment variable `CODEX_MULTI_AUTH_DIR` allows overriding the root directory for settings, accounts, cache, and logs
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Environment variable `CODEX_MULTI_AUTH_CONFIG_PATH` allows specifying an alternate config file input path
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Environment variable `CODEX_MODE` controls Codex mode toggling at runtime
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Environment variable `CODEX_MULTI_AUTH_RUNTIME_ROTATION_PROXY` controls the localhost Responses proxy for forwarded Codex sessions with values `1`/`true` to enable or `0`/`false` to disable
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Environment variables `CODEX_TUI_V2`, `CODEX_TUI_COLOR_PROFILE`, and `CODEX_TUI_GLYPHS` control terminal UI v2 features and styling at runtime
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Environment variables `CODEX_AUTH_FETCH_TIMEOUT_MS` and `CODEX_AUTH_STREAM_STALL_TIMEOUT_MS` allow overriding timeout values at runtime
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Environment variable `CODEX_AUTH_SCHEDULING_STRATEGY` allows per-process override of account scheduling strategy with values `hybrid` or `sequential`
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Storage writes should use temp-file and rename semantics to handle transient file system errors on Windows (`EPERM`/`EBUSY`)
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Cross-process refresh coordination should use lease/state files and avoid manual editing of those files while the CLI is running
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Live account sync should combine `fs.watch` with polling fallback to handle Windows watcher edge cases
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Backup and WAL artifacts may exist briefly during writes and recovery as part of normal safety behavior and should not be deleted
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: Runtime rotation shadow-home sync should use a lock directory and state metadata to avoid overwriting newer official Codex state after concurrent helper sessions
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:04.697Z
Learning: If shadow-home lock owner metadata cannot be written, the wrapper should remove the orphaned lock before surfacing the failure to prevent silent skip of later sync-back attempts
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:18.145Z
Learning: Use `codex-multi-auth status`, `codex-multi-auth check`, and `codex-multi-auth forecast --live` commands to validate settings changes
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:18.145Z
Learning: Named backup export must reject filenames with separators, traversal patterns (`..`), `.rotate.`, `.tmp`, and `.wal` suffixes to prevent security issues and collisions
Learnt from: CR
Repo: ndycode/codex-multi-auth

Timestamp: 2026-06-04T07:17:18.145Z
Learning: Use `CODEX_AUTH_SCHEDULING_STRATEGY` environment variable to set scheduling strategy to either `hybrid` (spread load across all accounts) or `sequential` (drain-first) without editing settings
📚 Learning: 2026-06-04T06:13:32.801Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: lib/accounts.ts:816-856
Timestamp: 2026-06-04T06:13:32.801Z
Learning: In ndycode/codex-multi-auth, `AccountManager.getCurrentOrNextForFamilySequential` (lib/accounts.ts) intentionally uses 100% exhaustion before advancing to the next account in the pool. Health-aware early failover (quota forecasting, health scores) is deliberately excluded from the sequential path because the confirmed v1 spec from issue `#509` requires full drain before switch to achieve staggered-recovery behavior. A soft `schedulingDrainThresholdPercent`-style knob was explicitly deferred to a future release. The hybrid mode (default) retains full health-aware selection for users who want it.

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:33:39.172Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.test.{ts,tsx,js} : Extend `chooseAccount` unit test suite to cover every pinned skip reason returned by `AccountManager.getAccountRuntimeSkipReason`: `rate-limited`, `cooling-down:auth-failure`, `disabled`, `workspace-disabled`, `circuit-open`, `policy-blocked`, `missing`, `already-attempted`

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-04T06:14:24.975Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: test/runtime-rotation-proxy.test.ts:2478-2491
Timestamp: 2026-06-04T06:14:24.975Z
Learning: In ndycode/codex-multi-auth test files (e.g. `test/*.test.ts`), when creating V3 storage fixtures for accounts, it’s an intentional convention to use `as never` for deliberately minimal stored-account objects that only include `refreshToken`, `addedAt`, and `lastUsed`. Do not treat `as never` here as a type-safety problem: optional/other fields are expected to be populated by the runtime during execution, and the cast is used solely to keep the fixture minimal and consistent across existing tests.

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:33:39.172Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.e2e.{ts,tsx,js} : Add end-to-end regression coverage for pinned-503 rate-limited and cooling-down paths; extend existing disabled-account test to assert the new structured fields

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:32:44.663Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.0.md:0-0
Timestamp: 2026-06-03T14:32:44.663Z
Learning: Applies to docs/releases/**/{account,recovery,state}/**/*.{js,ts,tsx} : Implement short-429 retry ordering, active-pointer normalization, and recovery atomic writes in account handling

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:31:07.275Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.7.md:0-0
Timestamp: 2026-06-03T14:31:07.275Z
Learning: Ensure regression test coverage across account switching, build/test paths, update resilience, auth sync, storage, and wrapper paths

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:33:50.590Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.1.md:0-0
Timestamp: 2026-06-03T14:33:50.590Z
Learning: Applies to docs/releases/**/*.{test,spec}.{ts,tsx,js} : Write schema round-trip preservation tests to ensure account metadata schema fields survive load/save cycles

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:30:06.925Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: README.md:0-0
Timestamp: 2026-06-03T14:30:06.925Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Implement health-aware account selection with quota forecasting and automatic failover to prevent pool cooldowns

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:33:00.811Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.3.2.md:0-0
Timestamp: 2026-06-03T14:33:00.811Z
Learning: Applies to docs/releases/**/*.{test,spec}.{js,ts,mjs,mts} : Add regression coverage for explicit no-capture forwarding, explicit capture forwarding, unsupported-model retries, and fixture-pinned `CODEX_HOME` isolation

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:34:33.388Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.2.0.md:0-0
Timestamp: 2026-06-03T14:34:33.388Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Make the account store atomic and self-healing using checksummed WAL with temp-and-rename pattern, and retry transient-lock taxonomy errors (EBUSY/EPERM/ENOTEMPTY/EACCES/EAGAIN) across all writes

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:31:20.214Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.9.md:0-0
Timestamp: 2026-06-03T14:31:20.214Z
Learning: Harden rollback and regression coverage for concurrent persistence, flagged-account recovery, malformed-token rows, and shared-workspace edge cases

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:30:44.405Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v0.1.4.md:0-0
Timestamp: 2026-06-03T14:30:44.405Z
Learning: Expand deterministic regression coverage across auth, refresh queue, docs integrity, retry/backoff, and CLI routing paths

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:33:12.019Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.10.md:0-0
Timestamp: 2026-06-03T14:33:12.019Z
Learning: Runtime pool exhaustion on `no-account` should reset volatile runtime trackers, reload accounts from disk once, and retry selection even when stale in-memory circuit breakers are open to prevent long-lived proxies from staying wedged after disk state has recovered

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:31:55.434Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.2.2.md:0-0
Timestamp: 2026-06-03T14:31:55.434Z
Learning: Realigned account-pool health handling across success healing, guardian penalties, circuit-breaker penalties, reason-scoped rate limiting, and stale cooldown metadata

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:32:03.085Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v1.2.3.md:0-0
Timestamp: 2026-06-03T14:32:03.085Z
Learning: Fix usage-limit cooldown persistence across account state, fallback 429 handling, and quota scheduling without dropping secondary quota state.

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-03T14:33:39.172Z
Learnt from: CR
Repo: ndycode/codex-multi-auth PR: 0
File: docs/releases/v2.1.13-beta.0.md:0-0
Timestamp: 2026-06-03T14:33:39.172Z
Learning: Applies to docs/releases/**/*.{ts,tsx,js} : Pinned-account 503 (`codex_pinned_account_unavailable`) must carry a structured `reason` field and a full `account_skip_reasons` map keyed by account index, mirroring the existing `writePoolExhausted` shape

Applied to files:

  • test/accounts.test.ts
📚 Learning: 2026-06-04T06:14:18.093Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: test/scheduling-strategy-config.test.ts:1-1
Timestamp: 2026-06-04T06:14:18.093Z
Learning: In ndycode/codex-multi-auth, do not flag explicit imports from "vitest" (e.g., describe, it, expect, beforeEach/afterEach, etc.) in test files as issues—even if the Vitest config sets `globals: true`. The repo’s established convention is to keep these imports for consistency with neighboring tests; removing them would make files outliers.

Applied to files:

  • test/accounts.test.ts

Comment thread test/accounts.test.ts
…ocked account (#509)

Review (Greptile P1) found that getCurrentOrNextForFamilySequential's
isUsable() gated only on rate-limit / cooldown / circuit / enabled, not on
the request's policy block set. When the primary was exhausted and the next
account was policy-blocked (paused / drained / lacking model capability) but
otherwise usable, the selector committed currentAccountIndexByFamily to that
blocked account before chooseAccount could reject it. Every later request then
stuck to the blocked account and fell through to the linear scan, silently
degrading sequential mode to fallback-only.

- accounts.ts: getCurrentOrNextForFamilySequential takes an optional
  blockedIndexes set; isUsable() treats blocked accounts as not usable so the
  active pointer never anchors on one.
- runtime-rotation-proxy.ts: pass policy.blockedAccountIndexes into the selector.
- test: selector never anchors on a policy-blocked account and selects it once
  the block clears (verified to fail without the fix).

Note: a second review comment (CodeRabbit, persist-path pointer move) was
investigated and found not to reproduce — every continue branch that benches
the primary also cools it down (refresh failure applies an auth cooldown,
429 a rate-limit, 5xx/network a cooldown, workspace-disabled disables it), so
the healthy-but-attempted-primary precondition is unreachable and the advance
is always legitimate. No change made for that one.
@ndycode ndycode merged commit d072244 into main Jun 4, 2026
2 checks passed
@ndycode ndycode deleted the feat/sequential-account-mode branch June 4, 2026 08:26
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.

[feature] Sequential Account Usage Mode (Drain One Account Before Switching)

1 participant