Client or integration
OpenCodex dashboard
Area
Catalog / models
Summary
On OpenCodex 2.36.0, the dashboard/management model list loses the entitled native OpenAI GPT-5.6 rows when the five-minute account-model roster cache expires.
Immediately after a successful entitlement discovery, GET /api/models contains seven native openai rows:
gpt-5.5
gpt-5.4
gpt-5.4-mini
gpt-5.3-codex-spark
gpt-5.6-sol
gpt-5.6-terra
gpt-5.6-luna
After five minutes, with no account or configuration change, the same endpoint returns only the first four. Calling GET /v1/models immediately restores all seven rows in /api/models for another five minutes.
The account is entitled to the three GPT-5.6 models: /v1/models returns them, the generated Codex catalog contains them with visibility: "list", and they remain usable. This appears to be a management/catalog projection bug rather than a loss of model access.
Expected: management readers should trigger or receive a current entitlement discovery before projecting account-gated native rows. The dashboard and exports should not silently change from 7 to 4 solely because the in-memory evidence cache expired.
Reproduction
-
Start OpenCodex 2.36.0 with an authenticated ChatGPT/Codex account entitled to gpt-5.6-sol, gpt-5.6-terra, and gpt-5.6-luna.
-
Set ADMIN_TOKEN to a valid local management API token. Do not print it.
-
Warm entitlement discovery once:
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \
http://127.0.0.1:10100/v1/models > /dev/null
-
Count the native OpenAI rows returned by the management endpoint every 30 seconds:
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \
http://127.0.0.1:10100/api/models \
| grep -o '"provider":"openai"' | wc -l
-
Observed timeline:
02:48:32 openai_rows=7
02:49:03 openai_rows=7
02:49:33 openai_rows=7
02:50:03 openai_rows=7
02:50:33 openai_rows=4 # roster cache expired
02:50:50 GET /v1/models
02:51:04 openai_rows=7 # restored immediately
02:51:34 openai_rows=7
...
02:55:38 openai_rows=7
-
A separate cold/warm check produced the same result:
BEFORE /v1/models
count=4
gpt-5.3-codex-spark,gpt-5.4,gpt-5.4-mini,gpt-5.5
GET /v1/models returned
gpt-5.6-luna,gpt-5.6-sol,gpt-5.6-terra
AFTER /v1/models
count=7
gpt-5.3-codex-spark,gpt-5.4,gpt-5.4-mini,gpt-5.5,gpt-5.6-luna,gpt-5.6-sol,gpt-5.6-terra
Suspected root cause
src/codex/catalog/native-models.ts: Sol/Terra/Luna are members of ACCOUNT_GATED_NATIVE_OPENAI_MODELS.
src/codex/catalog/metadata.ts: nativeModelRows() filters gated slugs through cachedAvailableAccountGatedNativeModels().
src/codex/model-entitlements.ts: the roster evidence is stored in the process-local accountModelsCache; MODEL_ROSTER_TTL_MS = 5 * 60_000. The cache projection requires entry.expiresAt > now.
src/server/management/model-routes.ts: GET /api/models calls only listManagementModelRows(config).
src/server/management/model-rows.ts: listManagementModelRows() calls fetchAllModels(config) and then nativeModelRows(config), but it does not call resolveCodexModelEntitlements(config) first.
- In contrast,
src/server/index.ts runs resolveCodexModelEntitlements(config, ...) on the GET /v1/models path. The resolver reuses a live cache entry and performs a new upstream roster fetch on a cache miss/expiry.
This also affects /api/client-config because loadExportModels() delegates to listManagementModelRows(). The live-service path used by ocx export reads /api/models, so an export performed while the cache is cold can silently omit the three GPT-5.6 entries.
A narrow fix may be to refresh entitlement evidence in the shared listManagementModelRows() path (or pass an explicit entitlement snapshot into the native-row projection) so /api/models, /api/client-config, and CLI exports stay aligned. The existing five-minute resolver cache would still prevent a remote request on every dashboard refresh.
Relationship to existing issues
Version
2.36.0
Operating system
Microsoft Windows 11 Pro, version 10.0.26200, build 26200, x64
Provider and model
Canonical openai provider using ChatGPT/Codex account authentication:
gpt-5.6-sol
gpt-5.6-terra
gpt-5.6-luna
Logs or error output
GET /api/models while entitlement cache is cold: openai_rows=4
GET /v1/models: GPT-5.6 Sol/Terra/Luna returned
GET /api/models immediately afterwards: openai_rows=7
Screenshots and supporting files
The complete redacted timeline and source trace are included above. No local patch has been installed.
Redacted configuration
{
"providers": {
"openai": {
"adapter": "openai-responses",
"authMode": "forward"
}
}
}
Checks
Client or integration
OpenCodex dashboard
Area
Catalog / models
Summary
On OpenCodex 2.36.0, the dashboard/management model list loses the entitled native OpenAI GPT-5.6 rows when the five-minute account-model roster cache expires.
Immediately after a successful entitlement discovery,
GET /api/modelscontains seven nativeopenairows:gpt-5.5gpt-5.4gpt-5.4-minigpt-5.3-codex-sparkgpt-5.6-solgpt-5.6-terragpt-5.6-lunaAfter five minutes, with no account or configuration change, the same endpoint returns only the first four. Calling
GET /v1/modelsimmediately restores all seven rows in/api/modelsfor another five minutes.The account is entitled to the three GPT-5.6 models:
/v1/modelsreturns them, the generated Codex catalog contains them withvisibility: "list", and they remain usable. This appears to be a management/catalog projection bug rather than a loss of model access.Expected: management readers should trigger or receive a current entitlement discovery before projecting account-gated native rows. The dashboard and exports should not silently change from 7 to 4 solely because the in-memory evidence cache expired.
Reproduction
Start OpenCodex 2.36.0 with an authenticated ChatGPT/Codex account entitled to
gpt-5.6-sol,gpt-5.6-terra, andgpt-5.6-luna.Set
ADMIN_TOKENto a valid local management API token. Do not print it.Warm entitlement discovery once:
Count the native OpenAI rows returned by the management endpoint every 30 seconds:
Observed timeline:
A separate cold/warm check produced the same result:
Suspected root cause
src/codex/catalog/native-models.ts: Sol/Terra/Luna are members ofACCOUNT_GATED_NATIVE_OPENAI_MODELS.src/codex/catalog/metadata.ts:nativeModelRows()filters gated slugs throughcachedAvailableAccountGatedNativeModels().src/codex/model-entitlements.ts: the roster evidence is stored in the process-localaccountModelsCache;MODEL_ROSTER_TTL_MS = 5 * 60_000. The cache projection requiresentry.expiresAt > now.src/server/management/model-routes.ts:GET /api/modelscalls onlylistManagementModelRows(config).src/server/management/model-rows.ts:listManagementModelRows()callsfetchAllModels(config)and thennativeModelRows(config), but it does not callresolveCodexModelEntitlements(config)first.src/server/index.tsrunsresolveCodexModelEntitlements(config, ...)on theGET /v1/modelspath. The resolver reuses a live cache entry and performs a new upstream roster fetch on a cache miss/expiry.This also affects
/api/client-configbecauseloadExportModels()delegates tolistManagementModelRows(). The live-service path used byocx exportreads/api/models, so an export performed while the cache is cold can silently omit the three GPT-5.6 entries.A narrow fix may be to refresh entitlement evidence in the shared
listManagementModelRows()path (or pass an explicit entitlement snapshot into the native-row projection) so/api/models,/api/client-config, and CLI exports stay aligned. The existing five-minute resolver cache would still prevent a remote request on every dashboard refresh.Relationship to existing issues
Version
2.36.0
Operating system
Microsoft Windows 11 Pro, version 10.0.26200, build 26200, x64
Provider and model
Canonical
openaiprovider using ChatGPT/Codex account authentication:gpt-5.6-solgpt-5.6-terragpt-5.6-lunaLogs or error output
GET /api/models while entitlement cache is cold: openai_rows=4 GET /v1/models: GPT-5.6 Sol/Terra/Luna returned GET /api/models immediately afterwards: openai_rows=7Screenshots and supporting files
The complete redacted timeline and source trace are included above. No local patch has been installed.
Redacted configuration
{ "providers": { "openai": { "adapter": "openai-responses", "authMode": "forward" } } }Checks