1.9.1 — an old Codex on the machine no longer hides GPT-6 - #27
Merged
Merged
Conversation
`alc --codex claude` offered Sol, Terra and Luna and no GPT-6, on a machine where posting `gpt-6-astra` to chatgpt.com by hand streamed normally. The model worked; only alc's list of it was missing. **alc was asking the wrong party.** `ModelCatalog::refresh` shelled out to `codex debug models` and kept only the `TARGET_MODELS` entries that came back, then wrote that shorter list over the bundled catalog - which does carry `gpt-6-astra`. But `codex debug models` is not a fact about the account; it is the answer chatgpt.com gives the Codex CLI that asked. Every model carries a `minimal_client_version`, and `gpt-6-astra`'s is 0.153.0, so a machine on Codex 0.149.1 is simply not shown it. The command did not fail. It succeeded with a shorter list, and alc believed it. alc does not route one byte through the Codex CLI - its bridge posts straight to chatgpt.com - so a Codex that has not heard of a model is evidence about that install and never about the model. `bridge_codex_models` has said so since 1.5.0, in a comment calling a hard-coded list one release behind Codex "the entire reason this code exists". The refresh path had recreated that bug one layer up, with the installed CLI's version as the gate. **The catalog alc ships is now a floor.** Discovery may enrich a model's metadata and may add models alc has never heard of; it may never remove one. `apply_floor` runs on every read rather than only on the writing path, so a catalog already pruned onto a user's disk repairs itself on the next command - offline, with no login, and with no Codex upgrade. **And the refresh asks the party that serves the turns.** A new `src/bridge/models.rs` fetches the catalog from chatgpt.com with the credentials the bridge already holds, declaring the newer of alc's own `CODEX_CLIENT_VERSION_FLOOR` and the version stamped in `~/.codex/models_cache.json`, so the server's gate cannot hide a model behind an old local Codex. `codex debug models` is the fallback; both sources share one parser and one filter, and the floor goes back over whichever answered. Membership now comes from Codex's own `visibility` and `priority` rather than a slug allowlist, so `TARGET_MODELS` is gone. Three consequences nobody had reported yet, all of them the same pruned list: - `agents::claude::apply_bridge` hands the first catalog entry to Claude Code's `opus` alias. With GPT-6 pruned that was `gpt-5.6-sol`, so `opus` silently resolved a tier below what README.md documents. - `alc config` browses the catalog for a Codex profile's model, and the picker re-selected a default when the saved model was absent - so opening the TUI on a profile pinned to `gpt-6-astra` and confirming overwrote the pin. - The picker badged by slug, so it labelled the most capable model `[custom]` on the day it arrived. Staleness is keyed on the Codex release stamp read out of `models_cache.json` (a 4 KiB file read, no process spawn), so upgrading Codex re-syncs immediately instead of up to a day later. `alc models`, `--dry-run` and `alc doctor` now say which source answered, which entries alc had to supply itself, and why the account rung did not answer when it did not. Verified as an A/B against a build of the previous release, in one environment: a stub Codex reporting exactly the 0.149.1 list, no login, no network. Before, the picker handed Claude Code three models; after, four, with `gpt-6-astra` first. A cache pruned by the old build recovers GPT-6 on the next command with no Codex binary at all. A cache written by this build carries three new fields and is refused by 1.9.0 and older, which reject keys they do not know. A downgrade therefore falls back to the bundled catalog, which is complete. The weekly compatibility job's `TARGET_MODELS` grep - which would have failed on this commit - is replaced by a two-directional drift check, plus a direct comparison of the declared client version against the Codex it just installed from npm. That last one is the only staleness neither alc nor a list comparison can notice on its own: with no `codex login` in CI, both sides of the comparison come from the same `codex debug models`. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
One bug, and it was hiding a model you are paying for. On a machine whose Codex CLI was older than the newest model's `minimal_client_version`, alc offered `gpt-5.6-sol`, `gpt-5.6-terra` and `gpt-5.6-luna` and no GPT-6 - while the same `gpt-6-astra` posted to chatgpt.com by hand streamed normally. alc had been treating `codex debug models` as a fact about the account when it is an answer scoped to the version of the CLI that asked, and alc routes nothing through that CLI. Nothing that exists today changes its behaviour: the same `alc claude`, the same flags, and a `config.toml` written by 1.9.0 loads unchanged. That is a patch release. Two things to know when upgrading. The model cache gains three fields, and 1.9.0 and older reject keys they do not know. Downgrading therefore falls back to the catalog bundled in the binary, which is complete - the list is right either way, it just stops being fresh. `alc models --refresh` on the older build rewrites it. `alc models` and `alc doctor` print more than they did: which source answered, which entries alc had to put back itself, and why the account was not asked when it was not. A list that is complete only because alc insisted used to look identical to one the source agreed with, which is what turned a one-line cause into a long investigation. You do not have to upgrade Codex for this. The fix works offline, with no `codex login`, and with no `codex` on PATH at all. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
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.
alc --codex claudeoffered Sol, Terra and Luna and no GPT-6, on a machine where postinggpt-6-astrato chatgpt.com by hand streamed normally. The model worked; only alc's list of it was missing.The reason
ModelCatalog::refreshshelled out tocodex debug modelsand kept only theTARGET_MODELSentries that came back, then wrote that shorter list over the bundled catalog — which does carrygpt-6-astra.But
codex debug modelsis not a fact about the account. It is the answer chatgpt.com gives the Codex CLI that asked, and every model carries aminimal_client_version. Probed directly with the reporter's own credentials:client_versiongpt-6-astra0.149.1(installed)0.154.0minimal_client_version: 0.153.0The command did not fail. It succeeded with a shorter list, and alc believed it.
alc does not route one byte through the Codex CLI — its bridge posts straight to chatgpt.com — so a Codex that has not heard of a model is evidence about that install and never about the model. Confirmed decisively:
POST /backend-api/codex/responseswithmodel: "gpt-6-astra"returned HTTP 200 and streamed, with Codex still at 0.149.1 (a deliberately fake slug is refused by name, so the 200 is a real accept).bridge_codex_modelshas said this since 1.5.0, in a comment calling a hard-coded list one release behind Codex "the entire reason this code exists". The refresh path had recreated that bug one layer up, with the installed CLI's version as the gate.The fix
The catalog alc ships is now a floor. Discovery may enrich a model's metadata and may add models alc has never heard of; it may never remove one.
apply_floorruns on every read rather than only on the writing path, so a catalog already pruned onto a user's disk repairs itself on the next command — offline, with no login, and with no Codex upgrade.And the refresh asks the party that serves the turns. A new
src/bridge/models.rsfetches the catalog from chatgpt.com with the credentials the bridge already holds, declaring the newer of alc's ownCODEX_CLIENT_VERSION_FLOORand the version stamped in~/.codex/models_cache.json.codex debug modelsis the fallback; both sources share one parser and one filter, and the floor goes back over whichever answered. Membership comes from Codex's ownvisibilityandpriorityrather than a slug allowlist, soTARGET_MODELSis gone.Staleness is keyed on the Codex release stamp read out of
models_cache.json(a 4 KiB read, no process spawn), so upgrading Codex re-syncs immediately instead of up to a day later.Three things nobody had reported yet
All the same pruned list:
agents::claude::apply_bridgehands the first catalog entry to Claude Code'sopusalias. With GPT-6 pruned that wasgpt-5.6-sol, soopussilently resolved a tier below what README.md documents.alc configbrowses the catalog for a Codex profile's model, and the picker re-selected a default when the saved model was absent — so opening the TUI on a profile pinned togpt-6-astraand confirming overwrote the pin.[custom]on the day it arrived.Verification
A/B against a build of the previous release, in one environment: a stub Codex reporting exactly the 0.149.1 list, no login, no network.
alc modelsA cache pruned by the old build recovers GPT-6 on the next command with no
codexbinary at all. The live account path was exercised against a realcodex login.cargo fmt,cargo clippy --all-targets --all-features -- -D warningsand 597 tests are clean.alc doctor's new "written before the installed Codex release" row was corrected to fire only on a catalog that has actually been synced — the bundled fallback was written before every Codex release and warning about it on a fresh install was a plain falsehood.Compatibility
A cache written by this build carries three new fields and is refused by 1.9.0 and older, which reject keys they do not know. A downgrade therefore falls back to the bundled catalog, which is complete.
The weekly compatibility job's
TARGET_MODELSgrep — which would have failed on this commit — is replaced by a two-directional drift check, plus a direct comparison of the declared client version against the Codex it just installed from npm. That last one is the only staleness neither alc nor a list comparison can notice on its own: with nocodex loginin CI, both sides of the comparison come from the samecodex debug models.🤖 Generated with Claude Code