Skip to content

fix(models): project drifted discovery reads instead of answering catalog_busy - #6333

Merged
lidge-jun merged 1 commit into
devfrom
codex/fix-stale-discovery-refusal
Sep 30, 2026
Merged

lidge-jun merged 1 commit into
devfrom
codex/fix-stale-discovery-refusal

Conversation

@lidge-jun

Copy link
Copy Markdown
Owner

Summary

Cross-platform CI on dev (run 36734548914) failed on Linux, Windows and macOS with one test: tests/codex-integration/model-visibility-management-api.test.ts "manual models replace management rows…" threw CatalogGatherBusyError. The cause is #6331. It marks every loadConfig() object as file-backed and refuses discovery publication once such a config differs from disk. A management read on a config that differed from disk (unsaved in-memory edits, or another writer changed the file) therefore answered catalog_busy 503. In production, the dashboard model list would keep failing until the config reloaded.

Read consumers now opt into a detached projection when a file-backed config has already drifted. The new-arrival policy is applied to a copy of modelDiscovery/disabledModels. Management renders new arrivals as disabled from that copy, and other fetch consumers receive only rows visible under it. The live config, disk and save baselines stay untouched, so the #6331 protection holds: no unsaved disable can later be persisted over an operator's on-disk choice. Writers (retained sync) still refuse stale publication.

Verification

  • The failing test and a new HTTP regression (drifted file-backed config lists rows without 503 and without mutating live config) fail before the fix and pass after. A concurrent-enable/later-save regression keeps the fix(models): apply new-model policy before discovery, sync and export publication #6331 contract.
  • bun test over model-visibility-management-api, new-model-policy-runtime, new-model-policy, server-new-model-policy-arrival, model-export-new-model-policy, codex-sync-new-model-policy, file-size ratchet and test-layout: 80 pass / 0 fail. bun x tsc --noEmit and bun run structure:check pass.
  • Full local suite not run by maintainer instruction; Cross-platform CI reruns once on the dev tip after this merge.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

…licy

File-backed inventory drift rejected ordinary model reads with catalog_busy. Identical synthetic inventory succeeds on the same cached roster, ruling out row replacement and cache revision churn in the reproduction.

Allow read callers to receive a detached new-arrival policy projection. Management renders disabled arrivals; other shared-fetch consumers receive only visible projected rows. Keep retained-sync and direct stale-writer refusal contracts, inventory/revision checks, and persisted merge baselines intact.

Verification: eight authorized files, 80 passed / 0 failed; after adding save-safety coverage, runtime-policy and ratchet files, 24 passed / 0 failed. Typecheck and structure checks pass. Full suite and docs build were excluded by the delegated command restrictions.
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner September 30, 2026 15:27
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 30, 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-09-30T15:33:06.380003Z c7cdebe 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.

@github-actions github-actions Bot added the bug Something isn't working label Sep 30, 2026
@coderabbitai

coderabbitai Bot commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Repository: lidge-jun/opencodex/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: cfa6f211-92f8-41b7-9582-aabd302c10fa

📥 Commits

Reviewing files that changed from the base of the PR and between 4f31822 and c7cdebe.

📒 Files selected for processing (11)
  • docs-site/src/content/docs/guides/model-routing.md
  • src/providers/new-model-policy-runtime.ts
  • src/server/management/model-rows.ts
  • src/server/management/shared.ts
  • structure/catalog.md
  • structure/config.md
  • structure/gui-and-management-api.md
  • structure/providers-and-adapters.md
  • structure/runtime.md
  • tests/codex-integration/model-visibility-management-api.test.ts
  • tests/providers/new-model-policy-runtime.test.ts
 ______________________________________________
< This is O(n) in theory and O(🤡) in practice. >
 ----------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@lidge-jun

Copy link
Copy Markdown
Owner Author

Maintainer integration into dev by @lidge-jun: fixes the Cross-platform CI failure on dev (run 36734548914, Linux/Windows/macOS, one test) introduced by #6331. The failing test and the new regressions pass locally at this head together with bun x tsc --noEmit and structure:check; Cross-platform CI reruns once on the dev tip after this merge.

@lidge-jun
lidge-jun merged commit 349588e into dev Sep 30, 2026
20 of 28 checks passed
@lidge-jun
lidge-jun deleted the codex/fix-stale-discovery-refusal branch September 30, 2026 15:29

@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: c7cdebebd5

ℹ️ 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".

Comment on lines +291 to +294
if (publicationConfig !== config && !publishProjection) {
// Other consumers keep their live config, so only return rows visible under the projection.
const { filterCatalogVisibleModels } = await import("../../codex/catalog");
return filterCatalogVisibleModels(models, publicationConfig);

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 Preserve unfiltered rosters for configuration endpoints

When a file-backed configuration already differs from disk, this filters the shared fetch result using every disabledModels entry and selectedModels allowlist, not only the newly projected arrivals. However, /api/selected-models explicitly uses fetchAllModels to construct its full unfiltered available roster, and the model-preset routes use it to calculate complete candidate sets. During persistent live/disk drift, those endpoints therefore omit models the user needs to re-enable and can apply a preset from a truncated roster; pass the detached config separately to visibility consumers while retaining raw rows for configuration callers.

AGENTS.md reference: src/AGENTS.md:L10-L10

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant