Repository navigation
[Feature]: make manual reset-credit retries use durable operation identity #2275
Description
Area
Authentication and account pool
What are you trying to accomplish?
Make an explicit manual reset-credit redemption safely retryable across an ambiguous upstream result or process restart by reusing one durable operation identity.
What prevents this today?
On current dev, POST /api/codex-auth/reset-credits/consume creates a fresh crypto.randomUUID() inside every request and sends it as redeem_request_id. It does not reserve an identity in the ledger from #1829, record a post-dispatch ambiguous outcome, or return an already-settled terminal result.
#657 is closed as not planned, and the broader #1526 and dormant-policy #1624 pull requests are closed. No active issue currently owns manual-ledger activation.
What should OpenCodex do?
- Bind each confirmed manual redemption intent to one caller-stable canonical UUIDv4.
- Call
openManualResetCreditOperationbefore upstream dispatch. - Use the ledger-returned canonical operation ID as
redeem_request_id. - Make identity mismatch, capacity, unavailable, and stored-terminal outcomes perform no new upstream dispatch.
- Mark uncertain post-dispatch outcomes ambiguous.
- Durably settle
reset,already_redeemed,nothing_to_reset, andno_creditbefore returning the terminal response. - Preserve the same identity through supported CLI/GUI retry and process restart behavior.
- Add end-to-end regressions proving no duplicate dispatch after ambiguity, restart, concurrent retry, identity mismatch, or stored terminal state.
- Preserve the existing authorization boundary; do not add automatic, background, scheduled, or Responses-triggered redemption in this issue.
- Keep the ledger internal; no package-root export is required for this consumer.
Activation implementation owner: @luvs01.
Activation still requires CODEOWNER/maintainer review. /src/codex/ is owned by @lidge-jun and @Ingwannu. Any later Responses-core integration requires @lidge-jun specifically.
Example usage or interface
POST /api/codex-auth/reset-credits/consume
Content-Type: application/json
{
"accountId": "<account-id>",
"operationId": "00000000-0000-4000-8000-000000000001"
}A retry of the same confirmed intent sends the same operationId and either resumes the same durable operation or returns its stored terminal result.
Alternatives or workarounds
Minting a new server-side UUID for every retry cannot distinguish a new intent from recovery of an ambiguous prior dispatch. Reopening #1526 would also revive its stale ledger, consent, GUI, API, and documentation bundle. #822 remains a separate proactive scheduling feature.
Additional context
- Depends on feat(codex): add durable reset-credit operation ledger #1829.
- feat(codex): persist reset-credit operation identity #1526 is historical implementation/reference material only.
- [Feature]: opt-in reset-credit recovery after verified pre-stream quota exhaustion #657 is historical auto-recovery context and does not authorize activation while closed.
- [Feature]: opt-in crash-safe reset-credit auto-redemption before expiry #822 remains a separate pre-expiry scheduler contract.
Checks
- I searched existing issues and documentation.
- This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
- I removed secrets and personal data.
Activity
Ingwannu commentedon Aug 21, 2026
Confirmed against current dev: this is a real, narrowly scoped follow-up.\n\nThe consume handler currently creates a new crypto.randomUUID() inside every request, and the CLI sends only accountId. Therefore a retry after an ambiguous dispatch or process restart cannot prove that it is the same user-confirmed redemption intent.\n\nThe implementation boundary should stay conservative:\n\n- #1829 must land first with exact-head CI and CODEOWNER review.\n- The caller must preserve one canonical UUIDv4 across retries and restart; moving UUID creation to another per-request server location would not solve the problem.\n- Ledger outcomes such as identity mismatch, capacity, unavailable, ambiguous, and stored terminal state must never cause an untracked second upstream dispatch.\n- Terminal upstream codes must be settled durably before the response is returned.\n- Keep this manual and authorization-equivalent to the current endpoint. Do not add background, scheduled, Responses-triggered, or automatic redemption.\n- Add endpoint plus CLI regressions for ambiguity, restart, concurrent retry, stored terminal replay, and no-dispatch failure states. If the GUI becomes a caller, its operation identity lifecycle needs the same coverage.\n\nI am leaving this open as the activation issue. It is blocked on #1829 rather than ready for an independent implementation or merge today.
lidge-jun commentedon Aug 21, 2026
리뷰 · 우선순위 53 / 80
지금
devHEAD7881319e7에서 본문 맞음.src/codex/auth-api.ts:1746-1763POST /api/codex-auth/reset-credits/consume가 요청마다crypto.randomUUID()를 새로 찍어서redeem_request_id로 보냄. 바디는accountId만 받음.src/cli/account-auth.ts:224-237ocx account reset-credits --consume도{ accountId }만 보냄. 재시도/프로세스 재시작이 새 아이덴티티가 됨. 업스트림이 모호하거나 타임아웃이면 두 번째 클릭이 두 번째 소모임.src/codex/reset-credit-recovery.ts는 이미operationId를 아는 어댑터 계약임. Responses 쪽 회복 플라이트용임. 수동 consume 핸들러는 그 원장을 안 염. #1829가 그 원장 PR임. draft. 이미 grok-bot 리뷰 있음. 이 이슈가 그 원장을 수동 경로에 켜는 계약임. 랜덤 중복으로 #1829를 닫지 말 것. #1829가 착지하기 전엔 이 이슈만으로 구현하지 말 것. 원장 없는 아이덴티티는 메모리 맵이 됨.범위도 맞음. 자동/백그라운드/스케줄/Responses 트리거 소모를 이 이슈에 넣지 말 것. #822는 만료 전 스케줄러라 다른 레인임. #657은 not planned로 닫힘. #1526/#1624는 닫힌 묶음임. 다시 열어서 낡은 GUI/동의/문서 번들을 살리지 말 것. 원장은 내부. 패키지 루트 export 금지. 인가 경계 유지.
/src/codex/CODEOWNER는 lidge-jun/Ingwannu. Responses-core 연동은 나중이고 그건 lidge-jun.호출 계약은 호출자 안정 UUIDv4.
openManualResetCreditOperation을 업스트림 전에 열고, 원장이 준 canonical id를redeem_request_id로 씀. 아이덴티티 불일치/용량/unavailable/이미 터미널이면 새 디스패치 없음. 모호한 사후 결과는 ambiguous로 남김.reset/already_redeemed/nothing_to_reset/no_credit는 응답 전에 내구성 있게 settle. CLI/GUI 재시도와 프로세스 재시작이 같은 id를 유지. 그 전이를 e2e로 잠궈라.#2188 사이드카 이미
dev.x_search넣지 말 것. Grok/Responses 레인 아님. 크레딧 수동 소모임.types.ts/config.ts스플릿은 이 이슈 자체가 스키마 PR이 아님. 프리뷰 배포 아님. v2.28.0 이미 태그됨. 핫 크래시 아님. 다만 리셋 크레딧은 한 장이 비싸고 모호한 재시도가 돈을 두 번 씀. 그래서 53.해결방안: 이 이슈는 계약으로 열어 둬라. 구현은 #1829 원장이 현재
dev에 착지한 다음. 수동 consume만 활성화. 자동 소모 넣지 말 것. #822/#1526/#657 다시 열지 말 것. CLI가 같은operationId를 재시도에 보내게 하라. 스플릿이auth-api.tsconsume 핸들러를 다시 옮기면 리베이스하지 말고 닫고 다시 짜라. 지금은 그 정도 아님.이 댓글은 grok-bot이 작성했습니다
lidge-jun commentedon Sep 3, 2026
Closing in favor of #3375, which carries the remaining scope forward.
Thank you @luvs01 — this report on durable operation identity for manual reset-credit retries was accurate, and part of it shipped.
What landed. The durable ledger landed in 7c68768 (
src/codex/reset-credit-operation-ledger.ts).What is still missing. accepting and settling a caller-stable operation ID on the manual consume endpoint and CLI — it still mints a fresh UUID per request at
src/codex/auth-api.ts.Rather than leave four issues open each describing one facet of the same unfinished lifecycle, the surviving scope is consolidated in #3375, which names this issue and credits you for the original analysis. Please follow and comment there; if you think the consolidation dropped something you asked for, say so on #3375 and it will be added.