Adds opt-in modelVisibilityAllowlist/modelVisibilityDenylist settings so an operator can curate exactly which models GET /v1/models advertises, mirrored into auto/* combo candidate pools (the same trap #6512 fixed for hidePaidModels). Default off, no behavior change for anyone who doesn't opt in.
TDD: 4 new test files, 22/22 passing (16 node:test + 6 vitest) + regression sweep across virtual-auto-combo/hide-paid/hide-auto-no-think suites (21/21).
Rebased onto the updated tip (a sibling #9133 landed first, same file) — kept both rebaseline annotations in file-size-baseline.json and set the value to the real measured line count after both merged.
#11845 landed on main as 163 while release/v3.8.51 had already used 163–168.
Per the cross-PR collision precedent (#3365/#3371) the later arrival takes the
next free number; the SQL is idempotent, so installs that already ran it as
163 on main are unaffected.
The eighteen commits main carries beyond the cycle branch, and what each one
became here:
already in release/v3.8.51 by its own PR (no-op, verified by content):
b090b601a5 / 026e1cadaa deps: nanoid 3.3.18 equal, dompurify 3.4.14 newer
918fba5e39 .gitignore: /_tasks already anchored
5f0a394091#10026 hide health-check-excluded models — same helper, 5 call sites
c68cda7dfb#11075 shared passthrough providers — superseded by #11071/#11078
superseded, one piece kept:
ca23eed77c#10055 memoize models.dev pricing — the cycle memoizes on the
catalog cache version already; only the resetDbInstance() hook is
ported, wired to that memo
applied as-is:
8778ea7d18 stamp dist/BUILD_SHA before the npm provenance gate (#11721)
aa52351113 decouple the Bun image from the release manifest (#11724)
925feb27b8 let the bun digest artifact be absent (#11740)
b65ef333da size the install-upgrade gate to a measured run
0ce21232db#11845 converge install/upgrade schemas (migration renumbered in
the next commit: 163 collides with 163_radar_feed_cache_generated_at)
b7c07edad8#11855 install-upgrade gate on disk, not tmpfs
8e2fb04329#11864 drop *.nft.json from the npm tarball (413)
dea6bb8b6b#11877 publish npm from a hosted runner (provenance 422)
handled by the sync script that follows (CHANGELOG protocol):
b4ec7807ab Release v3.8.50 — squash of content this branch already carries
5458026c21 / c44c0a29e8 CHANGELOG aggregation, stats and top-25
applied separately (its own commit, ten files):
65e81158ab#11088 Ollama capability routing — a 5,094-file squash from a
stale base; only the Ollama files are the change
Every cherry-pick that touched a file this branch had also changed was
resolved by hand and re-run through the tests both sides own for it.
Adds an opt-in customModels[].isFree flag so a self-hosted local model can be marked free-tier without touching the curated free-model catalog (providerHasFreeModels stays curated). 9/9 focused tests passing across the DB round-trip, schema tri-state validation, and free-model detection. Thanks!
Rebased onto the current release/v3.8.51 tip as part of a combined provider-retirement/provenance merge batch (Designer Web, Felo Web, Runtime, GPL-derived removal, Qwen Web already landed). Large conflict set (this is the biggest PR in the batch — the common ChatGPT Web provider touches chat, images, count-tokens, session leases, and combos). Conflicts resolved:
- `open-sse/config/providers/registry/chatgpt-web/*`, `open-sse/executors/chatgpt-web*`, `open-sse/handlers/imageGeneration/providers/chatgptWeb.ts`, and their tests: kept deleted, matching the PR's stated scope.
- `open-sse/config/providers/registry/minimax/web/index.ts`, `open-sse/handlers/imageGeneration/providers/geminiWeb.ts`, `open-sse/executors/gemini-web.ts`'s stale image-mode branch: base-drift collisions against already-merged sibling retirements (#11691, #11708) — kept deleted / dropped the dead code, since this PR's own branch forked before those merged.
- `src/shared/constants/reservedProviderPrefixes.ts`, `open-sse/executors/index.ts`, `executorProxy.ts`, `virtualFactory.ts`, `autoStrategy.ts`, `src/lib/db/providers.ts`, `src/sse/handlers/chat.ts`: combined the Designer + Runtime (Felo/Qwen) + common-ChatGPT-Web retirement guard calls at each shared chokepoint — compute-once-then-OR pattern, consistent with prior combinations in this batch.
- `src/sse/services/model.ts` / `src/sse/handlers/chatHelpers.ts`: adopted this PR's new `getModelInfoOrRetirementResponse()` central wrapper (a real improvement over ad-hoc try/catch), and extended it to also catch the Designer + Runtime retirement errors it didn't originally cover, so the consolidation doesn't regress the other two mechanisms.
- `src/app/api/v1/images/edits/route.ts`: this PR moved the retirement check earlier (before `enforceApiKeyPolicy`) but left the old later call+catch block in place from base drift — removed the now-redundant duplicate `resolveImageRouteModel()` call and merged the Designer catch into the earlier one.
- `open-sse/config/imageRegistry.ts`, `tests/snapshots/executors/executor-map.json` (`keyCount` recomputed to 133), `tests/snapshots/provider/translate-path.json`: same "both sides inserted a different retired provider at the same slot" pattern — resolved by dropping both.
- `tests/unit/chatcore-executor-proxy.test.ts`, `provider-node-reserved-prefix.test.ts`, `combo-auto-candidate-expansion.test.ts`, `messages-count-tokens-route.test.ts`, `virtual-auto-combo.test.ts`: split into independent per-mechanism test blocks (established pattern); `virtual-auto-combo.test.ts`'s old "includes cookie web-session providers" positive-inclusion test (which used chatgpt-web as its example) was retired along with the provider and replaced by this PR's negative-exclusion test for the same slot.
- `docs/architecture/ARCHITECTURE.md`, `CODEBASE_DOCUMENTATION.md` (+ 4 i18n mirrors), `README.md`, `FREE-TIERS-GUIDE.md`, `docs/diagrams/free-tier-budget.svg`, `docs/screenshots/free-tier-budget-card.svg`, `docs/reference/PROVIDER_REFERENCE.md`: recomputed every stale count from the real merged state — 104 executors (`countFiles` gate logic), 351 providers (regenerated via `gen:provider-reference`), 152/351 `hasFree` entries, 445/438/7 free-tier catalog rows, 13 ToS-avoid providers, budget-card regenerated via its real generator script. One doc conflict (`oauth/` module list) needed picking HEAD's side specifically — theirs still listed the already-removed `raycast` module instead of the real `openference`.
- `config/quality/test-masking-allowlist.json`: additive merge of the PR's 17 `_deletedWithReplacement` entries alongside the batch's existing ones (one real duplicate-key mistake in my first pass, caught and fixed via a `object_pairs_hook` duplicate-key check before finalizing).
Also fixed two real, unrelated-to-my-merge issues surfaced by the focused suite:
- `tests/unit/resolve-web-provider-host.test.ts`: the PR's own test had a typo — it asserted `perplexity-web`'s resolved host as `"perplexity.ai"`, but the provider's registered `website` is `"https://www.perplexity.ai"` and the resolver returns the URL's `host` verbatim (no www-stripping), so the correct value is `"www.perplexity.ai"` (consistent with the same test's own `url` assertion).
- `tests/unit/hard-session-lease-bypass-inventory.test.ts`: this golden call-site inventory was already stale on the pristine post-#11713 tip (confirmed via a throwaway probe worktree) — `src/lib/db/providers.ts`'s 3 connection-fallback sites and a third `src/app/api/providers/route.ts` site were never added to the golden list by the earlier-merged #11698/#11720 PRs. Updated it to the real current inventory (dated inline comments explain each delta and which PR introduced it), plus this PR's own legitimate deltas (image-edits duplicate-call removal, `ChatGptWebExecutor.execute()` site removed).
Focused suite green (433/433 across executor-proxy, reserved-prefix, hard-session-lease-bypass-inventory, resolve-web-provider-host, retirement/runtime-block/source-retirement/management-retirement/image-handler-retirement, migration-168, combo-auto-candidate-expansion, virtual-auto-combo, executor-map-golden and siblings), plus `typecheck:core`, `check-file-size`, and `check-changelog-integrity` clean. Thanks for the thorough provenance-hold retirement work — appreciated.
Rebased onto the current release/v3.8.51 tip as part of a combined provider-retirement/provenance merge batch (Designer Web, Felo Web, Runtime, GPL-derived removal all landed together already). Conflicts resolved:
- `src/shared/constants/providerRetirement.ts`: add/add conflict — combined `felo-web`/`felo` (already-merged) with `qwen-web`/`qw` into one `RUNTIME_RETIRED_PROVIDER_IDS` set, kept both `assertRuntimeProviderAvailable`/`assertRuntimeModelProviderAvailable` helpers.
- `open-sse/config/providers/registry/minimax/web/index.ts`: modify/delete — kept deleted (file is hailuo-web's registry entry, already retired by #11691; this PR's own change to it was just a comment reword on a since-removed target).
- `open-sse/executors/index.ts`, `executorProxy.ts`, `virtualFactory.ts`, `autoStrategy.ts`, `model.ts`, `chat.ts`, `chatHelpers.ts`, `auth.ts`, `src/lib/db/providers.ts`, `reservedProviderPrefixes.ts`: combined the Designer + Runtime (Felo + Qwen) retirement guard calls at each shared chokepoint — compute-once-then-OR pattern, consistent with the prior Designer+Felo combination.
- `src/shared/constants/providers/web-cookie.ts`, `tests/snapshots/provider/translate-path.json`, `tests/snapshots/executors/executor-map.json`: both sides had inserted a different retired provider (qwen-web vs. already-retired raycast/hailuo-web) at the same dict position — resolved by dropping both. `executor-map.json`'s `keyCount` recomputed to 135 (matches actual merged `entries`).
- `tests/unit/chatcore-executor-proxy.test.ts`, `tests/unit/provider-node-reserved-prefix.test.ts`: split into independent Felo/Qwen test blocks (established pattern for coexisting retirement-mechanism tests); recomputed `RESERVED_PREFIX_COUNT` to 398 (Designer+Felo+Qwen tombstones on top of the post-#11691 REGISTRY, verified via direct module evaluation, not hand-derived).
- `config/quality/test-masking-allowlist.json`: additive merge of Qwen's `_deletedWithReplacement` entries alongside Designer's.
- `README.md` + all `docs/i18n/*/README.md` mirrors, `docs/getting-started/FREE-TIERS-GUIDE.md`, `docs/reference/FREE_TIERS.md`, `docs/diagrams/free-tier-budget.svg`, `docs/screenshots/free-tier-budget-card.svg`: recomputed the free-tier catalog counts (447 entries / 440 active / 7 discontinued) from the actual merged `freeModelCatalog.data.ts`, regenerated the budget-card SVG via its real generator (`scripts/research/gen-budget-card-svg.mjs`), and dropped the retired Qwen quick-start row / QWEN MODELS section from every i18n README (identical unlocalized block across all 34 locales).
- Also fixed a duplicate-import merge artifact in `src/lib/db/providers.ts` (`isRuntimeRetiredProviderId` imported twice) caught by `typecheck:core`, and rebaselined `file-size-baseline.json` for the combined retirement-guard growth (`virtualFactory.ts` +3, with justification).
Focused suite green (345/345 across executor-proxy, reserved-prefix, migration-167, qwen-web-retirement, virtual-auto-combo, web-cookie/session, executor-map-golden and siblings), plus `typecheck:core` and `check-file-size`/`check-changelog-integrity` clean. Thanks for the provenance-hold retirement work — appreciated.
Rebased onto the current release/v3.8.51 tip as part of a combined provider-retirement/provenance merge batch (Designer Web, Felo Web, Runtime, and this GPL-derived Raycast/Hailuo Web removal all landed together). Conflicts resolved:
- `config/quality/test-masking-allowlist.json`: additive merge of the Hailuo-Web/Raycast-auth/Raycast-local-extract entries alongside prior sibling retirement entries.
- `docs/reference/PROVIDER_REFERENCE.md`: kept the branch's generated content (deferred to a future `npm run gen:provider-reference` regeneration pass).
- `src/app/api/providers/[id]/test/webSessionTestDispatch.ts`: comment-only, dropped stale retired-provider examples.
- `tests/snapshots/executors/executor-map.json`: recomputed `keyCount` to 137 (matches the actual merged `entries` object).
- `tests/unit/provider-test-token-web-session-dispatch.test.ts`: kept both sibling assertions (hailuo-web + t3-chat-web), avoided duplicating the dedicated microsoft-designer-web test already present.
Also recomputed the golden `RESERVED_PREFIX_COUNT` (397, down from 400) to reflect the 3 GPL-derived ids/aliases this PR removes from `REGISTRY`, and rebaselined `file-size-baseline.json` for the combined retirement-guard growth accumulated across the sibling PRs in this batch.
Focused suite green (86 tests across authz/oauth-autoimport, public-route-exact-match, gpl-derived-provider-removals, migration-166, muse-spark-ws-auth-token, oauth-providers-config, provider-alias-uniqueness, provider-test-token-web-session-dispatch, providers-constants-split, ts7-executor-override-signatures, executor-map-golden, provider-node-reserved-prefix), plus `typecheck:core` and `check-file-size` clean. Thanks for the GPL-license cleanup — appreciated.
Merged via /merge-batch (v3.8.51 provenance sweep). Boarded and validated together with the batch's other retirement PRs in a combined worktree — full gate suite green. This PR's conflicts (against #11720's Designer retirement, both introducing a retirement-guard mechanism across executors/index.ts, executorProxy.ts, providers.ts, reservedProviderPrefixes.ts, auth.ts, chat.ts, chatHelpers.ts, model.ts) were reconciled by combining both guards at every chokepoint, with the shared reserved-prefix count recomputed (not guessed) at 400. Re-validated with this PR's own 72 node:test + 20 vitest focused tests, all passing, and pushed before merge. Thank you.
Merged via /merge-batch (v3.8.51 provenance sweep). Boarded and validated together with the batch's other retirement PRs in a combined worktree — full gate suite green. This PR's own conflicts (against #11711's EdgeTTS retirement, both touching test-masking-allowlist.json and the "Image / video / audio generation" README bullet) were reconciled additively/subtractively (both retirements now correctly reflected), re-validated with this PR's own 62 focused tests, and pushed before merge. Thank you.
Obrigado pela correção! Validado em lote combinado (8 PRs, release/v3.8.51):
- Reprodução com imagem pública confirmada no corpo da PR (`compression_run_telemetry` ausente após fresh install).
- Reutiliza o helper `tableExists()` já existente — sem SQL cru novo.
- Testes focados: 7/7 em `tests/unit/telemetry-auto-cleanup-6848.test.ts` (verde).
- Gates estáticos do lote: typecheck, lint (228 erros pré-existentes na tip pura, confirmado via probe-worktree — zero regressão), complexity, cognitive-complexity, file-size e changelog-integrity — todos OK.
Merged via /merge-batch (lote 2026-08-26 batch 2, v3.8.51). Encontrei um bug real na validação: o guard `NODE_ENV==="test"||VITEST` não cobre o test runner nativo do projeto (`node --import tsx/esm --test`, que não seta NODE_ENV), então o fallback estava lendo `~/.omniroute/.env` — o .env de PRODUÇÃO real do operador — durante qualquer execução de teste sem esse env var. Corrigi usando o `isTestContext()` já existente e mais robusto em `dataPaths.ts` (cobre `NODE_TEST_CONTEXT`/`--test` argv), e troquei o path hardcoded `os.homedir()/.omniroute` por `resolveDataDir()` para respeitar `DATA_DIR` quando configurado. Enviei a correção para o seu branch antes do merge. Validado: 7/7 testes de `db-encryption.test.ts` passando. Obrigado pela contribuição — a ideia central (fallback do STORAGE_ENCRYPTION_KEY) é boa e necessária.
Merged via /merge-batch (lote 2026-08-26 batch 2, v3.8.51). Boarded no worktree combinado junto com outras ~20 PRs; validação única: typecheck/complexity/cognitive-complexity/changelog-integrity verdes, file-size rebaseado onde necessário (crescimento legítimo), lint com os mesmos 228 achados pré-existentes confirmados via sonda contra o tip puro (não introduzidos por este lote), e 292 testes focados (unit) + 18 (vitest) passando. Obrigado pela contribuição.
Validated in a combined 2-PR batch worktree off release/v3.8.51 tip.
- Focused test: responses-continuation-store.test.ts — part of batch's 46/46 node:test run
- typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity — all OK
- Full-repo lint: 228 pre-existing dashboard react-hooks/* findings, unrelated to this diff
Thanks for the live-verified root cause — a truncation sentinel getting forwarded upstream as a real Responses-API item, breaking the turn with a genuine 400, is exactly the kind of defect that's easy to miss without production traffic to reproduce against.
Validated in a combined 5-PR batch worktree off release/v3.8.51 tip.
- Focused test: perf-waterfall-elimination.test.ts — part of batch's 115/115 node:test run
- typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity — all OK
- Full-repo lint: 228 pre-existing dashboard react-hooks/* findings, unrelated to this diff
Thanks for parallelizing these independent DB/settings reads — straightforward, low-risk perf hygiene with parity tests.
Validated in a combined 3-PR batch worktree off release/v3.8.51 tip.
- Focused test: electron-smoke-script.test.ts — part of batch's 165/165 node:test run
- typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity, check:docs-counts-sync — all OK
- Full-repo lint: 228 pre-existing dashboard react-hooks/* findings, unrelated to this diff
Real hardware validation on a fresh packaged Windows build (Hard Rule #18) surfacing and fixing 5 genuine defects (GNU-tar drive-letter parsing, missing asar file, electron-builder's node_modules extraResources drop, USERPROFILE-derived userData path, unreachable driver-log assertion) is exactly the kind of investigation this repo needs more of. Thank you.
Validated in a combined 3-PR batch worktree off release/v3.8.51 tip (a sibling PR from the same author, #11495, was held out — see its own comment for the isolated finding, unrelated to this diff).
- Focused test: web-cookie-expiry.test.ts — part of batch's 94/94 node:test run
- typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity — all OK
- Full-repo lint: 228 pre-existing dashboard react-hooks/* findings, unrelated to this diff
Thanks for closing a real trust gap — operators deserve to know a cookie is about to expire before a live request fails.
Validated in a combined-batch worktree off release/v3.8.51 tip alongside #11259 and the cherry-picked #11323 successor (#11493):
- Focused test: tests/unit/oauth-connection-tokenexpiresat-5326.test.ts — 3/3 pass, exercises the round-trip through createProviderConnection/getProviderConnections
- typecheck:core, file-size, changelog-integrity, complexity, cognitive-complexity gates — all OK
- One-string allowlist fix, TDD-proven (fails on base with tokenExpiresAt: null, passes with the change), mutation-checked
Thanks for restoring #5326's fix end to end — clean, minimal, well-tested.
Merged into release/v3.8.51 via batch validation: exclusive-session-observability unit+UI suites green on the combined tree, static gates green. Nice additive observability layer over the #10362 lease backend — thanks @KaspaPulse!
Retargetado para release/v3.8.51 (release/v3.8.50 está congelada — freeze issue #11439). Resolvido um conflito de merge não-relacionado em src/shared/utils/wsPath.ts (originado de um refactor já mergeado nessa branch depois do fork deste PR; o diff real deste PR — scripts/dev/sync-env.mjs + tests/unit/sync-env.test.ts — ficou intacto) e revalidado: typecheck:core limpo, 13/13 testes focados passando.
Segue o precedente correto do #1622 (STORAGE_ENCRYPTION_KEY) para os dois secrets restantes que a postinstall preenchia por engano, defeituando o mecanismo de ensureSecrets(). Obrigado pela contribuição!
Retargetado para release/v3.8.51 (release/v3.8.50 está congelada — freeze issue #11439). Validado em lote combinado (batch-0824h2) contra o tip de release/v3.8.51: typecheck:core limpo, gates estáticos + migration-numbering OK, 127/127 testes focados passando (8/8 do PR entre migration-163 e radar-feed-cache-generated-at).
Migração limpa (ADD COLUMN nullable, sem backfill necessário), aditiva na API, mantém "unknown" honesto para linhas antigas. Obrigado pela contribuição!
Retargetado para release/v3.8.51 (release/v3.8.50 está congelada — freeze issue #11439). Validado em lote combinado (batch-0824h2, junto de #11435/#11436/#11437) contra o tip de release/v3.8.51: typecheck:core limpo, gates estáticos OK, 127/127 testes focados passando.
Investigação sólida com repro real via container isolado, três causas independentes identificadas e corrigidas com testes de regressão dedicados para cada uma. Obrigado pela contribuição!
Validated on the resolved merge against the current tip (527da656 + the post-#11281 rebaseline): the single conflict was a comment-only collision in providers/[id]/models/route.ts (kept the tip's #10828-ordering note). Focused suites 125/125 across all 13 touched test files (build-sqlite-stub, cc-compatible, copilot-claude-messages, copilot-gemini-route, executor-github, ghe-copilot, github-copilot-discovery-token, github-copilot-model-discovery, noauth-sibling-7620, provider-header-profiles, provider-models-config, request-log-payloads, upstream-error-passthrough), typecheck:core clean, file-size/changelog-integrity OK. Merged --admin over the inherited 2026-08-23 base-red cluster (#9985) — the reds are proven tip failures (CLI catalog cluster + @testing-library allowlist, being drained by #11280), not from this diff. Note: the rebase means several items the body listed (relay x-relay-path SSRF, /v1/search blocked-providers, #10736 rotation fence, #10903, #10865, #10899, #10916) already landed upstream and are NOT in this delta — the delta is: better-sqlite3 build guard + build heap/worker caps + telemetry-off (#10060 re-derived), credential-echo passthrough refusal + OCR/moderation redaction + call-log key redaction, Copilot CLI 1.0.81-6 wire identity + Claude→/v1/messages name-matched routing + discovery token fix, CC model_not_found 400, compat overrides for no-auth aliases (#7620-pinned). The Copilot wire-identity change is the one to watch in production. Thank you @arminanton — and the ported-author credits in the commit history (@rqzbeh, yidecode, the #10899/#10916 authors) are preserved. Your config-posture finding (REQUIRE_API_KEY default vs 0.0.0.0) is noted for a maintainer decision, as you scoped it.
Validated on the combined 12-PR batch board: focused node:test suites green (incl. provider-rate-limit-overrides-schema + ratelimit-admission-control-6593 isolated 11/11 + the new EditConnectionModal vitest 3/3), typecheck:core clean, all static gates within baseline. Pushed one follow-up commit to your branch with the real Vietnamese translations for the two new keys (repo convention: vi never ships __MISSING__ placeholders). Per-connection maxWaitMs override lands, folding the zai-web exception into the general mechanism. Thank you @maxmad64bis!
Merged after conflict resolution: the 5 conflicting test files were the base-red drains that #11201 already landed on the tip — kept the tip versions; the feature content is untouched. Validated on the combined batch board + this branch: codex-app-server + codex-gpt56-catalog 25/25, typecheck:core clean, docs-counts green (351 providers), provider-consistency 268/351/0. The opt-in codex-app-server transport (JSON-RPC-over-WS, turn/completed-awaited close, Responses SSE bridge) leaves the default codex path untouched. Thank you @arminanton — a 3.4k-line transport with the docs wave and tests to match!
Cherry-picked onto the current tip (authorship preserved), noise stripped. Validated on BOTH runtimes: bun test tests/unit/db-adapters/ 44/44 under the pinned Bun 1.3.14 (native bun:sqlite path), and node --test on the same suite 52 pass / 0 fail / 1 skip (Bun-only adapter skips under Node, as designed). Dockerfile.bun entrypoint now matches the standalone runner shape. Follow-up to #11039. Thank you @rqzbeh!
Cherry-picked the author's cleaned single-commit head onto the current tip. One fix applied pre-merge: the removal migration collided at number 161 with today's config_audit_log migration (#11103) — renumbered to 162_remove_hackclub_provider.sql. Focused tests: remove-hackclub-11118 + provider-metrics-deleted-provider green; check:provider-consistency OK (266/348/0). Provider removal requested by Hack Club maintainers (#11118). Thank you @rqzbeh!
Validated on the combined batch board over release/v3.8.50 tip d91238b7: static gates clean, typecheck:core clean, focused tests green.
Config-audit survives restarts with bounded growth (migration 161 + OR IGNORE seed, retention wired into runAutoCleanup); route cabling deliberately out of scope. Thank you @maxmad64bis!
Validated on the combined batch board over release/v3.8.50 tip d91238b7: static gates clean, typecheck:core clean, focused tests green.
Strict schema + {sanitized, rejected} DB boundary — silent validation degradation now answers 400 with the offending keys. Caller audit done: only the providers write path consumes the sanitizers. Thank you @maxmad64bis!
⭐4 — Suporte de backend nativo Bun + Dockerfile.bun multi-stage + fallback dinâmico de driver SQLite (better-sqlite3 prioritário sob Bun, bun:sqlite fallback; Node preservado) + correção de estabilidade do DAST CI smoke.
Validado a fundo (worktree board sobre tip): bun-support 4/4, typecheck:core limpo, dashboard-typecheck OK (220 dentro do baseline), open-sse-typecheck OK (5 pré-existentes), gate de runtime OK sob Node, changelog-integrity OK, file-size/complexity/cognitive/dead-code OK. Verificado que o driver preserva a cadeia Node/falback conforme AGENTS.md; teste bun-support presente. Baselines de typecheck removidos são ratchet honesto (erros não existem mais).
OBS: destravei 2 base-reds do tip neste turno (push direto 7ffa3ef): movi o changelog fragment da #11050 da seção inválida breaking/ para fixes/, e rebaselinei AddApiKeyModal 1067->1073 (crescimento da #11056). Sem isso a #11039 e o resto da fila ficariam vermelhos.
⭐5 — LIMIT negativo = "sem limite" no SQLite: ?limit=-1 retornava a leaderboard inteira em endpoint management autenticado; ceil por Math.min só no upper. Duas camadas: route rejeita não-inteiro/fora de range com 400 (mesmo contrato de parseListLimit), getTopN clampeia como backstop defense-in-depth + exporta LEADERBOARD_MAX_LIMIT. TDD red→green, 5 casos novos, 84/84 suíte gamification. Fecha #11058.
⭐5 — freeAccessPolicy "strict" opt-in (default off): verifica candidatos de auto-combo contra estado de quota ao vivo + segurança econômica por conexão antes do dispatch (fail-closed — estado desconhecido/stale/incompleto é excluído). Zero mudança de comportamento com o default "off". 82 testes focados, eslint/prettier/typecheck limpos, docs em docs/routing/STRICT_ZERO_COST.md.
⭐5 — Em SQLITE_CORRUPT/pager malformado durante rotação de call-log, pausa novas rotações em vez de retry de DELETE contra arquivo quebrado; /api/db/health reporta integrity_check_failed. Não faz REINDEX automático (inseguro em single-writer live). 4/4 testes novos + suíte irmã verde. Fecha o gap de #10736.
Validado no worktree combinado: mesmos gates + testes focados verdes. Extensão opt-in bem desenhada sobre #10909 (dimensão de uso real via call_logs). CI vermelho é o base-red já rastreado em #9985.
Validado no worktree combinado: mesmos gates + testes focados verdes. Fix bem medido (context window real vs anunciado divergindo por até 24h para modelos sincronizados fora do ciclo). CI vermelho é o base-red já rastreado em #9985.
Validado no worktree combinado: typecheck:core, changelog-integrity, complexity, cognitive-complexity, file-size, lint e testes focados (egress-ip-lock-10880, egress-lock-allowlist-10880, proxy-logs-egress-lookup-10880) todos verdes. Otimização de resiliência bem fundamentada (cooldown de conexões compartilhando IP de egress após 429 do allowlist). CI vermelho é o base-red já rastreado em #9985. Obrigado!
Validado no worktree combinado: typecheck:core, changelog-integrity, complexity, cognitive-complexity, file-size, lint e testes focados (auth-login-route, login-bootstrap-route, feature-flags-settings — corrigi EXPECTED_FEATURE_FLAG_COUNT 51→52 fix-in-place, novo flag adicionado sem atualizar a própria contagem) todos verdes. CI vermelho é o base-red já rastreado em #9985. Obrigado!
Reconciliado com a release (mesmo drift de typecheck-baseline/glm.ts/fetchTimeout.ts/stryker.conf.json que os PRs irmãos) e corrigi o `no-explicit-any` no teste novo (o tipo `ModelCompatOverride` já expõe apiFormat/targetFormat/supportsVision — o cast era desnecessário). Validado: lint limpo, 2/2 testes focados passando. Fix real e bem documentado (persistência de overrides de protocolo por modelo). CI vermelho é o base-red já rastreado em #9985. Obrigado!
Canonical provider id renamed freepik → magnific (Magnific Mystic official API), with a permanent redirect + runtime alias so old freepik/<model> traffic and /dashboard/providers/freepik URLs keep working. Existing provider=freepik connection rows are rewritten to magnific by migration 160.
Closes#10604.
Validated in an isolated worktree boarded onto origin/release/v3.8.50 (0 conflicts, 138 files):
- Focused suite: 54/54 tests pass (magnific-image-handler, provider-validation-image-only, provider-alias-uniqueness, redirects-cli-renames).
- check-file-size, check-changelog-integrity: OK.
- typecheck:core: clean.
- check-complexity / check-cognitive-complexity: OK, both under baseline.
Co-authored-by: RaviTharuma <RaviTharuma@users.noreply.github.com>
Obrigado — follow-up limpo do #10186: MiMoCode foi removido do OmniRoute, mas instalações que o configuraram antes da remoção retêm estado provider-scoped órfão (provider_connections, registered_keys, provider_key_limits, discovery_results, customModels). Migração de retirement segue o padrão explícito já usado para outros providers aposentados, preservando corretamente usage_history/call_logs históricos.
Validação (worktree combinado a partir de origin/release/v3.8.50, 0 conflitos):
- typecheck:core limpo, complexity/cognitive-complexity dentro do baseline
- tests/unit/migration-159-remove-mimocode-provider.test.ts — passando (mimocode + alias mcode removidos, estado de outros providers preservado, idempotência, histórico preservado)
Merged — locally validated together with related cryptiklemur PRs (typecheck:core clean, gates green). Good catch on the phantom usage_logs table. Thanks!
Merged — validated together with a batch of related RaviTharuma PRs in one combined worktree (typecheck:core clean, complexity/file-size/changelog gates green, focused tests passing). Thanks for the contribution!
Merged — validated together with a batch of related maxmad64bis PRs in one combined worktree (typecheck:core clean, complexity/cognitive-complexity/file-size/changelog gates green, focused tests passing). Thanks for the contribution!
Merged — validated together with a batch of related maxmad64bis PRs in one combined worktree (typecheck:core clean, complexity/cognitive-complexity/file-size/changelog gates green, focused tests passing). Thanks for the contribution!
Merged — locally validated (30/30 focused tests: chatcore-codex-account-pool, codex-account-cooldown-write, codex-account-pool, providers-route-codex-account-pool, resilience-explain-codex-account, sse-auth-codex-account-pool; typecheck:core clean; file-size/complexity/cognitive-complexity/changelog gates all green). Merges clean against the current release tip with zero conflicts. Great refactor — extracting persistCodexQuotaState out of chatCore.ts into a proper codexAccount/ module with virtual quota pool isolation is a solid improvement. Thanks!
Merged — locally validated (72/72 focused tests, typecheck:core clean, all static gates green) after resolving base-drift conflicts (catalog.ts cooperative-yield insertion point, modelMetadataRegistry.ts snapshot-param signature). CI's red checks (Unit Tests fast-path shards, Fast Quality Gates, Docs Gates) are confirmed PRE-EXISTING base-red on the pure release tip — reproduced tests/unit/db-driver-bundling-externals.test.ts, tests/unit/model-catalog-runtime-invalidation.test.ts and others failing identically against origin/release/v3.8.50 with zero PR content, unrelated to this change. Thanks for the design and for absorbing #10724's value here — great work on both review rounds!
Merged via merge-train (release/v3.8.50, batch1 2026-08-20) — static gates (typecheck/file-size/complexity/cognitive/changelog) green on the combined tree; test:unit reds observed in the boarded run were verified pre-existing on the pure release tip (unrelated flake), not caused by this PR. Thanks for the contribution!
Merged via merge-train (release/v3.8.50, batch1 2026-08-20) — static gates (typecheck/file-size/complexity/cognitive/changelog) green on the combined tree; test:unit reds observed in the boarded run were verified pre-existing on the pure release tip (unrelated flake), not caused by this PR. Thanks for the contribution!