Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b96aa7d
fix(codex): defer validation for quota-exhausted account registration
Sep 7, 2026
be3b780
fix(codex): fence deferred validation against stale guardian results
Sep 7, 2026
32e3b31
Merge remote-tracking branch 'origin/dev' into fix/codex-quota-regist…
Sep 7, 2026
ec9cc94
fix(codex): publish readiness changes and recheck pending selection
Sep 7, 2026
1639ce4
fix(codex): enforce pending readiness at request auth boundaries
Sep 7, 2026
2636e63
fix(codex): fence failed warmup metadata by credential generation
Sep 7, 2026
d2d6626
fix(codex): distinguish manual validation from background quota refresh
Sep 7, 2026
ebf4728
fix(codex): report pending validation in local health diagnostics
Sep 7, 2026
3dd3cfd
test(codex): distinguish passive quota observation from validation
Sep 7, 2026
94c175e
Merge remote-tracking branch 'origin/dev' into fix/codex-quota-regist…
Sep 7, 2026
77ac748
test: remove host timing dependencies from readiness checks
Sep 7, 2026
ceca43d
docs(pr): replace component preview with dashboard registration evidence
Sep 7, 2026
acfdf51
fix(codex): require a CSRF-protected POST for deferred validation
Sep 7, 2026
094d253
fix(codex): support explicit CLI recovery and await validation in the…
Sep 7, 2026
a1ec6b3
docs(codex): publish CLI recovery reference and final dashboard evidence
Sep 7, 2026
3d901b5
fix(cli): retain pending Codex readiness in account output
Sep 7, 2026
25798a5
fix(codex): report deferred readiness when login completes
Sep 7, 2026
f4ae062
fix(codex): retain actionable validation failures without changing pa…
Sep 7, 2026
55de3ee
fix(codex): clear matching reauth state after deferred validation
Sep 7, 2026
f1d7683
Merge remote-tracking branch 'origin/dev' into fix/codex-quota-regist…
Sep 7, 2026
8f94fd1
fix(codex): require dashboard consent for deferred validation
Sep 7, 2026
4136572
fix(codex): preserve validation intent at quota flight settlement
Sep 7, 2026
a1b5d23
Merge remote-tracking branch 'origin/dev' into fix/codex-quota-regist…
Sep 7, 2026
255fa82
test: keep quota registration PR scoped to account readiness
Sep 7, 2026
57b59a0
Merge dev quota activation while preserving pending validation guards
Sep 7, 2026
cb28a09
Merge remote-tracking branch 'origin/dev' into fix/codex-quota-regist…
Sep 7, 2026
aeb86cb
Merge the terminal-validation fix (#4120) into quota-deferred registr…
lidge-jun Sep 9, 2026
703f002
Merge origin/dev into quota-deferred registration
lidge-jun Sep 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/pr-assets/codex-quota-evidence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Codex quota registration browser verification

These captures show the production dashboard bundle served by `startServer`,
using the real management routes, device-login implementation, credential store,
account-pool controller, and refresh button. They are not component fixtures.

The server used an isolated OpenCodex/Codex home. Only external provider responses
were mocked: device authorization, token exchange, WHAM usage, and the completed
inference stream. The account identity and credentials are synthetic. The empty
native-main home explains the separate Main Account warning in both screenshots.
No live OpenAI account was used or charged.

The browser was Microsoft Edge through Playwright, at 1440 × 1100, English/light
theme, with external browser requests blocked. Verification ran on Windows.
The final capture used runtime and GUI changes through `25798a590`.

1. Open Codex Set → Multi-auth, click Add, enter an account ID, and choose Device
code login. Authorize through the mock device service.
2. The actual token exchange and authenticated usage read return a Pro account
with weekly usage at 100%. Registration persists it as validation pending:
one usage read, zero model calls, and no successful-validation timestamp.
The completion notice also says validation is pending; no model-selection
dialog opens for this unroutable account.
3. Reload the page and click Refresh quotas while usage is still 100%.
The account remains pending. Cumulative counts: two usage reads, zero model
calls. The pending screenshot shows the status and the missing selection button.
4. Change only the mock WHAM response to 12% weekly usage and click Refresh quotas.
The server receives a completed validation response. Cumulative counts:
three usage reads, one model call. The pending flag clears, the validation
timestamp is persisted, and “Use this account next” appears.
5. Select the recovered account and confirm the dialog. The real active-account
endpoint and stored config both report `weekly-demo` as selected and pinned.

Both explicit refreshes used `POST /api/codex-auth/accounts/refresh` with the GUI
session's CSRF header. The actual server accepted them. Separate live-server tests
reject POSTs without CSRF or with a different Origin; GET quota refreshes never
complete pending validation.

| Capture | Weekly usage | Pending | Model calls so far |
| --- | --- | --- | --- |
| `codex-quota-pending.png` | 100% | Yes | 0 |
| `codex-quota-recovered.png` | 12% | No | 1 |

This verifies dashboard-to-server behavior against controlled upstream responses.
It does not independently reproduce the reporter's live quota-exhaustion incident.
Binary file added .github/pr-assets/codex-quota-pending.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/pr-assets/codex-quota-recovered.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 7 additions & 7 deletions docs-site/src/content/docs/fr/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,13 +367,13 @@ délégation v1/base/v2 et de ses mécanismes de repli.

## Préchauffage des comptes Codex

Lorsqu'un compte ChatGPT est ajouté au groupe de comptes Codex, opencodex le vérifie avant de l'enregistrer
avec une petite requête en streaming vers le service Codex Responses. La requête utilise un véritable tableau
d'éléments Responses (`input: [{ type: "message", ... }]`), attend `response.completed` et utilise par défaut
`gpt-5.4-mini`. Si ce modèle renvoie HTTP 400, opencodex réessaie avec `gpt-5.5` ; les détails structurés de
l'erreur en amont sont affichés sans exposer le corps brut de la réponse. La revalidation en arrière-plan est
distincte et désactivée par défaut. Elle ne s'exécute que si Token Guardian est actif, si la stratégie
d'actualisation `chatgpt` vaut `proactive` et si `tokenGuardian.codexWarmupEnabled` vaut true.
L’ajout ou la réauthentification vérifie normalement le compte avant son enregistrement par une petite requête attendant `response.completed`. Le modèle par défaut est `gpt-5.4-mini`, avec un essai sur `gpt-5.5` en cas de HTTP 400. Les erreurs publiques contiennent des catégories fixes, sans corps de réponse brut.

Si la lecture authentifiée des quotas avec le nouveau jeton OAuth confirme un quota de 5 heures, hebdomadaire ou mensuel épuisé, le compte est enregistré sans appel au modèle et affiche **Validation en attente**. Il reste exclu du routage après un redémarrage ou un renouvellement du jeton. Après récupération du quota, actualisez les quotas : une lecture récente et complète avec de la capacité disponible permet une petite requête de validation. Seule sa réussite active le compte. Tout échec conserve la restriction. Les lectures passives ne déclenchent pas cette requête. Un quota inconnu à l’inscription conserve la vérification habituelle.

Sans tableau de bord, `ocx account refresh openai` effectue la même validation. `ocx account list openai --quota --refresh` consulte uniquement les quotas et ne valide pas les comptes en attente. La validation explicite peut aboutir pendant une pause, sans reprendre ni sélectionner le compte. Les échecs d’autorisation du modèle demandent une réauthentification et restent visibles même si la lecture des quotas réussit.

La revalidation en arrière-plan est distincte et désactivée par défaut. Elle nécessite Token Guardian, la politique `proactive` du fournisseur `openai` et `tokenGuardian.codexWarmupEnabled`, et ignore les comptes dont la validation d’inscription est en attente.

## Restauration de Codex natif

Expand Down
14 changes: 7 additions & 7 deletions docs-site/src/content/docs/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -554,13 +554,13 @@ Catalog sync makes the selected sub-agent models available to Codex; see [Codex

## Codex account warmup

When a ChatGPT account is added to the Codex account pool, opencodex verifies it before persistence
with a small streaming request to the Codex Responses backend. The request uses a real Responses
item array (`input: [{ type: "message", ... }]`), waits for `response.completed`, and defaults to
`gpt-5.4-mini`. If that model returns HTTP 400, it retries with `gpt-5.5`; structured upstream error
details are surfaced without exposing raw response bodies. Background revalidation is separate and
off by default; it runs only when Token Guardian is enabled, the `chatgpt` refresh policy is
`proactive`, and `tokenGuardian.codexWarmupEnabled` is true.
When a ChatGPT account is added or reauthenticated, OpenCodex normally verifies it before saving with a small streaming request to the Codex Responses backend. It waits for `response.completed`, defaults to `gpt-5.4-mini`, and retries with `gpt-5.5` on HTTP 400. Public errors contain fixed failure categories rather than raw upstream response bodies.

If the new OAuth credential's authenticated usage lookup confirms an exhausted 5-hour, weekly, or monthly quota, the account is saved without this model request and shows **Validation pending**. It cannot serve pool requests, even after a restart or token refresh. Once quota recovers, **Refresh quotas** finishes validation: a fresh, complete usage reading with headroom permits one small model request, and only a completed response enables the account. Failed or incomplete readings and failed validation preserve the restriction. Passive account polling does not trigger deferred validation. Unknown usage during initial registration retains the normal warmup gate.

On a headless installation, `ocx account refresh openai` performs the same validation. `ocx account list openai --quota --refresh` only reads usage and does not validate pending accounts. Explicit validation can complete while an account is paused; it does not resume or select that account. Model authorization failures require reauthentication and remain visible even when quota reads succeed.

Background revalidation is separate and off by default. It requires Token Guardian, the `openai` provider's `proactive` refresh policy, and `tokenGuardian.codexWarmupEnabled`. It skips accounts awaiting deferred registration validation.

## Restoring native Codex

Expand Down
3 changes: 3 additions & 0 deletions docs-site/src/content/docs/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ Desktop mode and current credential-bound upstream permission; a catalog entry a
authorize a request. See [Luna Reserve alongside routed models](/reference/cli/providers-accounts/#luna-reserve-alongside-routed-models)
for setup, restart order, authorization requirements, and unsupported helpers.

For adding an account with exhausted quota and finishing its deferred validation, see
[Codex account warmup](/guides/codex-integration/#codex-account-warmup).

### Providers overview pool capacity

For Codex login in Pool mode, the Providers overview shows a configured-weight estimate of the
Expand Down
8 changes: 7 additions & 1 deletion docs-site/src/content/docs/ja/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,13 @@ ocx service install # persistent: auto-starts on login and respawns on crash

## Codex アカウントのウォームアップ

ChatGPT アカウントが Codex アカウント プールに追加されると、opencodex は、Codex Response バックエンドへの小さなストリーミング リクエストで永続化する前にそれを検証します。リクエストは実際の応答項目配列 (`input: [{ type: "message", ... }]`) を使用し、`response.completed` を待機し、デフォルトは `gpt-5.4-mini` になります。そのモデルが HTTP 400 を返した場合、`gpt-5.5` で再試行します。構造化されたアップストリーム エラーの詳細は、生の応答本体を公開することなく表示されます。バックグラウンドの再検証は個別に行われ、デフォルトではオフになっています。これは、トークン ガーディアンが有効で、`chatgpt` 更新ポリシーが `proactive` で、`tokenGuardian.codexWarmupEnabled` が true の場合にのみ実行されます。
アカウントの追加・再認証では通常、保存前に小さなモデルリクエストで `response.completed` を確認します。既定モデルは `gpt-5.4-mini` で、HTTP 400 の場合は `gpt-5.5` で再試行します。公開エラーには固定の分類のみを表示し、生の応答本文は公開しません。

新しい OAuth トークンによる使用量取得で5時間・週次・月次の上限到達が確認された場合、モデルを呼ばずに保存し、**検証待ち**と表示します。再起動やトークン更新後も使用できません。上限回復後に使用量を更新すると、十分な空き容量を示す完全な最新情報を確認してから小さなモデルリクエストを送り、完了した場合のみ使用可能になります。取得や検証の失敗では待機状態を維持します。通常の状態ポーリングは検証リクエストを送りません。初回登録時の使用量が不明な場合は通常の検証が必要です。

ダッシュボードを使わずに `ocx account refresh openai` で同じ検証を実行できます。`ocx account list openai --quota --refresh` は使用量のみを取得し、待機中のアカウントを検証しません。 一時停止中でも明示的な検証は完了できますが、アカウントの再開や選択は行いません。モデルの認証エラーは再認証が必要な状態として表示され、使用量の取得に成功しても消えません。

バックグラウンド再検証は別機能で既定では無効です。Token Guardian、`openai` の `proactive` 更新ポリシー、`tokenGuardian.codexWarmupEnabled` が必要で、登録検証待ちのアカウントは除外します。

## ネイティブ Codexの復元

Expand Down
8 changes: 7 additions & 1 deletion docs-site/src/content/docs/ko/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,13 @@ catalog sync는 선택된 서브에이전트 모델을 Codex가 쓸 수 있게

## Codex 계정 워밍업

ChatGPT 계정을 Codex account pool에 추가하면, opencodex는 이를 저장하기 전에 Codex Responses backend로 작은 streaming request를 보내 확인합니다. 요청은 실제 Responses item array(`input: [{ type: "message", ... }]`)를 사용하고, `response.completed`를 기다리며, 기본값은 `gpt-5.4-mini`입니다. 그 모델이 HTTP 400을 반환하면 `gpt-5.5`로 다시 시도합니다. 구조화된 upstream error detail은 보여 주되 raw response body는 노출하지 않습니다. background revalidation은 별도 기능이며 기본값은 꺼져 있습니다. Token Guardian이 활성화되고, `chatgpt` refresh policy가 `proactive`이며, `tokenGuardian.codexWarmupEnabled`가 true일 때만 실행됩니다.
ChatGPT 계정을 추가하거나 재인증할 때 OpenCodex는 일반적으로 저장 전에 작은 모델 요청으로 확인합니다. `gpt-5.4-mini`의 `response.completed`를 기다리며 HTTP 400이면 `gpt-5.5`로 재시도합니다. 오류에는 고정된 실패 분류만 표시하고 원본 응답 본문은 노출하지 않습니다.

새 OAuth 토큰으로 인증된 사용량 조회에서 5시간·주간·월간 한도 소진이 확인되면 모델 요청 없이 계정을 저장하고 **검증 대기**로 표시합니다. 재시작이나 토큰 갱신 후에도 요청에 사용되지 않습니다. 한도 회복 후 **사용량 새로고침**을 실행하면, 여유가 있는 완전한 최신 사용량을 확인한 뒤 작은 모델 요청을 보내고 완료 응답을 받아야 계정을 사용할 수 있습니다. 조회나 검증 실패 시 대기 상태를 유지합니다. 일반적인 화면 상태 조회는 이 모델 요청을 보내지 않습니다. 최초 등록 때 사용량이 불명확하면 기존 워밍업 검증이 필요합니다.

대시보드 없이도 `ocx account refresh openai`로 같은 검증을 실행할 수 있습니다. `ocx account list openai --quota --refresh`는 사용량만 조회하며 대기 계정을 검증하지 않습니다. 일시 정지된 계정도 명시적인 검증을 완료할 수 있지만, 검증이 계정의 일시 정지를 해제하거나 계정을 선택하지는 않습니다. 모델 인증 실패는 재인증이 필요한 상태로 표시되며 사용량 조회가 성공해도 숨겨지지 않습니다.

별도의 백그라운드 재검증은 기본적으로 꺼져 있습니다. Token Guardian, `openai`의 `proactive` 갱신 정책, `tokenGuardian.codexWarmupEnabled`가 필요하며 등록 검증 대기 계정은 제외합니다.

## 네이티브 Codex 복원

Expand Down
15 changes: 7 additions & 8 deletions docs-site/src/content/docs/ru/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,14 +360,13 @@ v1/base/v2 при делегировании и fallback — в

## Прогрев аккаунтов Codex

Когда аккаунт ChatGPT добавляется в пул аккаунтов Codex, opencodex проверяет его до сохранения
небольшим streaming-запросом в backend Codex Responses. Запрос использует настоящий массив
Responses item'ов (`input: [{ type: "message", ... }]`), ждёт `response.completed` и по умолчанию
использует `gpt-5.4-mini`. Если эта модель отвечает HTTP 400, выполняется повтор с `gpt-5.5`;
структурированные детали upstream-ошибки показываются без раскрытия сырых тел ответа. Фоновая
перепроверка отделена от этого процесса и по умолчанию выключена; она запускается только когда
включён Token Guardian, у `chatgpt` выставлена политика refresh `proactive`, а
`tokenGuardian.codexWarmupEnabled` равен true.
При добавлении или повторной аутентификации аккаунт обычно проверяется до сохранения небольшим запросом, ожидающим `response.completed`. По умолчанию используется `gpt-5.4-mini`, при HTTP 400 — повтор с `gpt-5.5`. Публичные ошибки содержат фиксированные категории без исходного тела ответа.

Если запрос квоты с новым OAuth-токеном подтверждает исчерпание пятичасовой, недельной или месячной квоты, аккаунт сохраняется без вызова модели со статусом **Ожидает проверки**. Перезапуск и обновление токена не включают маршрутизацию. После восстановления квоты обновите её: полные свежие данные с доступной ёмкостью разрешают небольшой проверочный запрос. Только успешное завершение включает аккаунт. Ошибки сохраняют ограничение. Пассивный опрос не отправляет такой запрос. Неизвестная квота при регистрации требует обычной проверки.

Без панели управления ту же проверку выполняет `ocx account refresh openai`. Команда `ocx account list openai --quota --refresh` только читает квоты и не проверяет ожидающие аккаунты. Явная проверка может завершиться для приостановленного аккаунта, не возобновляя и не выбирая его. Ошибки авторизации модели требуют повторного входа и остаются видимыми даже при успешном чтении квоты.

Фоновая проверка — отдельная функция, выключенная по умолчанию. Она требует Token Guardian, политики `proactive` провайдера `openai` и `tokenGuardian.codexWarmupEnabled` и пропускает аккаунты, ожидающие проверки регистрации.

## Восстановление нативного Codex

Expand Down
16 changes: 7 additions & 9 deletions docs-site/src/content/docs/tr/guides/codex-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,15 +417,13 @@ Arayüzü](/tr/guides/sub-agent-surface/) sayfasına bakın.

## Codex hesap ısınması

Codex hesap havuzuna bir ChatGPT hesabı eklendiğinde opencodex, Codex Responses
arka ucuna küçük bir akış isteği ile kalıcılıktan önce hesabı doğrular. İstek
gerçek bir Responses öğe dizisi kullanır (`input: [{ type: "message", ... }]`),
`response.completed` bekler ve varsayılan olarak `gpt-5.4-mini` kullanır. Bu
model HTTP 400 döndürürse `gpt-5.5` ile yeniden dener; ham yanıt gövdelerini
açığa çıkarmadan yapılandırılmış yukarı akış hata ayrıntıları ortaya çıkarılır.
Arka plan yeniden doğrulaması ayrıdır ve varsayılan olarak kapalıdır; yalnızca
Token Guardian etkinleştirildiğinde, `chatgpt` yenileme politikası `proactive`
olduğunda ve `tokenGuardian.codexWarmupEnabled` true olduğunda çalışır.
Hesap ekleme veya yeniden kimlik doğrulama, normalde kaydetmeden önce `response.completed` bekleyen küçük bir model isteğiyle doğrulanır. Varsayılan model `gpt-5.4-mini` olup HTTP 400 durumunda `gpt-5.5` denenir. Genel hatalar ham yanıt gövdesi yerine sabit hata kategorilerini içerir.

Yeni OAuth belirteciyle yapılan kota sorgusu 5 saatlik, haftalık veya aylık kotanın tükendiğini doğrularsa hesap model çağrısı olmadan kaydedilir ve **Doğrulama bekleniyor** gösterilir. Yeniden başlatma veya belirteç yenileme yönlendirmeyi açmaz. Kota geri geldiğinde kotaları yenileyin: kullanılabilir kapasite gösteren eksiksiz güncel veri küçük bir doğrulama isteğine izin verir. Yalnızca tamamlanan yanıt hesabı etkinleştirir. Hatalarda kısıtlama korunur. Pasif sorgulama bu isteği göndermez. İlk kayıtta bilinmeyen kota normal doğrulamayı gerektirir.

Pano olmadan `ocx account refresh openai` aynı doğrulamayı gerçekleştirir. `ocx account list openai --quota --refresh` yalnızca kullanımı okur ve bekleyen hesapları doğrulamaz. Açık doğrulama duraklatılmış bir hesapta tamamlanabilir; hesabı devam ettirmez veya seçmez. Model yetkilendirme hataları yeniden kimlik doğrulama gerektirir ve kota okuması başarılı olsa bile görünür kalır.

Arka plan doğrulaması ayrı ve varsayılan olarak kapalıdır. Token Guardian, `openai` için `proactive` yenileme ilkesi ve `tokenGuardian.codexWarmupEnabled` gerektirir; kayıt doğrulaması bekleyen hesapları atlar.

## Yerel Codex'i geri yükleme

Expand Down
Loading
Loading