Skip to content

fix(codex): honor scoped cooldowns in subagent fallback - #2418

Open
luvs01 wants to merge 1 commit into
lidge-jun:devfrom
luvs01:fix/subagent-scoped-cooldown-fallback
Open

fix(codex): honor scoped cooldowns in subagent fallback#2418
luvs01 wants to merge 1 commit into
lidge-jun:devfrom
luvs01:fix/subagent-scoped-cooldown-fallback

Conversation

@luvs01

@luvs01 luvs01 commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Resolve the pool account separately for every subagent fallback candidate's routed Codex quota scope, so a shared-model preview cannot incorrectly decide Spark or another scoped candidate.
  • Apply the candidate's account-gated model entitlements during both preview and availability checks; fixed account selectors stay pinned and unentitled accounts fail closed.
  • Keep preview side-effect-free: it does not move account cursors, bind affinity, or acquire probe leases, while final authentication remains authoritative.
  • Reuse the same candidate-aware rules after encrypted child-task recovery and preserve account-wide probe pacing, unrelated-scope independence, and explicit-account behavior.

Verification

  • Bun 1.4 current-head native fallback account-preview regressions — 8 passed, 0 failed, 47 assertions.
  • Bun 1.4 current-head scoped/fixed/null/entitlement fallback regressions — 12 passed, 0 failed.
  • Coverage includes shared→Spark multi-account selection, Daybreak entitlement selection, fixed selectors, null previews, model-health keying, and encrypted recovery's second fallback pass.
  • bun run typecheck — passed.
  • bun run privacy:scan — passed.
  • git diff --check — passed.
  • Independent exact-diff review after the review fix — no actionable findings.
  • Exact head 25fbdd10dfb0f4f237ab6a5da4405dc0ce4e0ffe, based directly on dev at 4f41a8e936141af7ee828e335da314b9dc1ef761.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed. This restores an internal routing contract and adds no public API or configuration surface.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults. Entitlement and account selection fail closed; previews remain read-only and actual probe lease acquisition stays in the existing auth path.

Review readiness checklist

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

  • All CI tests are green on my local testing.

  • I pushed my PR to the latest dev commit.

  • I resolved all correct Codex and CodeRabbit findings.

  • My PR is ready for review.

@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Aug 22, 2026
@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9ba7c7ad-b94f-4b33-a8e8-87dccfd7b80e

📥 Commits

Reviewing files that changed from the base of the PR and between 1fa04e0 and 25fbdd1.

📒 Files selected for processing (4)
  • src/codex/subagent-model-fallback.ts
  • src/server/responses/core.ts
  • tests/subagent-fallback-handle-responses.test.ts
  • tests/subagent-model-fallback.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The change adds side-effect-free scoped quota probe eligibility, entitlement-aware pool account previews, model-specific fallback routing, and recovery-path reuse of those constraints. Tests cover cooldown recovery, fixed and pool accounts, entitlement filtering, and encrypted task recovery.

Changes

Entitlement-aware subagent fallback

Layer / File(s) Summary
Scoped probe and fallback routing
src/codex/routing.ts, src/codex/subagent-model-fallback.ts
Fallback routing resolves model-eligible pool accounts and checks model-scoped or account-wide probe leases during cooldowns. Account-qualified routes remain blocked during cooldowns.
Response entitlement wiring
src/server/responses/core.ts
Response handling resolves entitlements once, builds shared model-aware preview callbacks, and reuses them during fallback selection and encrypted task recovery.
Fallback behavior coverage
tests/subagent-model-fallback.test.ts
Tests cover entitlement filtering, fixed-account validation, null previews, model-scoped recovery, unrelated scopes, and account-wide probe pacing.
Response recovery coverage
tests/subagent-fallback-handle-responses.test.ts
Tests cover model-specific account previews, entitlement-gated native fallback, recovery retries, and recovery-state setup and cleanup.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 25fbd

The change scopes fallback cooldown handling to the appropriate quota scope while preserving existing pacing and selector behavior; no actionable merge-blocking risk remains after normal checks and review.

Suggested reviewers: lidge-j

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 5 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: applying scoped cooldowns during Codex subagent fallback routing.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

✅ READY

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

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ 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

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1fa04e07ad

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

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

Comment thread src/codex/subagent-model-fallback.ts
@luvs01
luvs01 force-pushed the fix/subagent-scoped-cooldown-fallback branch from 1fa04e0 to 25fbdd1 Compare August 22, 2026 21:42
@github-actions
github-actions Bot marked this pull request as draft August 22, 2026 21:43
@luvs01
luvs01 marked this pull request as ready for review August 22, 2026 21:44
@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 56 / 80

