Skip to content

fix(models): stop discovery from deleting bundled catalog entries - #6502

Merged
Yeachan-Heo merged 1 commit into
devfrom
fix/available-catalog-keeps-bundled-models
Oct 8, 2026
Merged

Yeachan-Heo merged 1 commit into
devfrom
fix/available-catalog-keeps-bundled-models

Conversation

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Why

The ChatGPT $20 (Plus) plan was blocked from gpt-6.1-sol on gjc only. The cause was client-side: openai-codex is the one provider whose live catalog is an account entitlement list (GET chatgpt.com/backend-api/codex/models with the OAuth bearer + chatgpt-account-id). The registry treated that list as authoritative and deleted bundled entries absent from it in two places:

  • getAvailable() via #getAuthoritativeDiscoveredModelIds()
  • getAvailableForProfileActivation() (its sole purpose)

So when a Plus account's plan-scoped response omitted gpt-6.1-sol, gjc silently hid the bundled openai-codex/gpt-6.1-sol from /model, profile activation (codex-medium/codex-pro/astra-* are built on it), and preset availability — while other clients still offered it. The earlier client-side entitlement preflight was already removed (#5412); this discovery-driven hide was the leftover.

What changed

A discovered catalog now only enriches the bundled catalog (adds unknown ids, refreshes metadata) and never deletes a bundled model. Access decisions defer to the provider, which returns a typed error (openai-codex-responses.ts maps not supported when using codex with a chatgpt account).

  • getAvailable() keeps every bundled entry; discovery no longer removes.
  • Removed ModelRegistry.getAvailableForProfileActivation() and the profileModelIds/profileFresh/profileEndpoint evidence fields behind it.
  • Call sites (model-profile-activation.ts, model-selector.ts, sdk/session.ts, sdk/host/session-runtime.ts) now read getAvailable(); the now-redundant startup fallback filter in sdk/session.ts was dropped.

Tests

  • Rewrote the tests that encoded the removed "live catalog is authoritative" contract (model-registry, model-profile-activation, codex-profile-pinned-discovery, cli-args-mpreset, model-selector-profiles, model-preset-landing-redteam-qa, sdk-q27-model-profiles, sdk-model-selection) to assert bundled entries survive; deleted one test whose only premise was the two-catalog distinction.
  • bun --cwd=packages/coding-agent run check:types clean; biome clean.
  • bun test across the model/profile/discovery/autorouting selector suites: pass.
  • Not run: spawn-based broker/e2e suites hit EBADF posix_spawn in this environment (also fails on a pristine tree).

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-08T06:39:15.088510Z e86fcfe PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

A live discovery catalog reflects what a provider -- or the signed-in
ChatGPT plan -- currently lists, not what exists. Treating it as
authoritative deleted bundled entries the provider omitted, so a ChatGPT
Plus account lost selectable ids such as openai-codex/gpt-6.1-sol from
/model, profile activation, and preset availability even though the model
was bundled.

Discovery now only enriches the bundled catalog: it adds unknown ids and
refreshes metadata, and never removes a bundled model. Access decisions
defer to the provider, which returns a typed entitlement error.

Lore-id: available-catalog-keeps-bundled-models
Constraint: the bundled catalog is authoritative for catalog visibility
Rejected: keep hiding for plan-scoped providers only | no reliable signal separates plan entitlement from a deprecation, and codex was the only observed case
Directive: do not reintroduce discovery-driven deletion of bundled models
Confidence: high
Scope-risk: wide
Reversibility: easy
Tested: model-registry, model-profile-activation, codex-profile-pinned-discovery, cli-args-mpreset, model-selector-profiles, sdk-q27-model-profiles, sdk-model-selection, model-registry-*, discovery and autorouting suites (bun test)
Not-tested: spawn-based broker/e2e suites (EBADF posix_spawn in this environment)
@Yeachan-Heo
Yeachan-Heo force-pushed the fix/available-catalog-keeps-bundled-models branch from e86fcfe to 1a76ad5 Compare October 8, 2026 06:36

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e86fcfe3f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
return !bundledIds.has(model.id) || liveIds.has(model.id);
});
this.#availableModelsCache = this.#models.filter(model => this.#isModelAvailable(model, disabledProviders));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep filtering stale dynamically discovered model IDs

