Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
c67e36a
docs: lock combo recovery composition and cancellation guards
invalid-email-address Sep 6, 2026
1b30050
docs: include combo recovery guide consistency
invalid-email-address Sep 6, 2026
fd5e90f
fix(combos): recover unavailable native tasks without losing cancella…
invalid-email-address Sep 6, 2026
0c97836
test(combos): preserve canonical and third-party quota selection
invalid-email-address Sep 6, 2026
cd054d9
test(combos): cover unavailable native recovery and abort at both sites
invalid-email-address Sep 6, 2026
f5c88be
docs: record mixed combo recovery verification scope
invalid-email-address Sep 6, 2026
4abd205
Merge branch 'codex/release-244-opaque-recovery-07c0' into codex/rele…
invalid-email-address Sep 6, 2026
e1f5a5b
Merge branch 'codex/release-244-opaque-recovery-07c0' into codex/rele…
invalid-email-address Sep 6, 2026
b668dc8
docs: finalize verified combo recovery composition record
invalid-email-address Sep 6, 2026
1697a77
Merge branch 'codex/release-244-shutdown-fixture-07c0' into codex/rel…
invalid-email-address Sep 6, 2026
da09d40
docs: lock Grok tracker boundary and asynchronous CI delivery
invalid-email-address Sep 6, 2026
3f30084
fix(responses): reconstruct sparse Grok terminal snapshots from valid…
invalid-email-address Sep 6, 2026
b0d0672
test(responses): cover Grok terminal repair and raw call identity guards
invalid-email-address Sep 6, 2026
c745026
fix(combos): recover stored Pool failures without reopening account hops
invalid-email-address Sep 6, 2026
8de1269
test(combos): cover stored Pool recovery budget and cancellation
invalid-email-address Sep 6, 2026
eaa005a
Merge branch 'codex/release-244-combo-recovery-07c0' into codex/relea…
invalid-email-address Sep 6, 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
9 changes: 9 additions & 0 deletions devlog/_plan/260906_release_244_followups/000_plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,12 @@ One work-phase is one PABCD cycle. Publish short dependency stacks; use merge co
## Evidence boundaries

#3735/#3734 are public current-SHA reports; independently inspect code, author local-pass statements remain reports. Kiro proof is recorded-log shape plus synthetic CI tests, never a live quota-consuming request. #3644 has a network A/B report and landed diagnostic #3693; do not claim a Windows runtime reproduction from mocked tests. Detailed private logs are never committed.

## Owner steering: asynchronous CI

From the Grok unit onward, implementation/review and PR publication proceed
without waiting for hosted CI. Each cycle records exact-head CI submission; its
runtime acceptance criterion stays open under release convergence. CI failures
are handled asynchronously and stacks cascade after repairs. Bottom-up merges
and release publication still require successful checks on their final heads.
This changes scheduling only; no test, platform or release criterion is removed.
35 changes: 35 additions & 0 deletions devlog/_plan/260906_release_244_followups/050_combo_recovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,38 @@ Before: a merely configured native target suppresses recovery even when not usab
Remote tests cover native disabled/cooldown, native 401 exhaustion, canonical summary exhausted with eligible account, noncanonical quota veto, caller eligibility, cooldown waiting, all targets unavailable skips recovery, recovery failure never dispatches plaintext/ciphertext, aborted recovery at both sites returns cancellation, no retry after client output. Preserve 32-inflight and no-persist safeguards where owned by recovery helper.
CodeRabbit HTTPS-only suggestion is assessed against existing http provider policy: do not invent combo-only URL permission changes. Record evidence-backed rebuttal or a narrowly necessary fix during P/security audit. This carry does not change provider URL policy or credentials. Exact-head CI + independent security review required; no live Kiro or local suites.


## Current composition and cancellation amendment

The lower stack PR #3753 is merged as b9f2acc82 from cd6d4d346 (full
CI34020474748 and independent security/final reviews passed). Source #3706 remains c311e9598; its source-only
patch applies cleanly to this foundation. Preserve every opaque preflight and
client-reader repair; only handleComboResponses changes in core.

