Skip to content

fix(responses): bound API-key 429 rotations across continuations - #4621

Draft
luvs01 wants to merge 21 commits into
lidge-jun:devfrom
luvs01:agent/key429-rotation-cap-20260914
Draft

luvs01 wants to merge 21 commits into
lidge-jun:devfrom
luvs01:agent/key429-rotation-cap-20260914

Conversation

@luvs01

@luvs01 luvs01 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Bound API-key rotations and physical sends across a logical Responses request. Preserve an exact prepaid compact recovery through intermediate combo scopes, settle it once, and retain its inherited total/recovery ceiling. A prepaid first send remains available even when the remainder cannot fund every later declared target. OAuth/forward account pools are separate from the documented API-key rotation count.

Current author verification

Exact head: 8885847bf52010c1b3f8a90036f21fdb14c51f61.

  • Replaced both brittle send-budget source oracles with structural checks, including negative controls for unfunded or shadowed allowances; the source-oracle suite passed 24 tests / 164 assertions.
  • Fixed terminal-continuation recovery for both retry-helper and Kiro-owned sends, retained remaining base retries after a prepaid OAuth hop, and refunded existing caller-owned hops when dispatch never occurred. The latest focused suite passed 64 tests / 562 assertions, with failing original-code controls for all three newly corrected boundaries.
  • The same first-send-only permit settlement also covers passthrough retries. A real OAuth regression proves A:429 -> B:reset -> B:success within three physical sends and without spending the recovery reserve; its original-code control fails. This final follow-up passed 47 related tests / 491 assertions. All four allowance call sites were checked for the shared contract.
  • Type, structure, privacy, file-size ratchet and diff checks passed; documentation built all 441 pages.
  • Exact-head fork Cross-platform CI run 35045571767 is pending. CI completion remains pending; no exact-head all-green claim is made. Earlier-head results are not validation of this new head.
  • The manually dispatched full Windows matrix is supplemental according to the existing workflow. Its previously observed Windows 2/6 failures are tracked separately; this PR does not change the workflow or absorb unrelated Windows fixes.
  • Google internal retry policy is unchanged. The documented physical-send cap applies to retry-helper-owned and budget-aware adapter paths; this change preserves/refunds an existing caller-owned Google hop without claiming a new cap for all Google internal retries.

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.

Summary by CodeRabbit

  • New Features

    • Responses requests using multi-key pools now enforce a shared, request-scoped API-key rotation limit, including continuation requests.
    • Limits account for whether the initial key is in the pool and are not replenished by cooldown expiry or pool growth.
    • Failed rotations record cooldown information without selecting a replacement key.
  • Bug Fixes

    • Improved handling of exhausted rotation and retry budgets while preserving existing error responses.
  • Documentation

    • Updated provider, transport, and architecture documentation on bounded rotation and retry behavior.

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
📝 Walkthrough

Walkthrough

The change bounds API-key 429 failover for generic Responses requests. It adds rotation controls, scoped combo send budgets, validation coverage, and documentation for shared limits and cooldown handling.

Changes

Responses key failover

Layer / File(s) Summary
Failover rotation control
src/providers/key-failover.ts, tests/adapters/key-failover.test.ts
Failover accepts allowRotation. Disabled rotation records the failed key cooldown without selecting or persisting a replacement. Tests verify configuration bytes, ownership, events, and cooldown behavior.
Combo send-budget scopes
src/server/responses/combo-send-budget.ts
Combo execution derives total send allowances, shares usage with parent scopes, and reserves capacity for later targets.
Failover behavior validation
tests/server/server-key-failover-e2e.test.ts
End-to-end cases cover bridge, exhausted, continuation, transient, budget-exhausted, recovery-success, and unpooled 429 flows. Tests verify authorization keys, cooldown state, response errors, continuation behavior, and request limits.
Contract documentation
docs-site/src/content/docs/*/reference/configuration/providers.md, structure/**/*.md
Localized provider documentation and structure references describe bounded rotation, cooldown handling, continuation sharing, and the scope of generic Responses failover.

Priority: ➖ Normal

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

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ResponsesAdapter
  participant ProviderTransport
  participant KeyFailover
  Client->>ResponsesAdapter: submit Responses request
  ResponsesAdapter->>ProviderTransport: send request with current API key
  ProviderTransport-->>ResponsesAdapter: return 429
  ResponsesAdapter->>KeyFailover: request bounded rotation
  KeyFailover-->>ResponsesAdapter: record cooldown and return replacement or no replacement
  ResponsesAdapter->>ProviderTransport: send recovery or continuation request
  ProviderTransport-->>ResponsesAdapter: return response or final error
  ResponsesAdapter-->>Client: return Responses result