When a descriptor-backed provider is refreshed under a different account or after its live catalog changes, #mergeDiscoveredModels() only merges the new snapshot into #models; it does not remove previously discovered IDs. The removed authoritative filter used profileModelIds to hide such non-bundled IDs once the current catalog omitted them, but this unconditional filter now exposes them indefinitely. For example, a paid Codex-only model remains selectable after switching to a free account, and a model unloaded from vLLM remains in /model and can be auto-selected. Preserve bundled/static entries as intended, but continue filtering or evicting dynamically learned IDs that are absent from current discovery evidence.

Useful? React with 👍 / 👎.

@probepark probepark left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (head 1a76ad5, gajae-reviewer on behalf of probepark)

Blocking findings:

  1. P1 — packages/coding-agent/src/config/model-registry.ts:5674: Preserve bundled models without retaining obsolete discovery-only models. #mergeDiscoveredModels() merges into the previous catalog (lines 3491–3506). #mergeResolvedModels() never removes absent IDs (lines 2423–2449). The replacement filter checks only provider authentication and disabled status (lines 5221–5227). After discovery returns a previously unknown ID, a subsequent successful response omitting that ID leaves it selectable indefinitely. This also affects profile activation and startup fallback. Retain bundled and explicit custom entries, but filter or evict discovery-only IDs absent from current evidence. Add a two-refresh regression: discover an unknown ID, omit it on refresh, then assert it disappears while an omitted bundled ID survives. This independently confirms the earlier Codex finding on the current head.
  2. CI blocker, cause unclassified — packages/coding-agent/src/sdk/host/session-runtime.test.ts:5392,8610: The exact-head CI job fails two accepted-control regressions. One never reaches terminal reconciliation; the other returns a result that does not match the expected settlement state. Job: https://github.com/Yeachan-Heo/gajae-code/actions/runs/37738534564/job/113188668410 (225 pass, 2 fail, exit 1). The reviewed dev failure run, https://github.com/Yeachan-Heo/gajae-code/actions/runs/37733646186, contains other failures; it does not establish these two as base failures. Fix the failures, or provide matching base-run evidence before approval.

CI: Coding-agent check, registry tests, profile activation tests, and selector integration tests passed. Other affected checks were still running when inspected. No local builds or tests were run in this pod.
Scope: +70 / -316, 14 files — model registry, profile activation, selector, SDK startup/query surface, eight test files, and a release-note fragment. All five OCR-selected source diffs were reviewed.
Conventions: Release-note fragment present, as required by AGENTS.md:202; no generated files changed; no labels.
ocr: blocking 1 / nit 0

Spec axis: The PR's bundled-catalog visibility change reaches all five source call sites. The discovery-only retention regression above is outside the stated bundled-preservation goal.
Checked and clean: Provider-authentication/disabled-provider filtering remains; profile materialization and selector/query call sites use the same available catalog. Test expectation changes have an explicit rationale in the PR description.
Not assessed: Live provider entitlement errors and spawn-based end-to-end behavior were not exercised locally. CI failure provenance remains unclassified.

Blocking: 2 total (1 source defect, 1 unclassified CI failure).
Verdict: gajae.pr-review-verdict.v1 needs-human sha256:b8c1e2b9ed42034eb47b48aa39cc30075afc312bacf388e61669fc4baff09bec reviewer:critic reviewer-id:gajae-reviewer evidence:stale-discovery-only-ids-remain-selectable;session-runtime-ci-failure-unclassified

PR body verdict line count=0, not updated. Body verdict line is owned by absent; not edited. Suggested verdict line: gajae.pr-review-verdict.v1 needs-human sha256:b8c1e2b9ed42034eb47b48aa39cc30075afc312bacf388e61669fc4baff09bec reviewer:critic reviewer-id:gajae-reviewer evidence:stale-discovery-only-ids-remain-selectable;session-runtime-ci-failure-unclassified

@Yeachan-Heo
Yeachan-Heo merged commit 7acc11d into dev Oct 8, 2026
54 of 56 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants