Repository navigation
fix(db): union dispatch-tagged registry models into authoritative live catalogs - #15599
Merged
diegosouzapw merged 7 commits intoOct 6, 2026
Conversation
…e catalogs Partial discovery surfaces could veto registry-curated models that the provider actually serves. z.ai's Anthropic-compat /models omits the glm-5.3-flash coding-plan family, so a fresh authoritative snapshot built from that surface rejected zai/glm-5.3-flash-max pre-dispatch with model_not_in_catalog, 503ing every combo targeting it (observed live: factory-efficient -> ALL_TARGETS_SKIPPED) even though both the static registry (targetFormat: openai) and the capability sync knew the model. getActiveSyncedCatalog now unions registry models that carry an explicit per-model targetFormat into the discovered set. The union is bounded: registry rows join only when discovery reported something and only for ids it did not; untagged models stay discovery-gated and custom rows alone still cannot establish authority (diegosouzapw#12934). Same union shape as diegosouzapw#12866 (sibling catalogs) and diegosouzapw#12597 (customModels).
…ract Extends the partial-discovery regression tests: the discovered row keeps its synced metadata where both sources know the id (a flipped merge direction would revert learned metadata to registry values for every tagged model), and the unioned row carries the registry dispatch intent and capability fields that visionBridgeRouter and the combo context filter read without a registry fallback.
Pre-landing review findings, all INFORMATIONAL: - Unioned rows carry catalogOrigin:"registry" so catalog rows derived from the static registry stay machine-distinguishable from discovery rows, and getAllActiveSyncedModels unions the same rows so listing surfaces agree with dispatch (pinned by a provenance test). - The registry-row derivation is cached per provider and the empty-discovery guard runs before any registry work: the union sits on the per-resolution hot path and its inputs are static registry data. - maxInputTokens maps to inputTokenLimit like its sibling budget fields (diegosouzapw#6191); the empty-snapshot authority guard and the row capability contract (outputTokenLimit) gained direct tests. The changelog notes the entitlement tradeoff.
Adversarial pass follow-ups: the merge loop tracks admission with an added flag instead of comparing Map sizes (correct even if a future caller passes unfiltered rows), supportsTools maps from toolCalling so unioned rows carry the same tool metadata discovery rows do, and catalogOrigin survives a normalizeSyncedAvailableModels round-trip so the registry-vs-discovery marker cannot be laundered away.
Adversarial follow-up: targetFormat tags exist on ~11 providers, and on several of them discovery omission means per-account entitlement, not a partial surface. Union on every tagged provider would have bypassed diegosouzapw#12137-style entitlement gating and re-armed doomed combos on github, vertex, and friends. The union now runs only for providers that opt in via registryDispatchUnion (zai first: its discovery surface is known to under-report the coding-plan family). Custom overlays drop the stale catalogOrigin marker, and cached union rows are frozen so the shared row objects cannot be mutated through catalog reads. A negative test pins that a tagged-but-unflagged provider keeps discovery gating.
Adversarial pass 3 prescribed two one-liners: the cached union rows are process-lifetime singletons, so their supportedThinkingEfforts arrays are frozen too (model.ts hands one to runtime metadata by reference), and normalizeSyncedAvailableModels no longer copies catalogOrigin from input records - the construction site is the only source, so operator custom-model JSON cannot self-stamp rows as registry-origin.
Pass 4 runtime-verified that the input-side freeze landed on the copy normalizeSyncedAvailableModels discards: .filter() rebuilds the array unfrozen, so model.ts still received a mutable singleton by reference. Freeze post-normalize (row + array) where the cache is built, and pin both with Object.isFrozen assertions.
diegosouzapw
merged commit Oct 6, 2026
8c1ccf5
into
diegosouzapw:release/v3.8.52
42 of 51 checks passed
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.
Summary
/modelssurface) omits theglm-5.3-flashcoding-plan family, so every combo targetingzai/glm-5.3-flash-maxreturned 503ALL_TARGETS_SKIPPEDwithmodel_not_in_catalog. Observed live on a v3.8.51 deployment: thefactory-efficientcombo was fully down while the model worked through every other path.unionRegistryDispatchModelsletstargetFormat-tagged registry models join the discovered set for providers that opt in via a newregistryDispatchUnionregistry flag (zai first). The union is bounded: only non-empty discovery sets, only ids discovery did not report; untagged models stay discovery-gated; custom rows alone still cannot establish authority (fix(catalog): union picker customModels into the dispatch-time live catalog (#12597) #12934). Same union shape as feat(models): live account catalog for Claude, Codex, Copilot, AGY #12866 (sibling catalogs) and fix(backend): chat dispatch ignores model-picker additions (customModels vs syncedAvailableModels) #12597 (customModels).getAllActiveSyncedModelsunions too, so listings agree with dispatch) and carrycatalogOrigin: "registry", whichnormalizeSyncedAvailableModelsrefuses to copy from input records, so operator metadata cannot forge registry provenance.autoFetchModels: trueand had synced that day; the snapshot containedglm-5.3, glm-5.2, glm-5.1, glm-5, glm-5-turbo, glm-4.7-flash, glm-4.7and no flash family.lookupModelMetarejected the request becauseliveBackedEffortVariantrequires the base model in the synced set. Upgrading the deployment could not fix it, because the snapshot re-syncs from the same partial surface. OthertargetFormat-tagged providers (github, vertex, grok-cli, and 8 more) do NOT opt in, so their feat(providers): filter explicit combo members against the GitHub Models live catalog (follow-up to #8134) #12137-style entitlement gating is untouched; the flag is an explicit per-provider decision with an instant kill-switch.Test Coverage
Tests: 6986 → 6987 (+1 new file, 7 tests)
Coverage: 92% value-weighted after strengthening (77% at first audit; 12 of 13 behaviors at ★★/★★★). 1 path left as a proposed integration test (visionBridgeRouter reading a real catalog) with value card below.
Test value: 7 regression tests written in the new file, 0 rejected, 3 existing tests extended during the coverage gate, 1 path weakly covered (noted in the audit diagram).
Regression proof — red on the pre-fix tree (2 of the first 4 tests failed before the union landed) · green after (7/7, including
Object.isFrozenpins).Pre-Landing Review
8 findings (0 critical) from 5 dispatched specialists (testing, maintainability, security, performance, simplification) plus the red team; security and simplification returned clean. All 8 fixed across 4 fix commits (memoized derivation with empty-discovery early-exit, maxInputTokens mapping, outputTokenLimit + empty-snapshot-guard + listing-parity tests, per-provider opt-in gate, catalogOrigin un-forge, effort-array freeze). PR quality score at audit time: 6/10; post-fix cluster 67/67, typecheck clean.
Outside review: unavailable. Codex passes skipped (
model_unusable: the local gstack install's model resolver is broken,scripts/resolve-codex-generation-model.tsmissing). Native adversarial coverage ran in 5 passes on this machine; final pass verdict: "approve because the delta is exactly pass 4's prescribed correction — runtime-proven on the current build (mutation attempts throw, both Object.isFrozen checks true, cached singleton identity holds across reads), with zero mutating consumers of the array anywhere in production code".Exploratory QA
Live contracts probed on the operator deployment (omniroute.home.arpa, v3.8.51 + operator-side DB workaround, separate from this PR's code path):
factory-efficient→ HTTP 200, served byglm-5.3-flash(the incident contract)factory-capable→ HTTP 200 (adjacent happy path)zai/glm-5.3-flashpresent in/v1/modelsProduction verifies the operator workaround; THIS PR's fix is verified by the native regression suite (red before, green after) plus a runtime freeze/mutation check done by the adversarial pass. Full local unit suite: not run locally. It deadlocked on this machine (the repo's documented leaked-DB-handle hang), and CONTRIBUTING.md #8084 assigns the full suite to CI (4 shards); CI results govern this PR. Both suite types that do cover the change ran green locally: 67/67 targeted cluster, 493/493 vitest.
Design Review
No frontend files changed — design review skipped.
Eval Results
No prompt-related files changed — evals skipped.
Scope Drift
Scope Check: CLEAN
Intent: union dispatch-tagged registry models into authoritative live catalogs, with tests.
Delivered: exactly that, plus the opt-in flag, listing parity, and provenance stamping that review added; every commit maps to a recorded finding.
Plan Completion
Plan completion audit: not run (no plan is bound to this branch and no docs/designs/ file matches). Fix: add "Plan: " to the PR body, or run /autoplan.
Verification Results
npm run typecheck:core: PASS (exit 0)Documentation
Status: current — ship-owned documentation audit of fix/zai-live-catalog-registry-union (base 23a1148 → head 34b89ae) found no authored doc contradicted by the shipped registry-union change; no edits made, no blockers.
Audited scope: all 6 committed files (changelog fragment, zai registry entry, shared RegistryEntry interface, activeSyncedCatalog union logic, synced row marker, new regression test) plus 9 untracked .gstack/qa-reports receipts; no staged or unstaged changes existed. Cross-checked docs: ARCHITECTURE.md provider table, USER_GUIDE.md free-tier lists, CURSOR-DOCKER.md exclusive-catalog claim, MODEL_EXPOSURE_LIST.md, changelog.d/README.md fragment convention, and the PROVIDER_REFERENCE generator.
Documentation health:
Documentation coverage:
Documentation Debt:
Diagram drift: none.
Test plan
node --import tsx/esm --test tests/unit/zai-partial-discovery-registry-union.test.ts(and 9 adjacent catalog suites): 67/67 passing on the final treenpm run test:vitest: 493/493 passing on the final treenpm run typecheck:core: cleanPOST /v1/chat/completionsfactory-efficient→ 200 served byglm-5.3-flashTests Added Or Updated