Bug
Commit b7ce5aad ("fix(codex): clamp catalog reasoning efforts to installed binary's ladder") introduced clampCatalogModelsToCodexSupport, which runs as the last step of syncCatalogModels and strips any effort rung not found in the installed Codex binary's bundled catalog.
The problem: even on a current Codex binary, codexSupportedReasoningEfforts reads the binary's bundled native model entries (gpt-5.5, gpt-5.4, etc.), and those entries only list low/medium/high/xhigh. So max and ultra are never present in the derived supported set — and the clamp removes them from every model in the catalog, including routed models and the gpt-5.6 family.
Reproduction
- Run opencodex sync with any current Codex binary.
- Check
opencodex-catalog.json — every model's supported_reasoning_levels tops out at xhigh. max and ultra are gone.
- The Codex UI model picker caps effort selection at
xhigh for all models, including gpt-5.6-sol, anthropic/claude-sonnet-5, and all other routed providers.
Root cause
codexSupportedReasoningEfforts (src/codex/catalog.ts) scans only bare native slugs (no /) in the bundled catalog for known effort strings. Those slugs ship with supported_reasoning_levels that stop at xhigh in the binary's own bundled catalog — because the binary predates the max/ultra additions to its native ladder. So the derived supported set is {low, medium, high, xhigh}.
The ensureGpt56ReasoningLevels / ensureUltraReasoningLevel calls earlier in the sync correctly add max and ultra, but the clamp at line 2205 undoes all of it before the file is written.
Suggested fixes
Option A — seed the supported set from CODEX_REASONING_LEVELS (simplest)
Treat max and ultra as always-valid in codexSupportedReasoningEfforts regardless of what the bundled native entries happen to declare. They are defined in CODEX_REASONING_LEVELS and the request pipeline already handles wire-clamping to the model's real top rung via nativeEffortClamp/adapters — so letting them through the catalog clamp is safe.
// in codexSupportedReasoningEfforts, seed with the full ladder first
const efforts = new Set(CODEX_REASONING_LEVELS.map(l => l.effort));
// then union in whatever the binary confirms
Option B — version-gate the clamp
Only apply the clamp when the Codex binary is old enough to actually crash on unknown rungs. The commit message cites 0.133.0 as the problematic version. Read the binary version and skip the clamp for binaries >= the first version that accepts max/ultra.
Option C — run ensure-functions after the clamp
ensureGpt56ReasoningLevels / ensureUltraReasoningLevel are explicitly designed to restore max/ultra. Moving them to run after clampCatalogModelsToCodexSupport instead of before would let their intent survive.
Context
- Regression introduced:
b7ce5aad (landed 2026-07-22)
- Affects: every model in the synced catalog —
anthropic/claude-sonnet-5, gpt-5.6-sol, all routed providers, etc.
CODEX_REASONING_LEVELS in src/reasoning-effort.ts correctly defines all six rungs (low → ultra); the issue is purely in the clamp's source-set derivation from native binary entries that predate max/ultra.
Bug
Commit
b7ce5aad("fix(codex): clamp catalog reasoning efforts to installed binary's ladder") introducedclampCatalogModelsToCodexSupport, which runs as the last step ofsyncCatalogModelsand strips any effort rung not found in the installed Codex binary's bundled catalog.The problem: even on a current Codex binary,
codexSupportedReasoningEffortsreads the binary's bundled native model entries (gpt-5.5,gpt-5.4, etc.), and those entries only listlow/medium/high/xhigh. Somaxandultraare never present in the derivedsupportedset — and the clamp removes them from every model in the catalog, including routed models and the gpt-5.6 family.Reproduction
opencodex-catalog.json— every model'ssupported_reasoning_levelstops out atxhigh.maxandultraare gone.xhighfor all models, includinggpt-5.6-sol,anthropic/claude-sonnet-5, and all other routed providers.Root cause
codexSupportedReasoningEfforts(src/codex/catalog.ts) scans only bare native slugs (no/) in the bundled catalog for known effort strings. Those slugs ship withsupported_reasoning_levelsthat stop atxhighin the binary's own bundled catalog — because the binary predates themax/ultraadditions to its native ladder. So the derivedsupportedset is{low, medium, high, xhigh}.The
ensureGpt56ReasoningLevels/ensureUltraReasoningLevelcalls earlier in the sync correctly addmaxandultra, but the clamp at line 2205 undoes all of it before the file is written.Suggested fixes
Option A — seed the supported set from
CODEX_REASONING_LEVELS(simplest)Treat
maxandultraas always-valid incodexSupportedReasoningEffortsregardless of what the bundled native entries happen to declare. They are defined inCODEX_REASONING_LEVELSand the request pipeline already handles wire-clamping to the model's real top rung vianativeEffortClamp/adapters — so letting them through the catalog clamp is safe.Option B — version-gate the clamp
Only apply the clamp when the Codex binary is old enough to actually crash on unknown rungs. The commit message cites
0.133.0as the problematic version. Read the binary version and skip the clamp for binaries >= the first version that acceptsmax/ultra.Option C — run ensure-functions after the clamp
ensureGpt56ReasoningLevels/ensureUltraReasoningLevelare explicitly designed to restoremax/ultra. Moving them to run afterclampCatalogModelsToCodexSupportinstead of before would let their intent survive.Context
b7ce5aad(landed 2026-07-22)anthropic/claude-sonnet-5,gpt-5.6-sol, all routed providers, etc.CODEX_REASONING_LEVELSinsrc/reasoning-effort.tscorrectly defines all six rungs (low→ultra); the issue is purely in the clamp's source-set derivation from native binary entries that predatemax/ultra.