At the initial unreadable-task recovery site, a false helper result returns 499
when the caller signal is aborted, otherwise the existing unreadable-task 400.
At native exhaustion, recheck caller cancellation after routed-target waiting and
recovery, before adopting the last native failure. A successful helper remains
one-shot; normal failed recovery preserves the prior failure and never dispatches
unreadable ciphertext or persists recovered plaintext. Add deterministic abort
fixtures at both recovery sites using the existing fake upstream boundary.

Canonical forward providers defer account/model quota admission to the existing
native selector; caller eligibility, target cooldowns and attempted exclusions
still apply. Noncanonical hosts and third-party cached quota remain filtered.

No combo-only HTTPS restriction is added: this routes recovered content through
the same operator-configured provider transport as the already-supported all-routed
recovery case. Recovery credentials still go only to its existing fixed backend,
and explicit opt-in, loopback/caller guards and no-persist policy remain unchanged.
Introducing a new URL policy only for this combo branch would contradict the
existing configured-provider contract without evidence of a distinct boundary.

Also update the English guides/sub-agent-surface.md paragraph that currently says
combo routing is unchanged and native-only. The configuration pages alone would
leave that guide contradicting the newly reachable opt-in routed recovery path.

The parent now also preserves native preflight read resets/cancellation and
tee/eager failed terminal accounting, including semantic streamAborted parity.
The combo delta remains unchanged through that cascade; a fresh composition
review confirmed the same patch and the complete child runtime passed CI34020475627.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Mixed combo recovery implementation

The carry changes only combo selection in core and provider usability in the
combo resolver. A selectable native target keeps priority. If native candidates
are unavailable or exhausted, an available routed target may be selected after
one explicitly enabled encrypted-task recovery. Existing caller admission,
fixed recovery backend, attempt exclusions and plaintext no-persistence remain.

Canonical native quota belongs to account/model selection; cached summaries keep
filtering third-party and noncanonical providers. Both initial and late recovery
failures recheck caller cancellation, including cancellation during target waiting,
before returning an unreadable-task or prior native error.

Original contributor tests cover disabled/cooldown/native-401, failed recovery,
unavailable targets, canonical/noncanonical quota and eligibility. The new paired
abort fixture waits for the recovery fetch to start, then cancels its actual signal;
499/client_cancelled, no routed call and empty cache/continuation stores are asserted.
No local suites/typecheck/build or live Kiro request are used. Hosted exact-head CI
and independent source/security/final reviews supply integration evidence.

## Verified composition

- Source fd5e90f1b and regressions cd054d926 passed independent source/security
and final reviews. The initial full hosted run was CI34019564577.
- Parent #3753 required a separate repair cycle for preflight read failures and
tee EOF account outcomes. That repair is merged on dev as b9f2acc82; source
cd6d4d346 passed CI34020474748 and its two review threads are resolved.
- The resulting child e1f5a5b8d passed full CI34020475627. Stable patch ID
8b62ad9ebb675f63a6dd4933e22663b48e1d95f2 matches the original combo delta,
and a fresh composition review passed. This documentation closeout changes
no runtime or tests. Final PR-head checks remain visible on #3754.
- #3706 remains open until #3754 actually merges. Closure requires a fresh
merged-state and dev-ancestry check; a successful merge command is not assumed.

No local suite, typecheck, build or live Kiro call was used for these results.
42 changes: 41 additions & 1 deletion devlog/_plan/260906_release_244_followups/060_grok_terminal.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Depends on composed relay stack; C3. Carry #3388 645180ceaf123c954ab5306969cf82d
## Exact diff map

- MODIFY src/server/responses-snapshot-repair.ts: add createGrokResponsesSparseTerminalBlockRewrite and narrow item validators; if file exceeds existing size significantly, extract separate src/server/grok-responses-snapshot-repair.ts for Grok-only tracker while retaining existing exports. Record extraction in P before B.
- MODIFY src/server/responses/core.ts existing rewrite list: enable only logCtx.surface === grok and insert Grok terminal tracker immediately before createResponsesSnapshotBlockRewrite. Preserve current order custom-tool restore -> Copilot -> Grok -> provider snapshot -> field backfill -> function repair -> undeclared-tool guard.
- MODIFY src/server/responses/core.ts existing rewrite list: enable only logCtx.surface === grok and insert Grok terminal tracker immediately before createResponsesSnapshotBlockRewrite. Preserve current order custom-tool restore -> tool-search restore -> Copilot -> Grok -> provider snapshot -> field backfill -> function repair -> undeclared-tool guard.
- MODIFY tests/responses/responses-snapshot-repair.test.ts and responses-snapshot-repair-server.test.ts; preserve existing sparse JSON function completion inference tests.
- MODIFY structure/04_transports-and-sidecars.md and public adapters reference with client-specific boundary.