Loading

Merge Risk: 🟡 Moderate · up to 5efbb

Multi-target Responses requests can exceed their bounded upstream-send allowance, so the shared accounting should be corrected before merge. The provider documentation should also clarify which authentication and retry modes the limit covers.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 5 files. (7 skipped: 7… 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: bounding API-key 429 rotations across Responses continuations. It matches the implementation and objectives.
Full details: Docstring Coverage

Explanation

Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 5 files. (7 skipped: 7 unsupported.)

✨ 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

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

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

github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • review readiness checklist open (2/4 boxes ticked).

What to do

  • Tick all four boxes in the PR description once you're done (currently 2/4).

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.

2/4 boxes ticked.

This PR stays in draft until every box above is ticked.

@luvs01

luvs01 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@luvs01

luvs01 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-16T01:53:19.882700Z 8885847 Manual request
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 64 / 80

설명

이 PR(작성자 luvs01, draft)은 API 키 풀에서 429가 났을 때 키가 무한히 돌 수 있는 구멍을 막는다. 짧은 쿨다운이 끝나면 이미 시도한 키를 다시 고를 수 있고, reset-only 전송은 공유 transient retry budget을 안 켜서 요청이 키만 바꾸며 계속 도는 장면이 나온다. 고치는 방법은 단순하다. handleResponsesInner 한 번 호출마다 첫 전송 전 풀 크기 N을 찍고, 최초 복구와 terminal continuation이 합쳐서 최대 N-1번만 키를 바꾸게 한다. 쿨다운이 풀리거나 나중에 풀이 커져도 이 숫자는 다시 채워지지 않는다.

현재 dev tip은 4f788f916 (#4620 출시 기록까지 포함)이고, 이 PR 본문은 기준을 62f02223a0이라고 적었다. 그 사이 #4618(2.56.0 open)과 #4620(docs)이 올라왔으니 리베이스가 필요하다. 코드 본체는 src/server/responses/core.tsmaxKeyPoolFailovers/keyPool429RetryAllowed 를 두고, src/providers/key-failover.tsrotateKeyOn429 / rotateProviderTransportOn429allowRotation 플래그를 추가한다. 거절 시에도 실패한 키 쿨다운은 기록하되 다른 키를 고르거나 디스크에 쓰지 않는다. 401 경로에는 이 플래그를 일부러 안 붙였다.

테스트는 핵심을 잘 잡는다. tests/adapters/key-failover.test.ts 의 health-only 시나리오는 allowRotation=false일 때 설정 파일 바이트·선택 이벤트·쿨다운을 검사하고, tests/server/server-key-failover-e2e.test.ts 는 exhausted/continuation/transient/budget-exhausted 네 모드로 전송 횟수·최종 본문·취소 여부를 고정한다. 픽스처가 6회를 넘기면 바로 터지게 해서 '테스트가 타임아웃으로만 실패하던' 예전 형태를 피했다. 작성자가 밝힌 대로 좁은 스위트 74통과는 있지만, --changed 임팩트 스위트는 900초 제한에 걸렸고 6589 pass / 57 fail로 끝나지 않았다. draft 유지 이유가 그것이다.

문서 쪽은 영어 providers.md와 8개 로케일, 그리고 structure/transports/responses.mdBounded API-key 429 rotation 절이 계약의 본체다. 그런데 같은 한 문장 링크를 adapters/catalog/clients/data-planes/gui/ops/xai/runtime/subagents/byte-accounting/inventory/streaming-health 등 관련 없는 structure 문서 여러 장 맨 위에 복붙했다. ownership 문서 폭발은 이 레포에서 자주 리뷰 지적되는 패턴이다. cost-guard #4546의 send-budget 계열(#4605~#4616)과 맞물리는 '요청 단위 상한'이라 방향은 현재 dev 과 잘 맞고, types/config 분할에 무효화되지도 않는다.

우선순위 64는 '실제 비용/루프 버그를 막는 코드'라서 문서 PR보다 높고, 동시에 draft·임팩트 스위트 미완료·structure 산포·tip 뒤처짐 때문에 70대로 올리지 않은 점수다. 콤보 전체 예산이 아니고 '키를 한 번씩만' 보장도 아니라고 본문이 솔직히 말한다. 그 범위를 메인테이너가 받아들일지가 머지 판단의 핵심이다.

src/server/responses/core.ts keyPool429RetryAllowed - continuation=false일 때만 auth-recovery reserve를 엿보는데, countedExternally:true 로 reserveDispatch를 호출한다. '검사만 하고 소비하지 않는다'는 주석과 실제 reserve API 의미가 같은지 tip 기준으로 한 번 더 확인이 필요하다.
src/server/responses/core.ts maxKeyPoolFailovers - apiKeyPool이 없거나 길이 1이면 상한이 0이라 회전이 아예 막힌다. 의도가 '풀이 없으면 돌리지 말 것'이면 맞고, 예전처럼 단일 키 경로의 다른 복구는 그대로인지도 회귀로 박아 두면 좋다.
structure/* 다수 파일 - 무관한 ownership 문서 상단에 동일 문장 링크를 뿌린 것은 계약 본체인 responses.md만 두고 나머지로의 back-link는 최소화하는 편이 이 레포 습관에 맞다.
PR base 62f02223a0 vs 현재 tip 4f788f916 - #4618/#4620 이후로 rebase 필요. 충돌 가능성은 docs/structure 쪽보다 core.ts send-budget 인접이 더 민감하다.
Verification - 로컬 --changed 57 fail 미귀속 상태로 draft. Ready 체크리스트도 CI/Codex·CodeRabbit 미해결로 비어 있다.

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

너의 추천
draft 유지. dev 4f788f916 위로 rebase한 뒤, structure 산포 문장을 걷거나 responses.md+providers 로케일만 남기고, 좁은 키-failover/e2e 스위트와 hosted CI가 초록인지 확인한 다음에만 Ready로 올린다. 지금 상태로는 머지하지 말고, #4546 레인에 'key-429 rotation cap'으로만 연결해 둔다.

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

@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: 78957f72f0

ℹ️ 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/server/responses/core.ts Outdated
@luvs01

luvs01 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@luvs01

luvs01 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

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

@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: e7dc2d7343

ℹ️ 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/server/responses/core.ts Outdated
@luvs01

luvs01 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@luvs01

luvs01 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

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

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

Reviewed commit: 9336e38f99

ℹ️ 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".

@luvs01

luvs01 commented Sep 14, 2026

Copy link
Copy Markdown
Contributor Author

Updated author evidence for the current head 9336e38. Both automated reviews are complete and their two findings are resolved, including the initially unpooled key and sidecar sites. CI completed with the explicitly documented Windows exceptions; this is author-ready, not a green-CI claim.

The reserve question was rechecked: reserveDispatch returns a permit, and shared state is charged only by permit.use(); the allowance query does not call it. Pools with fewer than two entries already decline key rotation in rotateKeyAfterFailure, while existing same-target retry and OAuth fallback policies remain separate.

The referenced dev changes from 62f0222 to 4f788f9 are a version bump and release evidence, with no diff in core.ts, key-failover.ts or request-execution-budget.ts. Rebasing solely to move the base label would restart validation without changing those semantics. The ownership manifest was not expanded: the short links satisfy its existing source-owner mapping while the contract stays in one canonical section. Maintainer acceptance of the invocation-level design remains a merge decision.

The four author-checklist boxes and review-ready label are complete. GitHub denied the author account permission to mark this PR ready, and the repository automation also reported a failed draft conversion. It therefore remains technically draft; a maintainer must perform that state transition. I have not retried the denied mutation.

@coderabbitai

coderabbitai Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

commit="90f6c2b39bda6883637b3598a67cc9048424e1d8"

echo '=== HEAD / COMMIT ==='
git rev-parse HEAD
git show --no-ext-diff --format=fuller --stat --summary "$commit"
echo '=== CHANGED FILES ==='
git diff-tree --no-commit-id --name-status -r "$commit"

echo '=== RELEVANT DIFF ==='
git diff --no-ext-diff --unified=100 "${commit}^" "$commit" -- \
  src/server/responses/combo-send-budget.ts \
  src/server/responses/core.ts \
  src/lib/request-execution-budget.ts \
  tests/responses/responses-send-budget-counts.test.ts \
  tests/lib/execution-budget-permits.test.ts \
  tests/server/server-key-failover-e2e.test.ts

echo '=== OUTLINES ==='
ast-grep outline src/server/responses/combo-send-budget.ts --items all
ast-grep outline src/lib/request-execution-budget.ts --items all
ast-grep outline tests/responses/responses-send-budget-counts.test.ts --items all

echo '=== IMPLEMENTATIONS ==='
cat -n src/server/responses/combo-send-budget.ts
sed -n '1,320p' src/lib/request-execution-budget.ts

echo '=== FACTORY CALL SITES / RESERVATIONS ==='
rg -n -C 12 '\b(comboExecutionBudgetPolicy|deriveSendBudgetScope|comboTargetSendBudget|reserveDispatch|finalRecoveryAllowance|reserveSpent|pendingExternalSends)\b' \
  src/server/responses/core.ts \
  src/server/responses/combo-send-budget.ts \
  src/lib/request-execution-budget.ts \
  tests -g '*.ts'

echo '=== PHYSICAL-SEND REGRESSION ==='
rg -n -C 30 '\[4,\s*1,\s*1\]|recovery-heavy|physical send|physical-send|combo' \
  tests/responses/responses-send-budget-counts.test.ts \
  tests/lib/execution-budget-permits.test.ts

echo '=== COMBO EXECUTION ==='
rg -n -C 20 '\b(comboExecutionBudgetPolicy|comboTargetSendBudget|deriveSendBudgetScope)\s*\(' src/server/responses/core.ts

Length of output: 196127


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== BUDGET ACCOUNTING CALL SITES ==='
rg -n -C 10 'onSendsConsumed|sendBudget\.used|\.used \+=|\.used =|remainingTransientSendBudget|recoverySendAllowance' \
  src tests -g '*.ts'

echo '=== RESPONSE CORE SEND BUDGET HELPERS ==='
sed -n '5260,5405p' src/server/responses/core.ts

echo '=== COMBO CHILD EXECUTION AND FAILURE BRANCHES ==='
sed -n '3230,3555p' src/server/responses/core.ts

echo '=== KIRO COMBO TEST AND RETRY ACCOUNTING ==='
sed -n '45,95p' tests/adapters/adapter-inner-send-budget.test.ts
fd -a '^kiro-retry\.ts$|^transport-retry\.ts$|^upstream-retry\.ts$' src
rg -n -C 12 'onSendsConsumed|sendBudget|remainingBaseSends' src/adapters/kiro-retry.ts src/lib/upstream-retry.ts src/adapters/cursor/transport-retry.ts 2>/dev/null || true

echo '=== CHILD EARLY RETURNS / THROWS BEFORE ADAPTER SEND ==='
rg -n -C 8 'return |throw |handleResponses\(' src/server/responses/core.ts -g '*.ts' | sed -n '1,520p'

Length of output: 141117


@luvs01 Reviewed commit 90f6c2b39bda6883637b3598a67cc9048424e1d8. I found no new correctness issue in the factory-derived scopes or the physical-send accounting.

The prior later-target starvation issue is addressed.

  • In src/server/responses/combo-send-budget.ts, Lines 69-74, ceiling now becomes the child scope’s maxTotalModelSends. This ceiling includes base sends and a qualifying recovery send. For three targets, the first child can use four sends, while the second and third children retain one send each.
  • In src/lib/request-execution-budget.ts, Lines 184-187 derive a child scope with the exact pending booking from the combo-hop permit. Lines 202-240 consume that booking once. This prevents the child’s first physical send from adding a second charge.
  • In src/server/responses/core.ts, Lines 3235-3250 reserve the combo hop and pass its permit to comboTargetSendBudget(...). This connects the parent reservation to the child scope that performs the physical send.
  • In tests/lib/execution-budget-permits.test.ts, Lines 157-176, the test now asserts [4, 1, 1]. This catches the previous failure mode where the first target exhausts the total and prevents target three from sending.
  • In tests/adapters/adapter-inner-send-budget.test.ts, Lines 56-71, the Kiro regression verifies physical sends as [3, 2, 1] and verifies six total sends. This covers adapter-owned sends that reserve each dispatch directly.

I inspected the source and tests. I did not run the test suite in this environment.


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

You are interacting with an AI system.

@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: 90f6c2b39b

ℹ️ 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/server/responses/core.ts Outdated
@luvs01

luvs01 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

The latest inline findings are corrected in 63807e330f76fe152ae9fcd948a736f3f2c0d8db. Regression evidence and remaining CI limitations are in the description.

@codex review

@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: 63807e330f

ℹ️ 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/server/responses/core.ts Outdated
@luvs01

luvs01 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Updated to c23a71c11b98418ce3b53f5c85c9156f92d7def0 after integrating dev and resolving the module-extraction conflicts. Validation and the exact-head CI run are in the description.

@codex review

@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: c23a71c11b

ℹ️ 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/server/responses/compact.ts
luvs01 and others added 2 commits September 15, 2026 19:57
…unds

Port the PR final dispatch deltas to current owners. Retry helpers settle the prepaid hop, while adapter sends retain the current dev dispatch-boundary confirmation and unused-hop refund. Product tests and CI not run here.

Co-authored-by: luvs01 <27862058+luvs01@users.noreply.github.com>
@lidge-jun
lidge-jun force-pushed the agent/key429-rotation-cap-20260914 branch from c23a71c to 6da3d84 Compare September 15, 2026 10:59
@lidge-jun

Copy link
Copy Markdown
Owner

Cross-platform CI is red at 6da3d84bc33ad99bbd4a8dd69a7cdd8cf294253c on both test 3/4 and macos 1/2, and it is deterministic rather than flaky — the same assertion fails identically on Linux and macOS, and the macOS lane already retried it.

The failing case is generic-OAuth hop reservations are handed back when no send happens > the adapter dispatch ladder confirms at the dispatch boundary and refunds otherwise. It is a source-oracle assertion, and it is asserting a literal that this PR's own implementation no longer produces:

Expected to contain: rebuildAndRefetch("oauth-account-429", () => { hop.permit?.use(); })

The source in the same branch reads:

const result = await rebuildAndRefetch("oauth-account-429",
  transportState.activeAdapter.fetchResponse ? () => { hop.permit?.use(); } : undefined);

So the callback became conditional on transportState.activeAdapter.fetchResponse — which is the right shape, and matches the comment two lines above it about retry helpers settling the externally counted hop themselves — but the oracle string was left at the unconditional form. Nothing about the runtime behaviour is wrong here; the assertion is stale against its own implementation.

Two ways out, and the second is better. Updating the expected literal to the conditional form restores green immediately. Asserting on the structure rather than on an exact source substring would stop this recurring: an exact-substring oracle over a multi-line expression breaks on any reformatting, including one that a later PR in this area will almost certainly cause.

Context for the timing: this PR is the bottom of the responses-budget lane in devlog/_plan/260915_bug_pr_landing_train/, because it defines the send-budget contract that #4656 modifies. The lane cannot be built on a red bottom, so this is currently the one thing holding that lane. Everything else approved alongside it — #4659, #4664, #4652, #4525 — came back green at their exact heads.

lidge-jun and others added 2 commits September 15, 2026 22:22
… exact source text

The source-oracle assertions in tests/lib/execution-budget-permits.test.ts were
written against an earlier form of the adapter-recovery-oauth-429 block and did
not survive this branch's own refactor of it, so Cross-platform CI was red on
test 3/4 and macos 1/2 with an identical failure on both.

Two things moved. The confirm callback became conditional on the adapter owning
its own fetchResponse, so the exact substring
rebuildAndRefetch("oauth-account-429", () => { hop.permit?.use(); }) no longer
appears anywhere. And the refund moved out of the failed arm into a finally, so
one idempotent release now covers the failed return, the success path and a
throw, which means the per-branch release the old assertion looked for is gone
by design.

Both assertions are rewritten to bind the behaviour instead of the formatting:
that rebuildAndRefetch is called with the oauth-account-429 tag and reaches
hop.permit?.use() within a bounded window, that the reservation is parked in
pendingHopPermit when the retry helper rather than the adapter will settle it,
that the failed arm returns, and that the finally releases. The neighbouring
assertions in this file already use indexOf and toMatch for exactly this reason;
this line was the only exact multi-line substring left, and it is why an
otherwise sound change went red.

No runtime code changed. 14 pass / 0 fail on
bun test tests/lib/execution-budget-permits.test.ts.

Co-authored-by: luvs01 <luvs01@users.noreply.github.com>
@luvs01

luvs01 commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

The corrective follow-up is published at 9c749cc4c8c377d05f4521310d64602d8c7ebe9c. The description records the failed-before/passed-after regression and current validation.

@codex review

@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: 9c749cc4c8

ℹ️ 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/server/responses/adapter-dispatch.ts Outdated
Declare when an HTTP adapter accounts for its own physical sends. Kiro receives the exact prepaid OAuth hop in a derived scope instead of charging a second reservation. Other fetchResponse implementations retain caller-owned confirmation after pacing. Carry the same ownership through queued continuations and refund unused hops.

Actual Kiro server regressions preserve all three credential attempts, including third-account success and a preceding reset. Before the change they stopped after the first account with a budget-exhaustion 502. The Kiro, permit and inner-budget run passed 30 tests/160 assertions. Two existing retry-helper OAuth cases passed with an explicit 20-second timeout after one default-5-second timeout. Typecheck, structure, privacy, file-size and diff checks pass; hosted CI remains separate.
Use a reasoning-only Kiro completion with the explicit emptyCompletionRetry opt-in. The public server takes one initial send, retries the first account, then follows two quota-driven OAuth hops and accepts the third account within four physical sends.

With only adapter-continuation restored to its pre-fix version, the fixture stops after the two first-account sends and fails. Restoring the prepaid continuation transfer passes this one test with four assertions. The previously passing suite was not repeated.

luvs01 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

The adapter-owned OAuth accounting follow-up and direct continuation regression are published at 77134192fe5972dd8708d3066267eddc76aa4c3f. The inline reply and updated description record the failed-before/passed-after cases and scoped validation. Exact-head CI is pending.

@codex review

@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: 77134192fe

ℹ️ 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/server/responses/adapter-continuation.ts Outdated

luvs01 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

Please review current head 6ce3aee226b3ff53cb02c27f01729b099f2100f3, including shared-reserve funding for the first terminal continuation and the formatting-independent retry-budget wiring regression.

@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: 6ce3aee226

ℹ️ 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/server/responses/adapter-continuation.ts Outdated

luvs01 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

Please review current head 107f5d8, particularly the repair-reserve handoff, prepaid generic retries retaining base allowance, and refunds before physical dispatch. The latest Kiro P2 is fixed with both reserve-enabled and reserve-exhausted real-adapter regressions.

luvs01 commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

Current head: 8885847. The additional change applies the same first-send-only prepaid permit consumption to the passthrough retry helper. Its real OAuth regression covers account A returning 429, account B's prepaid send resetting, then B succeeding using the remaining base attempt (three physical sends, no recovery reserve spent). The corresponding original-code control fails; 47 related tests / 491 assertions and type/structure/privacy/ratchet checks pass.

@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: 8885847bf5

ℹ️ 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".

sendBudget: replaySendBudget,
onPhysicalSend: send => noteAdapterPhysicalSend(continuationEstimate, send),
stream: nextParsed.stream,
executor: storedPoolReplayDispatchNotifier(providerFetch(route.provider, options.codexWsRuntimeIdentity, {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Confirm hops for adapters that ignore the supplied executor

When an empty-completion continuation on Command Code receives a 429 and rotates OAuth accounts, this notifier never confirms the reserved hop: that adapter captures its own executor and fetchCommandCode never invokes ctx.executor (and MiMo similarly calls fetch directly). The continuation therefore performs the replay, then lines 296-297 release its permit as if no dispatch occurred, allowing subsequent account rotations to send outside the shared request ceiling. Confirm caller-owned permits after the outer pacing wait before invoking adapters that do not declare fetchResponseUsesSendBudget, or require those adapters to dispatch through the supplied executor, with a focused non-Kiro OAuth continuation regression.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in bdf3dd9. Command Code inference (including its retry) and MiMo inference/401 replay now use ctx.executor when supplied. Command Code catalog discovery and MiMo credential bootstrap retain their separate existing transports. This lets the caller confirm its reserved hop at actual inference dispatch while retaining pre-dispatch refunds.

The real Command Code empty-completion -> 429 -> OAuth rotation regression fails on the original code with five sends and unnecessary further account rotations; the fix makes three sends and settles the existing caller-owned hop exactly once. This is not a claim of a new global cap on all internal adapter sends. Executor-selection regressions cover both adapters. All four fetchResponse implementations were checked; Google already uses the supplied executor and Kiro settles its own budget.

78 adapter/regression tests and the two recalled-native-combo tests passed (80 tests / 309 assertions), with the existing fixture/timeouts unchanged. Type, structure, privacy, ratchet and diff checks passed. Latest-head cross-platform CI is still pending.

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants