Repository navigation
[Bug][Windows] Stale persisted CLI 0.135.0 strips max/ultra while Codex Desktop runs 0.153.4 #4204
Description
Summary
On Windows, OpenCodex 2.50.0 can strip max and ultra from the shared Codex catalog using a stale standalone CLI, while the running Codex Desktop app uses a newer runtime that supports both. Starting/syncing OpenCodex can therefore remove options that the actual Desktop runtime accepts.
The installed sources for runtime.ts, catalog/bundled.ts, and catalog/effort.ts were verified byte-for-byte against the corresponding Git blobs at upstream HEAD 2d4d7a22381a2e497c2442902104619e25f937c7 during this investigation.
Client / Area / Environment
- Client: Codex App; area: Catalog / models, Windows runtime discovery.
- Windows 11 Pro, build 26200, x64.
- OpenCodex:
@bitkyc08/opencodex2.50.0. - Installed MSIX:
OpenAI.Codex26.903.9818.0; app.asar package version: 26.903.71938. - Persisted OpenCodex runtime:
%LOCALAPPDATA%\Programs\OpenAI\Codex\bin\codex.exe,codex-cli 0.135.0, sourceconfigured. - Running Desktop child runtime, verified through the process table:
%LOCALAPPDATA%\OpenAI\Codex\bin\<hash>\codex.exe,codex-cli 0.153.4. - Desktop parent executable:
%ProgramFiles%\WindowsApps\OpenAI.Codex_<version>_x64__<publisher>\app\ChatGPT.exe.
Reproduction And Fresh Proof
The existing codex-runtime-clamp.json records removedEfforts: ["max", "ultra"], runtime version 0.135.0, at 2026-09-10T12:01:09.525Z. Affected rows include gpt-6-astra, the GPT-5.6 family, and routed Anthropic models.
A non-mutating probe imported the installed OpenCodex functions supportedCodexReasoningEffortsFromObservedCatalog and clampCatalogModelsToObservedCodexSupport. For each real executable it ran --version and debug models --bundled, then applied the derived support set to the same in-memory GPT-6 Astra row. It did not run live sync or rewrite the user's catalog.
| Runtime | Derived support | Removed | Surviving |
|---|---|---|---|
| persisted CLI 0.135.0 | low, medium, high, xhigh | max, ultra | low, medium, high, xhigh |
| active Desktop CLI 0.153.4 | low, medium, high, xhigh, max, ultra | none | low, medium, high, xhigh, max, ultra |
Reproduction shape, with legacyCli and desktopCli set to the two real executable paths:
import { execFileSync } from "node:child_process";
import {
supportedCodexReasoningEffortsFromObservedCatalog,
clampCatalogModelsToObservedCodexSupport,
} from "./src/codex/catalog/effort";
for (const exe of [legacyCli, desktopCli]) {
const bundled = JSON.parse(execFileSync(exe, ["debug", "models", "--bundled"], { encoding: "utf8" }));
const rows = [{
slug: "gpt-6-astra",
default_reasoning_level: "medium",
supported_reasoning_levels: ["low", "medium", "high", "xhigh", "max", "ultra"].map(effort => ({ effort })),
}];
console.log(clampCatalogModelsToObservedCodexSupport(
rows, supportedCodexReasoningEffortsFromObservedCatalog(bundled),
));
}The user reports disappearing picker options after starting OpenCodex. The full UI/startup sequence was not replayed during this investigation, to avoid restarting an active Desktop session. At inspection time the on-disk catalog already contained max/ultra for Astra and Sol (last write 2026-09-10T12:55:35Z), while the earlier clamp diagnostic remained. Thus that diagnostic is historical evidence, not a claim that the current file still lacks the options. The controlled probe reproduces the destructive projection itself.
OpenCodex Source Trace
- runtime.ts:576: resolution orders environment, persisted configuration, shim, PATH, fallback. A still-runnable persisted CLI wins even when another runtime is newer. This resolver does not reconcile its choice with the running Desktop child.
resolveAndPersistCodexRuntimealso persists automatically discovered selections, soconfiguredalone does not establish that the user intentionally pinned an old runtime. - catalog/bundled.ts:241: bundled-catalog loading probes the single selected runtime and defaults
discoverAlternativesto false. - catalog/effort.ts:313: the effort vocabulary is derived from bundled bare native models.
- catalog/effort.ts:348: unsupported rungs are removed from rows; the list-level helper applies this across models.
- catalog/sync.ts:1945: sync invokes the clamp. cli/index.ts:488 calls the startup sync gate.
Why This Appears On Windows
The inspected Windows Desktop app and OpenCodex do not share executable discovery. Desktop runs a relocated, hash-addressed runtime under %LOCALAPPDATA%\OpenAI\Codex\bin, while OpenCodex retains a runnable older executable under %LOCALAPPDATA%\Programs\OpenAI\Codex\bin.
The installed Desktop app.asar was read directly, without modifying it. In .vite/build/main-CMBCj4XL.js:1, runtime resolution contains Windows-specific bundled-path and WindowsApps relocation handling (Zr, Qr, $r; relocateWindowsApps). This differs from OpenCodex's persisted/PATH resolver. The process table and both --version probes confirm that these paths actually differ on the affected machine.
This is a Windows packaging/runtime-discovery mismatch, not evidence that Windows cannot support these efforts. The clamp itself is platform-independent, and the same stale-runtime arrangement could affect other OSes. No macOS machine was tested, so strict Windows exclusivity is not established.
Separate Desktop Display Conditions
The installed Desktop renderer also filters efforts independently of the catalog:
webview/assets/app-initial-f094ef01c64d.js:1,M2i: intersects model effort rows withenabledReasoningEfforts, and removes Ultra whenincludeUltraReasoningEffortis false.- The same bundle defines
enabled-reasoning-efforts; its default list omitsmax. Ultra additionally has a feature gate in the model query (1186680773) and ashow-ultra-in-model-picker-sliderpreference defaulting to false. webview/assets/agent-settings-bfb770313a62.js:1: the available-efforts settings depend onhasModelSupportingMaxReasoningEffort/hasModelSupportingUltraReasoningEffort. A clamped model list can therefore remove the settings choices themselves.
These are source-observed conditions, not a claim about the affected user's current feature-gate values. They explain why restoring catalog bytes alone is insufficient to guarantee visible controls. No Windows-only max/ultra exclusion was established in these inspected filter functions.
Expected Behavior / Suggested Fix
For Desktop catalog synchronization, detect and report the consuming Desktop runtime and compare it with the selected OpenCodex CLI before destructively reducing the shared catalog. Distinguish explicit runtime pins from automatically persisted discovery. Account for Windows MSIX relocation and process identity; do not simply probe a protected WindowsApps path or silently replace an intentional pin.
Keep old-CLI compatibility handling where it is actually needed. Do not unconditionally enable arbitrary efforts: a newer Desktop and an older CLI may share the catalog, so runtime-specific projections or an explicit mismatch/recovery flow may be necessary. Diagnostics should separate runtime mismatch, catalog clamp, stale Desktop model cache, and renderer visibility preferences/gates.
Regression coverage should include a runnable legacy configured CLI beside a newer MSIX Desktop child, and verify that Desktop synchronization does not silently use the legacy ladder.
Related / Checks
- Related closed issue bug(catalog): clamp in b7ce5aad strips max/ultra from all models regardless of Codex binary version #297 covers the general bundled-ladder clamp; this report adds a reproduced Windows stale-runtime selection mismatch on 2.50.0.
- Related closed issue Windows: model picker stays stale after ocx sync --restart-codex until full desktop app restart #2292 covers stale Windows Desktop model caches. Cache staleness alone cannot explain the recorded clamp or the controlled probe, but remains a separate possible cause of current UI state.
- Existing issues and official configuration documentation were checked. Public documentation alone does not resolve this installed-build runtime mismatch.
- No credentials, account data, user-specific absolute paths, or full proprietary app sources are included.
Activity
Ingwannu commentedon Sep 10, 2026
The reported two-runtime probe is evidence of a consumer-identity mismatch, not evidence that Windows lacks max/ultra support. I am treating the saved clamp diagnostic as historical, as your report explicitly does—not claiming the currently materialized catalog is still clamped.
The paired failure in #4207 matters for the fix: remote-client downloads can be too permissive for the legacy CLI, whereas using that same legacy CLI's ladder globally can be too restrictive for Desktop. Keep the existing compatibility clamp; bind any local projection to its consumer rather than globally enabling efforts or silently replacing an intentional runtime pin. This needs mixed-runtime coverage and a distinction between catalog compatibility and Desktop renderer visibility. I have not probed proprietary app binaries or changed the live runtime/catalog in this review.
lidge-jun commentedon Sep 10, 2026
리뷰 · 우선순위 45 / 80
Windows 에서 OpenCodex 가 디스크에 남은 오래된 standalone Codex CLI(0.135.0)로 공유 카탈로그를 clamp 하면
max/ultra가 빠지는데, 실제로 돌아가는 Codex Desktop 은 더 새 런타임(0.153.4)이라 그 rung 을 지원합니다. 시작/동기화만으로 Desktop 이 쓸 수 있는 옵션이 사라집니다. “어떤 Codex consumer 기준으로 카탈로그를 깎을 것인가” 설계 문제입니다.현재
devHEAD6101140ff(2.51.0) 에서src/codex/catalog/sync.ts는clampCatalogModelsToCodexSupport(:1945) 로 모델을 깎고,:261)라 대체 런타임 탐색이 기본 꺼져 있습니다. runtime resolve 는 persisted CLI 를 선호합니다. Feasibility L4 에서는 이 이슈를 lane 작업에서 빼 두었고(design), #4207 은 클라이언트 투영/readiness 쪽 잘못된 lane 위험을 따로 적었습니다. product freeze tipsrc/codex/catalog/bundled.ts의 discoverAlternatives 기본값은 false(6d3ad12e3근처 맥락과도 맞습니다. 지금은 열어 두되 이번 round lane 에 넣지 않는 것이 맞습니다.라인 - src/codex/catalog/sync.ts ~:1945 — clampCatalogModelsToCodexSupport(catalog.models) 가 동기화 경로에서 항상 적용
라인 - src/codex/catalog/bundled.ts ~:261 — discoverAlternatives 기본 false; Desktop 자식 런타임 자동 채택 약함
경로/심볼 - persisted CLI vs Desktop child runtime — 낮은 CLI 로 clamp 하면 높은 Desktop 옵션이 공유 카탈로그에서 사라짐
경로/심볼 - #4207 — 관련하나 client catalog projection; 이 이슈는 Desktop consumer identity 설계
메인테이너의 판단이 필요한 지점
너의 추천
PARKED design 으로 열어 두세요. 이번 round lane 작업에 넣지 마세요. 필요할 때 consumer-specific catalog projection 설계 이슈를 따로 열고, 실행 가능한 쪽은 #4207 클라이언트 projection/readiness 를 먼저 하세요.
이 댓글은 grok-bot이 작성했습니다
fix(codex): emit max/ultra efforts unconditionally and expire stale c…
lidge-jun commentedon Sep 14, 2026
Fixed on
devby #4585, merged asdfa0e2f985e32df8263c87ad43d17ce0123a42be.codex-runtime.jsonnow recordsorigin: "pinned" | "discovered".resolveAndPersistCodexRuntimestamps its automatic selectionsdiscovered, and a record with no origin reads as discovered too, because auto-discovery is what wrote every one of them — which is exactly the point this report makes aboutconfigurednot establishing intent. An unpinned record now hands over to a strictly newer valid runtime and reports it assupersededDiscovered; a pin is never touched, equal versions stick, and an unknown version on either side is not treated as evidence of an upgrade.The report's source trace item 2 is also addressed: the bundled-catalog loader passes
discoverAlternatives: false, so the comparison could never have run where the bug bites. That fast path now still probes the bounded Codex App roots under%LOCALAPPDATA%\OpenAI\Codex\binwhen the persisted record is unpinned, while PATH-wide discovery stays off.Closing as resolved for the runtime-selection defect. Two things this does not claim: the renderer-side
enabledReasoningEfforts/show-ultra-in-model-picker-sliderconditions you documented are Desktop preferences outside this repository, and no live Windows Desktop reproduction was replayed — the fix is covered by regression tests that reconstruct the 0.135.0-beside-0.153.4 arrangement. Please reopen if the picker still loses rungs after a sync on the affected machine.lidge-jun commentedon Sep 14, 2026
Fixed on
devby dfa0e2f.The runtime record now carries whether its version was pinned by an operator or merely discovered, and an unpinned stale entry yields to a newer runtime that is actually installed. So a persisted 0.135.0 no longer strips max and ultra from the ladder while Codex Desktop is running 0.153.4. The resolver also gained an installed-runtime source — newest-first for the Windows App layout, and a POSIX fallback after PATH — plus a deferred memo that never publishes a half-probed result into the process cache.
Focused handover tests cover the Programs versus LOCALAPPDATA App layouts. An earlier head was red on one of those tests writing a Windows PATH into a Linux shard, which is worth mentioning only because it is the kind of test bug that looks like a product bug.
fix(codex): emit max/ultra efforts unconditionally and expire stale c…