Expand All @@ -15,3 +15,43 @@ Before: Grok Build renders deltas but sees empty completed.response.output and m

Remote unit and server fixtures: Grok positive text/function/custom output, missing vs explicit-empty terminal, ordinary-client byte preservation, explicit provider snapshot + Grok coexistence, invalid item shapes/indexes/ids, duplicate/gap/bound checks, failed/incomplete terminal cannot become completed, raw done order retained. CI typecheck/privacy/runtime gates on final head; contributor reported old baseline failures are not accepted without current evidence. This is Grok Build terminal compatibility, not Cursor/Grok semantic no-progress issue #3506.


## Current composition and module decision

Base: verified combo #3754 at 1697a7748. Source #3388 remains 645180cea.
The existing snapshot module is 621 lines; the source adds 327 lines for a
separate client policy. Keep the provider policy stable and put the Grok tracker
in new src/server/grok-responses-snapshot-repair.ts. Extract only the existing
isPlainObject, jsonBlock and RetainedOutputItem into a leaf
src/server/responses-snapshot-codec.ts so both trackers share their wire codec.
Core and Grok tests import the new tracker directly; existing public snapshot
exports stay unchanged and no convenience re-export or circular edge is added.
The tracker imports the existing relay retention limits, SSE block type/parser
and budget type. The codec imports nothing. This local functional dependency
replaces duplication; the stream order is an explicit temporal dependency.

Keeping everything in the old file would mix two different opt-in contracts and
push it near 950 lines. A broad provider-tracker refactor is also rejected. The
old module remains above the default size limit but shrinks without behavioral
changes; the new tracker stays below 400 lines. Its stateful closure remains one
cohesive retention owner. The source/test carry exceeds 500 lines because its
regression matrix must land with the behavior, not as an untested upper layer.

Keep the source Grok describe as one top-level block before the existing provider
snapshot describe; do not split the latter. Preserve the current server file's
f121348a9 sparse JSON/function-repair EOF fixture. Add missing/empty/whitespace
call_id negatives for function/custom calls, a valid custom call alongside a
visible message, and a same-provider absent-marker/marker=1 server control.

x-opencodex-grok: 1 is a client-selected compatibility opt-in, not authenticated
client identity. Do not add authentication or infer privileges from it. Public
adapters documentation must describe that boundary. No live Grok or Kiro probe
is required for this synthetic protocol repair.

## Asynchronous verification

The user directed CI to run after implementation asynchronously. Close this
implementation cycle after source audit, attributed PR and exact-head CI queue
verification, then proceed to the next unit. c-grok-terminal remains open until
hosted runtime CI succeeds; release convergence owns that unchanged criterion.
Do not merge or publish an unverified head. No local suites/typecheck/build.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Pour un tour enfant créé, l’ordre de repli est le suivant :

