Repository navigation
fix(server): recover Codex child models after metadata lookup fails - #22830
Draft
juliusmarminge wants to merge 8 commits into
Draft
juliusmarminge wants to merge 8 commits into
juliusmarminge wants to merge 8 commits into
Conversation
Contributor
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts # apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.ts # knip.jsonc
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Fixes #15250.
Change
A native Codex child's first metadata lookup can race an empty rollout. If both read and fallback resume fail, its Lineage model stays “Not reported” even after metadata becomes available. Retry the lookup up to six times with bounded backoff, stopping when the child's actual selection is known or its lifecycle no longer permits recovery. Newer settings/reroute metadata wins over an older lookup; the parent model is never substituted.
Scope and approval
Fixes #15250
GitCafe: https://git.cafe/pingdotgg/t3code/issues/15250
Triaged bug via the automated issue flow.
Evidence index includes correlated native IDs, wire/projection timestamps, exact same-parent task_status errors, card/UI text, completion records, rebuild instructions, temporary fault script/patch, rendering environment and clean restoration proof. Server-only exception: scoped tests and real runtime transcripts replace a pixel matrix. Runtime injection is a published temporary artifact, not committed product code or a committed database seed; the deterministic replay fixture is committed.
Validation: scoped report. Focused adapter suite: 76 passed (prior auditor's run). Scoped formatting passed; lint exited 0 with two unused-variable warnings; server-only typecheck exited 0 with Effect suggestions. Two independent reviews, Codex and Claude, reported MERGE (lead-supplied reports; not rerun by the evidence assembler). At the final lead check, CI reported 21 successful, 2 pending (Collect PR targets and Prepare PR size config), and 0 failing checks. Final proof audit: SUFFICIENT; its timestamp wording finding is corrected in the evidence index.
Verification
Reproduced against the actual base 1688f96568, then verified at 4dd9adf5c0, using Codex 0.163.0 and a real isolated dev server. Parent Sol/low spawned native Luna/high children. Before, a natural empty-rollout read error and a temporarily rejected successful resume result left the child model null through completion. After, attempt 1 hit natural empty-rollout/list_turns errors; attempt 2's successful wire results were rejected by the temporary fault, which then released; attempt 3 read succeeded at 11:35:43.716 UTC. The persisted selection corrected to Luna/high by 43.778 and remained through completion at 11:38:48.129. Healthy control also retained Luna/high through completion. No settings/reroute notification supplied the correction.
Rendering: T3 preview Chromium/Linux, 1280×800 CSS viewport, light, measured DPR 2, no emulation, default font scaling. The after image shows the running recovered card; completion retention is established by the persisted snapshot and final UI text. Across captures, isolated history/titles/timers changed, displayed diff counts included temporary instrumentation, and an update notification was dismissed. Product changes are limited to the server adapter and its tests; existing client renderers and contracts are unchanged.
P/I race and interruption behavior are covered by deterministic replay. B/V retry bounds and invalid-result variants are code-inspected with executable coverage limits disclosed in the index. Native task_status still accepts app-owned tasks only; the same-parent native probe returns task_not_found. Unverified: Claude children, mobile card, remote/relay/tunnel and multi-environment behavior. No pixel-diff or completed-card screenshot claim.
Model: GPT-6.1-Sol. Harness: Codex in T3 Code.
Evidence
Both sides ran a real
t3 startserver with an isolated--base-dir, the same driver, and a STUBBED Codex app-server (real Codex was rate-limited). Before is the merge-base 8d3b061121; after is aa57d7d3ba. The stub replaces Codex throughproviderInstances.codex.config.binaryPath, and itsthread/readandthread/resumereplies follow a fixture. The client value is the subagentmodel/modelSelectioninorchestration_v2_projection_subagents.payload_json, read read-only. The client shows "Not reported" when it isnull.apps/server/scripts/evidence/issue-15250/(run.mjs,stub-codex-app-server.mjs,README.md).In the table, R is
thread/readand S isthread/resume. Times are seconds after the child registered.8d3b061121aa57d7d3bagpt-6-luna→gpt-6-lunanull(Not reported) →gpt-6-lunanull→null(stable, no retry storm)null→nullnull(interrupted) at bothmodel/reroutedarrives mid-retrygpt-5.6-sol, one update, at bothgpt-6-lunaat bothEnvironment: fs-24, Linux 6.1.102 x86_64, node v26.12.1. Ports 127.0.0.1:43832 (before) and 43833 (after). Stubbed Codex app-server, isolated homes under
/tmp.What else changed between before and after:
git diff --stat 8d3b061121 f3117126dclistsCodexAdapterV2.ts,CodexAdapterV2.test.ts, the three evidence files and one line inknip.jsonc. Nothing else.Verification log
results.jsonand checked both diff claims. It rebuilt R2a and R3 from the committedrun.mjson fresh checkouts at8d3b061121and89d72c1ff2, and both matched within about 20 ms: R2a went from 1R 1Snullto 2R 1Sgpt-6-luna, and R3 went from 1R 1S to 6R 6S. Caveat: the raw logs from the first pass record checkout paths, not SHAs. The rebuild is what ties those results to SHAs.vp test run apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.tspassed 78/78 ataa57d7d3ba.vp lintandvp fmt --checkon the changed files show no errors, only two existing unused-variable warnings inCodexAdapterV2.ts.knip --include files,dependenciesand theapps/serverexports pass both exit 0 atf3117126dc.89d72c1ff2, 25 checks passed and 2 failed:LintandCheck. The local knip run flagged the two evidence scripts as unused files;f3117126dcadds them as knip entries and knip now passes locally. CI is pending onf3117126dc.