설명: 이 PR 은 자식 에이전트가 다른 모델로 넘어갈 때, 그 모델의 할당량 칸에 맞는 계정만 고르게 한다. 지금 CURRENT dev HEAD 는 4f41a8e93 이다. 이번 시간에 origin/dev 는 그대로다. 새 머지는 없다. 착지는 여전히 2396 사용량 CLI 오늘 비용이다. package.json 은 2.27.0 이다. src/config.ts 는 3975줄이다. src/runtime 폴더는 지금 HEAD 에 없다. 지금 HEAD 의 src/codex/subagent-model-fallback.ts 176줄 resolveRouteFallbackAccountId 는 이미 박힌 계정이 없으면 미리보기 계정 하나를 그대로 쓴다. 234줄 isSubagentModelUnavailable 은 그 계정으로 건강을 본다. 260줄은 안 박힌 풀 길에서 계정 전체 식힘만 본다. 모델 칸 식힘은 안 본다. src/server/responses/core.ts 2386줄 previewCodexAccountForRequest 는 첫 모델의 칸만 넣는다. 그래서 솔이 식어도 스파크 칸은 다른 계정이 비어 있는데, 미리보기가 솔 칸의 계정 A 를 스파크에도 씌운다. A 의 스파크가 막혀 있으면 자식이 실패한다. A 의 계정 전체가 식으면 스파크를 건너뛰고 먼 길로 간다. 이 PR 은 후보마다 그 모델 칸으로 계정을 다시 미리 본다. 미리보기는 계정 순서도 안 옮기고 임대도 안 잡는다. 계정에 묶인 네이티브 모델은 권한 표를 미리보기와 가능 검사에 같이 넣는다. 박힌 선택기는 그대로 고정이다. 권한 없는 계정은 닫힌다. 암호로 감싼 자식 작업을 되살린 뒤 두 번째 고름에도 같은 규칙을 쓴다. src/codex/routing.ts 는 칸 임대를 읽기만 하는 함수를 더한다. 실제 임대는 인증 길에 남긴다. 시험은 공유에서 스파크로 넘어갈 때 계정 B 를 고르는지, 데이브레이크 권한이 있는 계정만 남는지, 암호 복구 두 번째 고름이 새 칸을 다시 보는지 잠근다. 작성자 로컬은 미리보기 8개와 칸/고정/빈/권한 12개, typecheck, privacy:scan 통과라고 적었다. 드래프트가 아니다. bug 와 review-ready 라벨이 있다. 체크리스트 네 칸이 채워져 있다. 작성자는 luvs01 이다. 베이스는 지금 HEAD 와 같다. Closes 가 없다. GitHub 위생과 게이트는 READY 다. CodeRabbit 은 지적 없음이다. Cross-platform CI 권위는 아직일 수 있다. 사용자 길이로는 자식이 식은 칸의 계정으로 스파크를 고르는 구멍이라서 56. 카탈로그 팁은 Ox Alpha x-preview-f-free + deepseek-v4-flash-vision-exp. Cursor 정적 카탈로그는 opus-4-8-fast / opus-5-fast. 2334 CursorCredentialRouter 는 여전히 src/providers/cursor-pool.ts 모듈+테스트만 있고 어댑터에 연결되지 않았다. 2332 H2 는 discovery 전용. 2320 overflow + 2342 는 이미 dev. 2188 사이드카는 이미 dev. 2382 데스크톱 앱 재시작은 이미 dev. 2292 는 아직 연다.

src/codex/subagent-model-fallback.ts 라인 176 - 지금 HEAD 는 박힌 계정이 없으면 미리보기 계정 하나를 모든 후보에 쓴다
src/codex/subagent-model-fallback.ts 라인 260 - 안 박힌 풀 길은 계정 전체 식힘만 본다. 모델 칸 식힘은 건너뛴다
src/server/responses/core.ts 라인 2386 - 미리보기는 첫 모델 칸만 넣는다. 스파크 후보는 솔 칸의 계정을 그대로 받는다
src/codex/routing.ts 새 canAcquireCodexQuotaScopeProbeLease - 칸 임대를 읽기만 한다. 실제 임대는 인증 길에 남긴다
tests/subagent-fallback-handle-responses.test.ts - 공유에서 스파크로 넘어갈 때 계정 B 를 고르는지, 복구 두 번째 고름이 새 칸을 다시 보는지 잠근다
GitHub CI - 위생과 게이트는 READY. Cross-platform CI 권위는 아직일 수 있다. 작성자 로컬은 20개 통과

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

  • GitHub 시험이 아직이면 기다릴지. 작성자 로컬은 이미 통과라고 적었다
  • 권한 표를 미리보기와 실제 인증에서 두 번 읽는다. 한 번으로 줄일지
  • 이 구멍을 이슈로 남길지. 본문에 Closes 가 없다

너의 추천
GitHub 시험이 초록이면 머지한다. 가드를 더 넓히지 말 것. 미리보기는 읽기만 하게 둔다. 실제 임대는 인증 길에 남긴다. types.ts/config.ts 스플릿과 겹치지 않는다. 라벨은 그대로 둔다. 프리뷰 배포가 아니다.

이 댓글은 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.

The candidate-scoped preview direction is correct, but the current handleResponses gate leaves one account-qualified primary path outside the entitlement boundary.

subagentFallbackNeedsModelEntitlements(parsed, config) correctly scans the fallback chain, but core.ts resolves the entitlement snapshot only when the initial route has route.codexAccountId === undefined. If a thread starts on an account-qualified primary (for example team/gpt-5.6-sol) and that fixed candidate is skipped by cooldown/health, a later pooled or fixed gpt-daybreak-blue-latest fallback is evaluated without modelEligibleAccountIdsForModel. The unit helper can enforce entitlements when a callback is passed, but the production call never creates that callback for this route shape. It can therefore skip a healthy entitled pool account because an unentitled preview account is cooled, or admit an unentitled fixed fallback and fail only during final auth.

Please remove the initial-route account-id condition from entitlement snapshot setup; the need should be derived from the actual fallback chain, not the primary route ownership. Add handleResponses regressions for an account-qualified primary that falls through to (1) a pooled account-gated model where only another pool account is entitled and (2) an unentitled fixed account-gated selector that must be skipped. Keep preview side-effect-free and final authentication authoritative.

After the fix, rebase onto current dev, rerun the two focused fallback suites, typecheck, and exact-head CI. No broader routing refactor is needed.

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