Les chaînes de repli propres à un rôle doivent résider dans la configuration d’opencodex. L’ajout de `model_fallback` dans `$CODEX_HOME/agents/*.toml` amène Codex 0.146+ à rejeter le fichier de rôle entier à cause de ce champ inconnu, puis à ignorer le rôle (#1190). Une ancienne ligne `model_fallback` dans le fichier TOML reste lue par souci de rétrocompatibilité, mais `ocx doctor` la signale.

opencodex ignore les candidats désactivés, non routables, en mauvais état, en période de temporisation ou ayant atteint le seuil de quota. L’instantané de disponibilité est mis en cache pendant `subagentModelFallbackPollMs`. Les tâches enfants chiffrées limitent la chaîne aux cibles ChatGPT natives canoniques et aux routes Responses directes avec authentification par clé explicitement approuvées via `allowEncryptedV2AgentTasks: true` ; si aucune ne peut consommer la charge chiffrée, la requête échoue au lieu d’envoyer un texte chiffré illisible à une autre destination. Les combos restent limités aux cibles natives canoniques.
opencodex ignore les candidats désactivés, non routables, en mauvais état, en période de temporisation ou ayant atteint le seuil de quota. L’instantané de disponibilité est mis en cache pendant `subagentModelFallbackPollMs`. Les tâches enfants chiffrées limitent la chaîne aux cibles ChatGPT natives canoniques et aux routes Responses directes avec authentification par clé explicitement approuvées via `allowEncryptedV2AgentTasks: true` ; si aucune ne peut consommer la charge chiffrée, la requête échoue au lieu d’envoyer un texte chiffré illisible à une autre destination. Un combo essaie d’abord une cible native canonique disponible ; si aucune n’est sélectionnable et que `agentTaskRecovery` est activé, un `NEW_TASK` chiffré est récupéré une fois avant l’envoi routé du combo.

```json
{
Expand Down Expand Up @@ -111,7 +111,7 @@ Ce mécanisme ne protège pas contre un autre processus exécuté sous le même

N’activez cette option que si la requête authentifiée supplémentaire, la consommation de quota, la présence de texte en clair dans le processus et la dépendance à un service privé sont acceptables. Dans le cas contraire, privilégiez un enfant ChatGPT natif ou une délégation hétérogène v1.

Ce mécanisme de récupération s’applique aux enfants routés directement. Au maximum 32 requêtes de récupération peuvent être actives simultanément ; toute absence supplémentaire dans le cache échoue de manière sûre. Pour les tâches chiffrées, le routage par combinaison conserve son filtre existant limité aux cibles natives et n’utilise pas la récupération.
Ce mécanisme de récupération s’applique aux enfants routés directement et aux `NEW_TASK` chiffrés d’un combo. Au maximum 32 requêtes de récupération peuvent être actives simultanément ; toute absence supplémentaire dans le cache échoue de manière sûre. Un combo disposant d’une cible native canonique disponible continue d’envoyer directement le texte chiffré ; la récupération ne s’exécute que si aucune cible native n’est sélectionnable. Un échec de récupération, l’épuisement des cibles ou leur indisponibilité conserve l’échec fermé sans transmettre le texte chiffré à un fournisseur routé.

## Plafonds d’effort

Expand Down
7 changes: 5 additions & 2 deletions docs-site/src/content/docs/guides/sub-agent-surface.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,11 @@ byte-for-byte fidelity is not guaranteed. It rejects generic/API-key proxy calle
`unreadable_encrypted_agent_task` on any failure. See
[Agent configuration: Encrypted v2 task recovery](/reference/configuration/agents/#encrypted-v2-task-recovery)
for the full trust boundary and configuration.
Combo routing remains unchanged and continues to consider only canonical native ChatGPT targets for
encrypted tasks.
Combo routing prefers a selectable canonical native ChatGPT target for encrypted tasks. If none
is usable, or native authorization attempts are exhausted, an explicitly enabled recovery may
make the task readable for one available routed target. All recovery trust and no-persistence
guards above still apply; a configured but disabled or cooling native target does not block this
fallback, and cancellation never becomes an unreadable-task error.

## Rejected encrypted history

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ V1 ガイダンスは、`max` または `ultra` でのみプロアクティブ
拒否し、ロールをスキップします(#1190)。TOML 内のレガシー `model_fallback` 行は後方互換性の
ために引き続き読み取られますが、`ocx doctor` がそれをフラグ付けします。

opencodex は、無効、ルーティング不能、異常、冷却期間、またはクォータしきい値の候補をスキップします。可用性スナップショットは `subagentModelFallbackPollMs` に対してキャッシュされます。暗号化された子タスクでは、チェーンを正規のネイティブ ChatGPT ターゲットと、`allowEncryptedV2AgentTasks: true` で明示的に信頼された直接のキー認証 Responses ルートに制限します。暗号化されたペイロードを処理できる対象がない場合、読み取り不可能な暗号文を別の場所へ送らず、リクエストは失敗します。コンボは引き続き正規のネイティブ対象だけを使用します
opencodex は、無効、ルーティング不能、異常、冷却期間、またはクォータしきい値の候補をスキップします。可用性スナップショットは `subagentModelFallbackPollMs` に対してキャッシュされます。暗号化された子タスクでは、チェーンを正規のネイティブ ChatGPT ターゲットと、`allowEncryptedV2AgentTasks: true` で明示的に信頼された直接のキー認証 Responses ルートに制限します。暗号化されたペイロードを処理できる対象がない場合、読み取り不可能な暗号文を別の場所へ送らず、リクエストは失敗します。コンボはまず利用可能な正規ネイティブ対象を試し、選択できるネイティブ対象がなく `agentTaskRecovery` が有効な場合、暗号化された `NEW_TASK` をルーティングされたコンボ送信の前に一度だけ復旧します

```json
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ V1 안내는 `max` 또는 `ultra`에서만 선제 텍스트로 제공됩니다.
거부하고 역할을 건너뜁니다 (#1190). TOML의 기존 `model_fallback` 줄은 하위 호환성을 위해
계속 읽히지만 `ocx doctor`가 이를 표시합니다.

opencodex는 비활성, 라우팅 불가, 비정상, 쿨다운 중, 또는 할당량 임계값에 걸린 후보를 건너뜁니다. 사용 가능성 스냅샷은 `subagentModelFallbackPollMs` 동안 캐시됩니다. 암호화된 하위 작업은 정규 네이티브 ChatGPT 대상과 `allowEncryptedV2AgentTasks: true`로 명시적으로 신뢰한 직접 키 인증 Responses 라우트만 후보로 사용합니다. 암호화된 페이로드를 처리할 수 있는 대상이 없으면 읽을 수 없는 암호문을 다른 곳으로 보내지 않고 요청이 실패합니다. 콤보는 계속 정규 네이티브 대상만 사용합니다.
opencodex는 비활성, 라우팅 불가, 비정상, 쿨다운 중, 또는 할당량 임계값에 걸린 후보를 건너뜁니다. 사용 가능성 스냅샷은 `subagentModelFallbackPollMs` 동안 캐시됩니다. 암호화된 하위 작업은 정규 네이티브 ChatGPT 대상과 `allowEncryptedV2AgentTasks: true`로 명시적으로 신뢰한 직접 키 인증 Responses 라우트만 후보로 사용합니다. 암호화된 페이로드를 처리할 수 있는 대상이 없으면 읽을 수 없는 암호문을 다른 곳으로 보내지 않고 요청이 실패합니다. 콤보는 먼저 사용 가능한 정규 네이티브 대상을 시도하고, 선택 가능한 네이티브 대상이 없으며 `agentTaskRecovery`가 켜져 있으면 암호화된 `NEW_TASK`를 라우팅된 콤보 전송 전에 한 번 복구합니다.

```json
{
Expand Down
15 changes: 15 additions & 0 deletions docs-site/src/content/docs/reference/adapters.md
Original file line number Diff line number Diff line change
Expand Up @@ -422,3 +422,18 @@ Shared helpers used by the vision-aware adapters:
Anthropic/Google image blocks.
- `contentPartsToText(content)` — flatten content parts to text for text-only tool messages
(an undescribed image becomes a short `[image]` marker, never a token-exploding base64 blob).

## Grok Build terminal snapshots

Requests marked with `x-opencodex-grok: 1` opt into a narrow Responses terminal
repair. If `response.completed.response.output` is missing or empty, opencodex
can reconstruct it from real, uniquely indexed, contiguous `output_item.done`
items whose raw fields satisfy the supported shapes. Deltas alone do not create
output. Malformed, contradictory, duplicated, gapped or oversized evidence keeps
the empty terminal unchanged; failed and incomplete responses never become success.

The marker is a client-selected compatibility option, not authenticated identity
or a permission grant. Unmarked clients retain their existing behavior. This
repair runs before the separate provider `responsesSnapshotRepair` option and
does not enable that broader lifecycle repair. Existing tool-search, custom-tool,
function-completion and undeclared-tool handling keep their established order.
Loading
Loading