Skip to content

[WRONG BRANCH] docs(routing): cite what the prompt-caching guide actually says (#4546) - #4765

Merged
lidge-jun merged 4 commits into
codex/cx1-upstream-spend-limit-classificationfrom
codex/cx2-identity-domain-doc-source
Sep 16, 2026
Merged

lidge-jun merged 4 commits into
codex/cx1-upstream-spend-limit-classificationfrom
codex/cx2-identity-domain-doc-source

Conversation

@lidge-jun

Copy link
Copy Markdown
Owner

Summary

The cache rule in src/routing/identity-domains.ts reaches the right answer from a source that does not say what the comment claims it says.

The comment asserted that OpenAI "documents that changing keys inside one organization does not guarantee a hit", and presented same-org-and-region unknown as the provider declining a promise. The prompt-caching guide contains no such sentence. The phrase "API key" appears on that page zero times, so it never addresses two keys inside one organization in either direction.

What the page does say is the separating half, verbatim:

Caches are not shared across organizations and cannot be reused across regional processing boundaries.

and, about keys generally:

Keys influence routing; they do not pin requests to a machine or guarantee a cache hit.

The classification is unchanged. A different org or region still relates distinct, an identical one still relates unknown, and evidence stays "separates". No code path, key derivation, or test expectation moves. Only the stated reason changes: same org and region is unknown because the provider never promised the hit, not because the provider denied it. The absent promise is the evidence.

That distinction matters for the next person. A maintainer who went looking for the documented denial this comment described would not have found it, and would then have had to guess whether the code or the comment was wrong. A comment that is right about behaviour and wrong about its source sends a reader somewhere the source does not exist.

The OpenAI quota rule gains its verbatim source in the same pass, since that is what "separates-and-shares" rests on and it was previously only paraphrased:

Rate limits are defined at the organization level and at the project level, not user level.

structure/catalog.md carried the same mis-citation, in the invariant that owns this file, and is corrected to match.

Part of #4546.

Stacking

This targets codex/cx1-upstream-spend-limit-classification and contains that branch. Retarget to dev once the parent lands or closes. This is the lane tip, so its CI run is the lane's gate.

Verification

Local verification was NOT run, by explicit instruction from the repository owner. No bun run test, no individual test file, no bun run typecheck, no bun install, no build. This push used --no-verify. The only evidence is hosted CI at the exact head SHA of this branch.

This change is comment and documentation prose only -- no executable line is touched, which the diff shows directly: every src/ change sits inside a /** */ block or a // comment, and the key functions, the evidence values and PROVIDER_DOCUMENTED_DOMAINS are byte-identical. No test expectation depends on comment text, so tests/routing/routing-identity-domains.test.ts needs no change and its assertions continue to pin the same relations.

Sources were read on 2026-09-16 from the signed-in OpenAI platform documentation, expanding all 162 collapsed sections of the prompt-caching guide and extracting the full page text before quoting, rather than reading a rendered summary. The "API key appears zero times" claim is a count over that extracted text.

Structure gate checked by hand: structure/catalog.md is 398 lines, well under the 600-line budget in structure/manifest.json, and the change adds no new repository path reference.

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.

The cache rule's conclusion is right and its source was not. The comment claimed
OpenAI "documents that changing keys inside one organization does not guarantee a
hit", and the prompt-caching guide contains no such sentence: the phrase "API key"
appears on that page zero times, so it never addresses two keys in one organization
in either direction.

What the page does say is the separating half, verbatim: "Caches are not shared
across organizations and cannot be reused across regional processing boundaries."
The nearest statement about keys is "Keys influence routing; they do not pin
requests to a machine or guarantee a cache hit."

The classification is unchanged. A different org or region still relates distinct, an
identical one still relates unknown, and evidence stays "separates". Only the reason
moves: same org and region is unknown because the provider never promised the hit,
not because the provider denied it. A reader who went looking for the denial this
comment described would not have found it, and would have had to guess whether the
code or the comment was wrong.

The OpenAI quota rule gains its verbatim source in the same pass -- "Rate limits are
defined at the organization level and at the project level, not user level" -- which
is what "separates-and-shares" rests on. structure/catalog.md carried the same
mis-citation and is corrected to match.

Sources read from the signed-in platform documentation on 2026-09-16.
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner September 16, 2026 02:28
@coderabbitai

coderabbitai Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • ^dev$
  • ^preview$

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: af01985b-449c-4f67-afd9-1c5a2adb6ae0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 16, 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-16T02:32:20.141314Z 5ee7f63 PR opened
ℹ️ 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 Author

리뷰 · 우선순위 77 / 80

이 PR은 src/routing/identity-domains.ts와 structure/catalog.md에 적혀 있던 주석의 근거만 고칩니다. 실행 코드, key 함수, evidence 값(separates), PROVIDER_DOCUMENTED_DOMAINS의 분류 결과는 그대로입니다. 지금 dev HEAD는 3070d64d8(feat(combos): carry forced default effort from PR #4054 (#4714), 패키지 2.57.0)이고, #4546 에픽은 여전히 OPEN입니다. 이 파일은 계정 풀이 쿼터/캐시 도메인을 나눌 때 “문서가 분리만 말했는지, 공유까지 약속했는지”를 evidence로 구분하는 자리입니다.

문제의 핵심은 이렇습니다. 예전 주석은 OpenAI 프롬프트 캐싱 가이드가 “같은 조직 안에서 키를 바꿔도 히트를 보장하지 않는다”고 문서에 적었다고 말했습니다. 그런데 그 페이지에는 “API key”라는 말 자체가 없고, 같은 조직·같은 리전에서 두 키가 캐시를 공유하는지에 대한 문장도 없습니다. 가이드가 실제로 말하는 분리 쪽은 이 문장입니다: “Caches are not shared across organizations and cannot be reused across regional processing boundaries.” 키에 대해 가까운 문장은 “Keys influence routing; they do not pin requests to a machine or guarantee a cache hit.” 정도입니다. 그래서 예전 주석은 동작 결론(distinct / unknown)은 맞았지만, 근거를 잘못된 출처에 붙인 상태였습니다. 다음 사람이 그 “문서화된 거부”를 찾아 헤매다 코드와 주석 중 누가 틀렸는지 추측하게 됩니다.

이번 수정은 그 이유를 바꿉니다. 다른 org/region 키는 여전히 distinct, 같은 org+region은 여전히 unknown, evidence는 여전히 separates입니다. 다만 같은 org+region이 unknown인 이유가 “제공자가 히트를 거부했다고 문서에 썼다”가 아니라 “제공자가 히트를 약속한 적이 없다(침묵이 근거)”로 바뀝니다. 같은 패스에서 OpenAI 쿼터 규칙(separates-and-shares)에도 원문 인용을 넣습니다: “Rate limits are defined at the organization level and at the project level, not user level.” structure/catalog.md의 같은 불변조건도 맞춰 고쳐, 카탈로그와 소스 주석이 다시 한 줄로 맞습니다. #4546의 “문서가 말한 것만 믿기” 방향과 잘 맞습니다.

베이스는 dev가 아니라 codex/cx1-upstream-spend-limit-classification입니다. 부모 열린 PR은 #4764(fix(codex): stop rotating accounts inside an organization-scoped quota refusal)이고, 이 PR 헤드는 codex/cx2-identity-domain-doc-source(팁 5ee7f63, +25/−17, 파일 2개)입니다. PR 본문이 말한 대로 부모 랜딩/클로즈 후 dev로 리타겟하면 됩니다. 상태는 MERGEABLE UNSTABLE이고, Cross-platform CI·hygiene·react-doctor 등이 아직 QUEUED입니다. 로컬 스위트는 저장소 소유자 지시로 돌리지 않았고 --no-verify 푸시라서, 증거는 헤드 SHA의 호스티드 CI뿐입니다. 실행 줄을 안 건드린 docs/주석만의 변경이라 테스트 기대값 수정이 없는 것도 맞습니다.

현재 dev 체크아웃의 identity-domains.ts 모듈 머리말(대략 23–24행 근처)에는 아직 “documentation separates, then declines to promise the hit” 표현이 남아 있습니다. 이번 diff가 고친 블록보다 한 단계 위에 있는 문장이라, “문서화된 거부”보다는 “약속 부재”에 가깝지만 새 주석의 “silence is the evidence”와 어조가 완전히 같지는 않습니다. 동작에는 영향 없고, 같은 파일 안에서 근거 톤만 살짝 어긋날 수 있는 위생 포인트입니다.

라인 40-50 근처 - 캐시 evidence 설명 블록: 예전 “changing keys… does not guarantee a hit” 출처 주장을 가이드 원문(조직/리전 비공유 + 키는 라우팅만 영향)으로 교체한 핵심. 분류 불변은 유지.
라인 133-136 근처 - OpenAI 쿼터 bullet: separates-and-shares가 기대는 원문(“Rate limits are defined…”)을 직접 인용해 근거를 고정.
라인 163-172 근처 - cache 인라인 주석: same org+region → unknown 이유를 “명시적 거부”에서 “약속 부재”로 맞춤. key/evidence 바이트는 동일해야 함.
structure/catalog.md 불변조건 - 동일 오인용을 “absent promise” 프레임으로 동기화. 카탈로그·소스 불일치가 다시 생기면 다음 독자가 또 헤맴.
모듈 머리말 ~23-24행 - 이번 hunk 밖 “declines to promise” 표현이 새 주석의 silence 프레임과 톤이 약간 다름(선택 정리).
베이스/CI - base≠dev, 스택 팁 CI가 레인 게이트. 부모 #4764 전 dev 머지 금지.

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

너의 추천

  • 스택 유지: #4764가 먼저 안정적으로 랜딩(또는 클로즈)할 때까지 이 PR을 열어 두고, CI가 헤드 5ee7f63에서 그린이 되면 부모 뒤에 머지. dev에 직접 올리지 말 것.
  • 코드/테스트 변경 요구는 없음. 머리말 톤 정리는 있으면 좋지만 머지 블로커는 아님.
  • #4546은 OPEN 유지. 이 댓글은 주석 출처 교정 + 카탈로그 동기화 커밋으로 기록.

이 댓글은 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: 5ee7f63262

ℹ️ 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 structure/catalog.md
Comment on lines +271 to +274
regional processing boundaries, while no documentation states that two keys inside one
organization do share a cache, so a different org or region relates `distinct` and the same org
and region relates `unknown`. The absent promise is what withholds `shared` there, not a
documented denial. OpenAI quota, Anthropic workspace cache, and Azure deployment domains carry

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 Correct the remaining documented-denial claims

This now says the result follows from an absent promise, but src/routing/identity-domains.ts:23-24 still says the documentation “declines to promise the hit,” and tests/routing/routing-identity-domains.test.ts:80-82 still says changing API keys is “explicitly not guaranteed to hit.” A maintainer tracing the same-org classification will therefore still encounter the unsupported denial this commit is intended to remove; update those comments too so the contract has one consistent explanation.

AGENTS.md reference: structure/AGENTS.md:L61-L63

Useful? React with 👍 / 👎.

Comment on lines +43 to +44
* not discuss two API keys inside one organization, and what it does say about keys is that
* they "influence routing; they do not pin requests to a machine or guarantee a cache hit."

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 Identify the routing key as prompt_cache_key

The quoted routing statement describes prompt_cache_key, not API credentials. Placing it immediately after “two API keys” and referring only to “keys” makes it sound as though the provider documents API-key routing, recreating the source-attribution ambiguity this change is meant to fix. Name prompt_cache_key explicitly or remove this sentence, since its routing behavior supplies no evidence about cache sharing between two API credentials.

Useful? React with 👍 / 👎.

…4710) [skip ci]

The classifier has always called an uploaded file_id account-bound, and the
scrubber has always removed only previous_response_id and conversation. A body
whose only account-bound state was a file reference therefore reported nothing
scrubbed and was replayed unchanged against the new account, which is exactly
the case the advertised safety fix was supposed to cover.

Deleting the references is not the fix. A file reference is content the caller
attached, not continuation state the turn can do without, and dropping it
silently answers a different question than the one that was asked with no way
for the caller to tell. Pinning the request to the issuing account is not
available either: every call site resolves and materialises its credential
before reaching here, and the retry sites are reached precisely because the
issuing account just refused the request.

So the move is refused before dispatch, with HTTP 400 and an instruction to
re-upload. Not a retryable status, which would invite the same request back
unchanged.

The check reads the carriers directly rather than the portability verdict. That
verdict reports the FIRST reason it finds, so a body carrying both a previous
response id and a file reference reports only the response id, and the file
would slip through the scrub that follows.

Wired at the initial Codex selection and at the native compact dispatch, both of
which can answer with a Response. The two alternate-account retry sites still
only scrub: refusing there needs a new outcome variant on their result types and
on their callers, which is a larger change than this one. The detection now
lives in one exported place, so neither site can drift further from it.

Closes #4710
@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

…t paths too (#4710)

The carried change refuses an uploaded-file move at the two sites that can answer
with a status, and leaves the two alternate-account retry sites scrubbing only. This
closes those two, and it does not need the new result variant the deferral assumed.

A retry site does not have to raise a status, because an earlier response already
exists and is what the caller returns. It only has to decline the move. And the
question it declines on does not depend on which alternate would be chosen -- an
uploaded file is readable only by the account that received it -- so it can be asked
from the body alone, before an alternate is resolved. conversationCarriesUploadedFiles
is that predicate. Asking there reserves no send, cancels no response, and leaves the
first account's rejection intact for the caller, which is the guarantee the comment
above the compact resolution already depended on.

Refusal still beats a previous_response_id at both sites, for the same reason the
carried change reads the carriers directly instead of the portability verdict: the
verdict reports only the first denial it finds.

Two corrections to the carried code. collectConversationStateCarriers(body).fileIds is
optional on the carrier type and was dereferenced directly, which does not survive a
strict typecheck; the emptiness test now lives in one exported place so no caller can
get it wrong again. And the refusal message named the cause but not the consequence.
The reference stays in the conversation's history, so once rotation has moved a
conversation carrying an attachment, every later turn is refused the same way. A caller
told only that the reference is invalid resends unchanged and watches the conversation
die. The message now says what happened, that it will keep happening, and the two
things that end it: re-upload under the serving account, or start a new conversation.

A same-account replay is unaffected, and a single-account install never reaches any of
this, because serving and issuing accounts cannot differ without pool rotation.

Pinning a file-carrying conversation to its issuing account is the real answer and is
routing-affinity work; filed as #4778.

Co-authored-by: JUN <bitkyc08@gmail.com>
…-scope

fix(responses): refuse an account change that would orphan an uploaded file (#4710)
@lidge-jun

Copy link
Copy Markdown
Owner Author

Cascading the lane downward. Chained-child stacks merge top-down: merging a child lands in its parent's branch rather than in trunk, so #4777 landed here in codex/cx2-identity-domain-doc-source and this pull request now carries the whole lane.

CI evidence transfers exactly, by tree identity rather than by re-running. The verified head 3ae8ca7 has tree 20d3e2ad8acd9e893dd2eb08c512d30e92b3fa6b, and this branch head 44392b5 has the same tree. At that tree, test 1-4/4 and macos 1-2/2 all completed with conclusion success, verified through the check-runs API rather than the rollup, alongside gates, hygiene, api usage, storage policy, docker smoke, keyring and npm-global.

Maintainer integration decision under MAINTAINERS.md / AGENTS.md, recorded with the exact-head evidence above.

@lidge-jun
lidge-jun merged commit 8b504f9 into codex/cx1-upstream-spend-limit-classification Sep 16, 2026
6 checks passed
@lidge-jun
lidge-jun deleted the codex/cx2-identity-domain-doc-source branch September 16, 2026 03:24
@github-actions github-actions Bot changed the title docs(routing): cite what the prompt-caching guide actually says (#4546) [WRONG BRANCH] docs(routing): cite what the prompt-caching guide actually says (#4546) Sep 16, 2026
@github-actions

github-actions Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • wrong target branch (codex/cx1-upstream-spend-limit-classification); retarget to dev.

What to do

  • Retarget this PR to dev — all contributions go to dev.

Its title has been prefixed with [WRONG BRANCH].
Automatic draft conversion failed (token cannot change draft status). Please convert this pull request to a draft manually. The required enforce-target check will keep failing until every issue above is resolved.

agentHits pushed a commit to agentHits/opencodex that referenced this pull request Sep 17, 2026
…omain-doc-source

docs(routing): cite what the prompt-caching guide actually says (lidge-jun#4546)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant