Skip to content

fix(codex): activate quota from saved deadlines - #6020

Closed
terrytan95 wants to merge 1 commit into
lidge-jun:devfrom
terrytan95:terry-codex-quota-deadlines
Closed

terrytan95 wants to merge 1 commit into
lidge-jun:devfrom
terrytan95:terry-codex-quota-deadlines

Conversation

@terrytan95

@terrytan95 terrytan95 commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes #6018.

Automatic quota-window activation currently queries upstream usage again when a snapshot is five minutes old, even when the next reset deadline is already persisted. This change waits on those saved deadlines locally and queries only when an enabled window lacks an uncompleted deadline, preserving automatic activation while reducing avoidable authenticated background traffic.

The issue records the user's observation of forced sign-outs and concern about regular background traffic. Causation, OpenAI detection thresholds, and improved session lifetime are not established or measured; this PR claims reduced unnecessary requests only.

Key Changes

  • Reuse retained reset deadlines, including after restart with no in-memory quota snapshot; successful activation response headers seed the next window.
  • Back off unresolved metadata discovery and activation failures at 5, 10, 20, 40, then 60 minutes; successful discovery/activation clears the respective retry state.
  • Preserve account opt-in, pause/reauth/hard-lock gates, credential ownership and generation fences, simultaneous-window coalescing, and durable completion.
  • Document the scheduling behavior in English/Chinese and the required structure ownership docs; existing dashboard and reset-notification polling remain independent.

Verification

  • PASS: bun test tests/codex-integration/codex-quota-auto-refresh.test.ts tests/codex-integration/codex-quota-auto-refresh-main-admission.test.ts — 46 tests, 274 assertions. Includes five hours of simulated local ticks, restart without quota cache, zero pre-deadline metadata queries, exactly one activation, missing-window discovery/backoff, response-header continuation, and expired native-main credential handling with/without metadata discovery.
  • PASS: bun run typecheck.
  • PASS: bun run structure:check, bun run privacy:scan, and git diff --check.
  • PASS: cd docs-site && bun install --frozen-lockfile && bun run build — 537 pages, 73,478 internal links checked.
  • INCOMPLETE / NOT GREEN: bun run test:changed expanded broadly and was interrupted with SIGINT (exit 130) after roughly eight minutes as local command responsiveness degraded. Its partial output contains 840 failure reports, including repository-local fixture cleanup rejected by the real-Codex-home guard because this managed checkout is under .codex/worktrees, plus CLI subprocess and network timing failures. All 46 activation tests also passed within that run. The other failures have not all been triaged or reproduced on the base revision, so they are not asserted to be unrelated. A clean broader run in a suitable checkout/CI remains required before readiness.
  • Full bun run test has not been run; this contribution remains a draft, not a review-ready attestation. Cross-platform CI and independent maintainer review remain outstanding. No live account probes or activation requests were used for validation.

Impact & Risk

No breaking configuration changes, migrations, new dependencies, or environment variables. Known idle deadlines can remain stale after an out-of-band upstream schedule change until normal traffic, explicit refresh, or recovery observes it. Retry backoff is process-local and resets on restart; actual activation may occur on the next minute sweep. This affects scheduling only and makes no guarantee about upstream sign-out prevention.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Author inspection and regression tests preserve the existing authentication/ownership protections; independent security review is not claimed.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • Required local validation passed; commands, results, and any full-suite exception are documented.

  • I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

Summary by CodeRabbit

  • Improvements
    • Automatic quota activation now checks known reset times locally, including after a restart, instead of repeatedly refreshing stale quota data.
    • When reset information is missing, the app retries discovery and activation with increasing delays, up to one hour. Successful response data can provide the next reset time without an extra query.
    • Dashboard refreshes and optional reset notifications continue to operate independently.
  • Documentation
    • Updated guides to explain quota activation timing, retry behavior, and restart recovery.

@coderabbitai

coderabbitai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 7e182fd2-1ade-4080-ad22-af6ae8d8c7b2

📥 Commits

Reviewing files that changed from the base of the PR and between 2a3cfa5 and 11c9286.

📒 Files selected for processing (14)
  • docs-site/src/content/docs/getting-started/how-it-works.mdx
  • docs-site/src/content/docs/zh-cn/getting-started/how-it-works.mdx
  • src/codex/quota-auto-refresh-state.ts
  • src/codex/quota-auto-refresh.ts
  • structure/catalog.md
  • structure/codex-home.md
  • structure/config.md
  • structure/gui-and-management-api.md
  • structure/ops/docs-and-release.md
  • structure/providers/openai-tiers.md
  • structure/runtime.md
  • structure/subagents.md
  • tests/codex-integration/codex-quota-auto-refresh-main-admission.test.ts
  • tests/codex-integration/codex-quota-auto-refresh.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Quota activation now waits locally for retained reset deadlines instead of querying metadata solely because quota snapshots are stale. Missing-deadline discovery and failed activations use bounded backoff. Regression tests and documentation cover restart behavior, deadline recovery, and the separation from dashboard quota queries.

Changes

Quota activation scheduling

Layer / File(s) Summary
Deadline scheduling, retries, and coverage
src/codex/quota-auto-refresh*.ts, tests/codex-integration/codex-quota-auto-refresh*.test.ts, docs-site/src/content/docs/getting-started/how-it-works.mdx, docs-site/src/content/docs/zh-cn/getting-started/how-it-works.mdx, structure/*.md, structure/providers/openai-tiers.md, structure/ops/docs-and-release.md
Per-account retry state now stores the next retry time and delay. Metadata discovery is suppressed while enabled windows have retained deadlines, and discovery and warmup failures use backoff capped at one hour. Integration tests cover persisted deadlines, missing-deadline discovery, response-header recovery, and failed activations. Documentation describes the scheduling behavior and its boundaries.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant MinuteSweep as Local minute sweep
  participant AutoRefresh as runCodexQuotaAutoRefresh
  participant WHAM
  participant Warmup as Quota warmup
  MinuteSweep->>AutoRefresh: Check retained reset deadlines
  AutoRefresh->>WHAM: Query when an enabled deadline is missing and retry is due
  WHAM-->>AutoRefresh: Return quota metadata and reset deadlines
  AutoRefresh->>Warmup: Activate due windows
  Warmup-->>AutoRefresh: Return response headers with next deadlines
Loading

Merge Risk: ⚪ Minimal · up to 11c92

No confirmed issue blocks merging. Discovery after a completed deadline remains unverified and merits a focused check when the relevant source is available.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 11c92

The change reduces background quota lookups without widening account access or bypassing the existing sign-in controls. A retry from an earlier credential failure may, however, delay activation after sign-in is restored by up to an hour.

Retained concerns

  • Low · reliability · inferred: An activation failure's account-keyed cooldown is not tied to the credential that failed. After reauthentication clears the account gate, the old cooldown can still postpone activation; the new backoff extends that delay from five minutes to as much as one hour.
Security review details

Security Blast Radius

  • inferred — The changed request timing affects opted-in Codex accounts selected by the scheduler, not an additional caller or account class. Authenticated upstream traffic should decrease while deadlines remain known.

Trust Boundaries and Controls

  • observed — Pool warmup checks the live credential generation before using and publishing quota results. Native-main warmup uses a profile claim and checks credential identity and generation around the request.

Resilience and Maintainability Implications

  • inferred — The longer, account-keyed activation cooldown may survive a credential recovery transition. This delays a permitted action rather than granting the replacement credential additional authority.

Hardening Proposals

  • proposed — Consider clearing or generation-scoping activation retry records when a credential is successfully replaced, while retaining the existing eligibility and credential-use checks.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Issue #6018 has coding requirements for persisted deadline scheduling, restart recovery, due-window activation, shared warmups, response-header deadline capture, conditional metadata discovery, bounde…
Out of Scope Changes check ✅ Passed The changed source files implement the deadline-based activation behavior from issue #6018. The changed tests verify that behavior. The documentation changes describe the same scheduling, persistence,…
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 4 files. (10 skipped: 1…
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: activating Codex quota windows from persisted reset deadlines.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added the bug Something isn't working label Sep 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions

github-actions Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ Required local validation passed; commands, results, and any full-suite exception are documented.
  • ✅ I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

✅ 4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

@terrytan95
terrytan95 marked this pull request as ready for review September 27, 2026 00:51
@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 62 / 80

이 PR은 5시간 창과 일주일 창이 다시 열릴 때 계정을 살짝 깨우는 기능은 그대로 둡니다. 빼는 것은, 다음 리셋 시각을 이미 아는데도 사용량을 자꾸 물어보던 요청입니다. 지금은 스냅샷이 5분만 지나도 그 요청이 나갑니다. 저장된 마감이 있어도 그렇습니다. 바꾼 뒤에는 켜 둔 창의 마감이 있으면 1분마다 이 컴퓨터에서만 시각을 봅니다. 프록시를 껐다 켜서 메모리에 스냅샷이 없어도, 설정에 남은 마감으로 기다립니다. 마감이 비어 있을 때만 사용량을 조회합니다. 조회가 안 되거나 깨우기가 실패하면 다음 시도는 5분, 10분, 20분, 40분, 그 다음부터는 60분입니다. 성공한 응답에 다음 시각이 있으면 그 값으로 이어 가고, 사용량을 한 번 더 묻지 않습니다. 대시보드 새로고침과 리셋 알림은 이 일정과 따로 돕니다. 베이스는 dev입니다. 지금 tip은 d8b85adc(#6016)이고, 이 커밋은 그보다 하나 뒤입니다. 패키지는 @bitkyc08/opencodex 2.68.0입니다. types.ts와 config.ts 분리와는 안 겹칩니다. draft는 아닙니다. review-ready가 붙어 있습니다. 본문에는 넓은 테스트가 중간에 끊겨서 아직 draft라고도 적혀 있습니다.

라인 - src/codex/quota-auto-refresh.ts의 deferRetry(56행)와 실패 처리(351행). 깨우기가 실패하면 기다리는 시간이 두 배가 됩니다. 메인 계정이 사용 중이라 206행에서 던지는 native main busy도 같은 대기입니다. 창이 막 열렸는데 그 계정을 쓰는 중이면, 다시 깨우는 시도가 한 시간까지 밀립니다. 예전에는 이런 실패를 5분마다 다시 했습니다.

라인 - 같은 파일 340행과 351행. 401이면 재로그인이 필요하다고 표시합니다. retryAfterByAccount의 대기는 지우지 않습니다. 324행은 재로그인 중이면 그 계정을 바로 건너뜁니다. 사용자가 다시 로그인한 뒤에도 340행이 남은 대기를 봅니다. 첫 401만 있으면 대기는 5분입니다. 그 전에 다른 실패로 대기가 길어져 있으면, 재로그인이 끝난 뒤에도 최대 60분이 남습니다. 그 대기를 지우는 곳은 깨우기가 성공한 345행뿐입니다.

메인테이너의 판단이 필요한 지점

저장된 마감이 틀려도, 스냅샷이 오래됐다는 이유만으로 사용량을 다시 묻지 않습니다. 상류가 리셋 시각을 바꾸면, 일반 요청이나 직접 새로고침이 오기 전까지 모릅니다. 작성자는 이 선택을 본문에 적었습니다. 로그인 강제 종료를 막는다는 측정은 없고, 불필요한 요청만 줄인다고 했습니다.

대기 시간은 프로세스 메모리에만 있습니다. 프록시를 재시작하면 5분부터 다시 셉니다.

작성자는 활성화 테스트 46개가 통과했다고 했습니다. bun run test:changed는 약 8분 뒤 SIGINT로 끊겼습니다. 일부 실패는 이 체크아웃이 .codex/worktrees 아래라서 났다고 적었습니다. 그 실패가 베이스에도 있는지는 확인하지 않았습니다. 준비 완료 칸은 이미 체크돼 있습니다.

너의 추천

합치기 전에 351행 대기를 나누세요. 메인이 바쁜 경우와 재로그인이 필요한 경우는 5분으로 두세요. 재로그인 표시가 풀리면 그 계정 대기를 지우세요. 상류 깨우기가 실제로 실패한 경우만 5분에서 60분으로 늘리세요. 베이스 dev는 유지하세요. 닫을 중복 PR은 없습니다. 넓은 테스트가 끊긴 사실은 남기되, 그 840건을 이 변경의 실패로 단정하지는 마세요.

이 댓글은 grok-bot이 작성했습니다

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Blocking exact head 11c92862ad8a3c1b13eb18ee7668fdb0bfae3753 on two P2 scheduler defects:

  1. activationRetryByAccountId is account-keyed rather than credential-generation-keyed. A 401/failure from the old generation can leave a 60-minute retry, then replacement credentials clear generation-scoped reauth evidence but remain suppressed by line 340 until that old retry expires. A late old-generation failure can also reintroduce the cooldown after replacement. Scope/reset retry evidence to the credential generation without clearing durable deadline/completion state, and add the replacement-during-await regression.

  2. warmAccount() throws when native-main admission is locally unavailable, and the outer catch grows the same 5→10→20→40→60 upstream-failure backoff. Startup/recovery gates, drains, shutdown, or exhausted admission can therefore defer activation for an hour even though no upstream request ran. Return a distinct local-busy/skipped outcome with bounded short retry, and test repeated refusal followed by release. Ordinary concurrent main use alone is not the refusal condition.

Readiness also needs reconciliation: the PR is non-draft with all boxes checked, but its body says the broad run was interrupted with exit 130/840 untriaged reports, and exact-head Cross-platform CI 36283299907 is action_required rather than semantic green. Please obtain clean exact-head CI after fixing the two cases.

The known-deadline scheduling and cleanup paths otherwise look coherent; this review does not attribute the 840 reports to this patch.

@lidge-jun

Copy link
Copy Markdown
Owner

Landed on dev in #6062 (merge bf6c57c0d7) as one squashed commit that keeps your authorship. A follow-up commit (2a49525f1d) answers the review on this PR: retry records carry the credential generation, and a local native main busy refusal retries after one minute without growing the backoff. Thank you. Closing because this repository merges into dev, so GitHub does not close carried PRs automatically.

@lidge-jun lidge-jun closed this Sep 27, 2026
Flowershangfromthebranches pushed a commit to Flowershangfromthebranches/opencodex that referenced this pull request Sep 27, 2026
Carried from lidge-jun#6020 into merge train round 3.

Co-authored-by: Terry Tan <tmy1995hflc@gmail.com>
Flowershangfromthebranches pushed a commit to Flowershangfromthebranches/opencodex that referenced this pull request Sep 27, 2026
Follow-up to lidge-jun#6020, from the review on that PR. Retry records carry the credential generation, so a replaced or reauthenticated credential no longer waits out its predecessor backoff, and a failure that raced a replacement is not recorded. A local native-main admission refusal retries after one minute without doubling the upstream backoff. main account unavailable stays in the growing backoff; generation keying already lets a later token start clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants