Repository navigation
typecheck: add a production type ratchet, and pay down 453 -> 272 - #18603
Conversation
|
Two checks are red here, and both are red on Run on a clean worktree of the base commit The same two commands on this branch give the same output, so the failures are
Neither check reads anything this branch changes. I have not touched either of these because they are outside what this PR is for; |
70b667e to
fbf21c4
Compare
|
Follow-up after the latest push.
I tried to fix it and stopped, for reasons worth writing down. The policy file has two lists. So it needs an
So either the catalog entry is wrong about Reverted my attempt; This check fails identically on |
14e9fce to
9032cb0
Compare
Remaining CI red is base drift, not this diffFive checks are failing. Each one traces to a file this PR does not touch, and I verified that per check rather than assuming it.
Evidence for the "not this PR" claim, per row:
Everything that measures this diff is green: I have not touched these four because fixing them means a separate change with its own justification — bumping dependencies for the vuln ratchet, re-recording the provenance audit against a commit that exists, refreshing 96 translated counts, and correcting the SSO script's entry guard. Happy to open that as its own PR if you would rather not fix them on the release branch directly. |
9032cb0 to
0c7348d
Compare
Nothing type-checks this repo's production code. `next build` runs with `typescript.ignoreBuildErrors: true`; the blocking `typecheck:core` gate covers a curated 27-file allowlist; the dashboard and API-route gates each freeze their own existing errors; and the root tsconfig includes `tests/` through `**/*.ts` and cannot finish on an ordinary machine. The production surface between those was unwatched, and 453 diagnostics had accumulated there. tsconfig.build.json narrows the program to shipped code. It finishes in about a minute, which makes it usable as a gate for the first time, and it surfaced three call sites that were wrong rather than merely untyped: - the Cursor login poll route called `syncToCloud()` with no machine id. The function requires it, interpolates it into a request path, and the route had computed the id two lines earlier for the credential save, so every sync POSTed to `/sync/undefined` and failed. - the provider models route passed an outbound guard as a third positional argument to `safeOutboundFetch(url, options)`, which reads `options.guard`. The argument was dropped and the request ran on the default policy. That URL is a string literal, so nothing was reachable by an attacker, and the 17 sibling call sites in the same file already passed it correctly. The policy the caller asked for is now the policy that runs. - `ProviderModalsPanel` passed `copied="extlink"` to a prop that renders only on that value, so the "copied" indicator on the external-link modal never appeared. Those three change behaviour. Everything else is annotations and declarations. `check:build-typecheck` holds the result against a frozen per-(file, code) count baseline. A new or raised pair fails; a lower count asks you to ratchet. `--update` refuses while the live run contains a new or raised pair, so widening the baseline to get green has to be an explicit `--force`. The second escape is suppression. `@ts-nocheck` makes a file report nothing at all, so it is invisible to every diagnostic-based check. Twenty-eight files use it, all without a stated reason, and removing them raises the count by 54, concentrated in token and credential handling. They are frozen by name: adding the directive fails, removing it is always allowed. Getting the detector right meant matching tsc's own rule rather than approximating it, because each approximation missed a different real case. A fixed read window is defeated by a licence banner of the wrong length, since tsc honours the directive anywhere before the first statement. Judging only the first textual occurrence is defeated by a comment that mentions the pragma above the real directive; `src/lib/tokenHealthCheckCursor.ts` already reads "no @ts-nocheck" at line 10. Treating `#!` as a statement misses the 20 files under `scripts/` that start with a shebang. And excluding `\r` from the terminators misses every directive on a CRLF checkout: rewriting the frozen files with CRLF made the scan find none of them while tsc honoured all of them, and `.gitattributes` pins only `*.sh`. The detector now walks the file's leading trivia the way the compiler does: skip whitespace and block comments, accept only a single-line comment matching the pragma, terminated by whitespace, a colon, or end of line. `@ts-ignore` and `@ts-expect-error` are per-line, so they are counted per file against `config/quality/ts-suppressions-baseline.json` rather than frozen by name. One added comment line removes a diagnostic, and without this the gate read that as progress. tsc honours the pragma in four shapes (leading `//`, trailing after code, `/* */`, `/** */`) and all four are counted. `--update` did not run the validation verify ran, so a run verify rejected could rewrite the baseline and then pass, with the failure message suggesting exactly that. Both paths share one function now. The "carries baselined errors while silencing the compiler" check was asking the live diagnostics, which is precisely the list an opted-out file leaves, so the intersection was empty by construction. The scan set was a hand-kept list of five directories, already drifted from the program it described: `electron/**/*.d.ts` is in the include but was not in the list, and `scripts/check/*.ts` imports files under `tests/` that the list skipped by name. It comes from `tsc --listFilesOnly` now, and an empty result fails closed instead of reporting a clean run. That surfaced a related problem: `src/lib/source.ts` imports the fumadocs collection in `.source/`, which is generated and gitignored, so a checkout that has never run `next build` reports six more errors than one that has. The gate regenerates the collection itself, so the verdict depends on the tree rather than on build history. Shrinking the program was the cheapest escape and needed no directive: add a directory to `exclude` or turn a check off and the diagnostics vanish while the gate reports an improvement. The include and exclude lists and the full compiler option set are frozen in the baseline, so that is a failure rather than a shrink. The file count is recorded but is not a drift signal, because a quarter of commits add or remove a source file and failing on that would make the gate something people route around. The API-route gate had none of these closers. It is a blocking CI gate whose whole `--update` path was `writeBaseline(live); exit 0`, and its baseline had frozen 283 errors against 180 live, which is 103 units of headroom that would have absorbed a new error without a word. It now shares `scripts/check/ratchet.mjs` with the build gate, gets the same four guards, and its baseline is tightened to the 180 that actually exist. The extraction cut `check-build-typecheck.mjs` from 529 lines to 313. `--force` is now two flags. Accepting a new counted error and granting a file permanent silence are different decisions, and one keystroke should not make both: `--force-regressions` banks a counted error, `--force-nocheck` accepts a suppression. A bare `--force` is rejected rather than silently degraded to a plain `--update`. `relax-baselines.mjs` deliberately does not list `build-typecheck-baseline.json`. That script loosens baselines by 20% to preserve headroom from the 2026-08-30 velocity phase; this baseline was frozen afterwards at raw counts, so loosening it would hand out new headroom rather than preserve old. Thirteen `as unknown as UsageRows` casts in the analytics route erased the mismatch they were hiding: the concrete row interfaces have no index signature, so they are not assignable where `Record<string, unknown>` is expected. The three receivers now declare `object` and widen once internally, which is honest because they genuinely read both camelCase and snakeCase spellings off the same row. The casts are gone, the route reports the same diagnostics as before, and the now-unused `UsageRows` alias is deleted. The images/edits route carried eighteen diagnostics from one cause: it reads `allRateLimited`, `retryAfter` and `retryAfterHuman` off a credential resolver that returns a fifteen-member union, so those fields were not visible on the type at all. Its four call sites now narrow to a local shape, which is what the two call sites above them already did. A provider result union whose members both declare `success: boolean` is discriminated on the presence of `data` instead, because a boolean carries no information. Three call sites hand the resolved credentials to handlers that only read `apiKey`/`accessToken`, so they now say exactly that. The build baseline ratchets from 272 to 254. Rebased onto the current release tip, which brought in two unrelated things: generated agent skill files that had drifted from their catalog, and five type errors in the new Entra SSO code where one union is returned where another is declared. Those failures are rebuilt explicitly, because `strict` is off in `tsconfig.build.json` and discriminating on `ok` does not narrow there. Two of the largest `@ts-nocheck` files are compiled again: `tokenHealthCheck.ts` and `bedrock.ts`, forty-four diagnostics between them that the directive had been hiding from every gate including tsc itself. tokenHealthCheck's were five values read out of untyped bags — the refresh circuit, the scheduler singleton's `initTimeout`, a rate-limited timestamp, a copilot probe result, the local refresh result type — plus one call that omitted the logger slot. bedrock's were all objects built up field by field and therefore inferred as `{}`; they carry the SDK's own input types now, which is also why the payload it hands to `ConverseCommand` had been a plain Record. The `@ts-nocheck` list drops from 28 files to 26. Build diagnostics stay at 254, because both files were silent before and clean now. The `@ts-nocheck` list drops from 28 files to 18. Stripping the directive from all 26 remaining files showed what it was hiding: twenty-three produced zero build diagnostics, so removing it looked free. It is not. `typecheck:core` compiles a stricter program, and sixteen of those files surface around 120 implicit-any errors there. They are back behind the directive, and that gap is the finding worth keeping: the build program's narrower options make a file look clean while the core program has never seen it. Ten files are genuinely clean now. `tokenHealthCheckCopilot` and the tokenRefresh provider modules had nothing hidden. `migrations.ts` and `circuitBreaker.ts` keep their fixes and their directive, because their only core-gate complaint is a declaration the repo itself owns: `yazl` ships no types and the core file list does not include the hand-written `declare module`. `scanNoCheckFiles` skips `.source/` now. fumadocs regenerates that tree every run, so a directive inside it describes no file anyone maintains. `QUALITY_GATES.md` states the difference between the two typecheck programs next to their gate table. A reader who finds a file clean under the build gate has no way to tell that the strict program never agreed, and that gap is what let the `@ts-nocheck` list sit at 28 files while every gate looked green. Two provider docs gain the frontmatter fumadocs requires. Both have been in the tree without it, and the strict docs job compiles every file `source.config.ts` matches, so they were breaking that job on the base as well. The gate fixtures answer the program probe and provide the compiler's config parser, because the api gate resolves the program before comparing counts; a stub that only simulates diagnostics makes the run prove nothing. The `--update` assertion checks the diagnostic entries instead of requiring the whole file to be empty, since the baseline now records the program fingerprint alongside them. All four typecheck ratchets run with `--incremental false`. A verdict that depends on which `.tsbuildinfo` happened to be on disk is not a verdict. Gates: typecheck:core, typecheck:noimplicit:core, api, dashboard, open-sse, build and the gate manifest all pass. Dashboard baseline tightened 270 -> 96 with zero added and zero raised pairs. The gate's own suite covers 35 cases, each verified by reverting the mechanism and watching it fail. One thing came along because it blocks everything else: `check:agent-skills-sync` fails on release/v3.8.53 itself, because the generator finds three skills out of date (omni-settings, omni-resilience, omni-inference) and exits 2 under CI. A red `Change Classification` skips every gate after it, including the one this PR adds, so the regenerated docs are included. They are the generator's own output from the current catalog, covering routes that already shipped. The other red check on the base, `check:free-catalog-evidence`, is not fixed here. It wants evidence for `tokenharbor/claude-haiku-5.5:free`, and the policy's legacy list is a frozen seed that refuses to grow, so the only honest fix is a real source record from someone who verified it. `BedrockClientLike.send` was a free generic: `send<T = unknown>(command, opts)` returning `Promise<T>`. That let the executor name whatever it expected at each call site, but it also let an injected client promise a shape the executor cannot consume, and the SDK client only satisfied it by inference. It now declares the contract the executor actually reads, `BedrockClientOutput`, and takes the two command types explicitly. The SDK client stays assignable; injected clients are checked against real fields. A test extracts those interfaces from the source, typechecks them in a fixture next to the real SDK import, and requires zero diagnostics for both the SDK client and two concrete injected clients. Signed-off-by: Minxi Hou <houminxi@gmail.com>
b009082 to
85d9205
Compare
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…uard, fix stale --force hints Adds regression tests for the two behaviour fixes in this PR (syncToCloud receives the machine id, Inner.ai models fetch carries the outbound guard), points the gate refusal messages at --force-regressions/--force-nocheck, and adds the changelog fragment. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…rging the release tip Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
4eb994d
into
cheaper-inference:release/v3.8.53
… Kit (#22) * docs(ci): record the Team plan, the janitor ceiling of 8 and the hosted-only test lane in RUNNER_BOX (#18456) Records the 2026-10-28 state of the runner box in docs/ops/RUNNER_BOX.md: Team plan (60 hosted jobs), janitor ceiling 8, five OmniRoute listeners (113-7 also carries omni-build, 113-3/-4/-8 deleted), and the vars.USE_VPS_TEST_RUNNER rule (same-repo pull_request only, off) with the measurement that turned it off. The 66 mirrors and .i18n-state.json come from scripts/i18n/run-translation.mjs (record/replay against a local backend). * feat(i18n): Google fallback and quota circuit breaker for every translation entry point (#18461) * fix(docs): sync the migration and provider counts to the live tree (base-red #17219) (#18476) * feat(providers): extend expiry-first account routing (#16352) * feat(api): serve Gemini-native /v1beta routes on the API-only port (#16745) Co-authored-by: Muhammad Usama <55662931+MuhammadUsamaMX@users.noreply.github.com> * feat(dashboard): per-step Test button in the combo create/edit modal (#16748) Co-authored-by: Erwan Novianto <smserwan@gmail.com> * feat(dashboard): hide/show models across providers from the Models catalog (#16749) Co-authored-by: Muhammad Usama <55662931+MuhammadUsamaMX@users.noreply.github.com> * fix(usage): enforce pending-request byte ceiling on all mutation paths (#17282) Co-authored-by: turbolego <turbolego@gmail.com> * perf: settings/combo read caches, async fs routes, bounded limiter settings (#17304) Co-authored-by: Mayank Jaiswal <mayankjaiswal1707@gmail.com> * fix(providers): align chatplayground with the current web chat API (#17312) * fix(release): list the three covering tests in stryker tap.testFiles (#18485) Refs #17219 * fix(release): open-sse typecheck and README diagram counts (377) on release/v3.8.53 (#18472) Refs #17219 * feat(search): support Exa 3.0 lite pricing and field set (#17394) Co-authored-by: Praveen K Palaniswamy <Praveen.Palaniswamy@gmail.com> * fix(catalog): keep operator-defined custom models on curated providers (#18018) * fix(sse): preserve harness tool history in Codex app-server (#18105) Co-authored-by: Anton Shilin <coder.root@gmail.com> * fix(sse): strip learned-only effort suffix back to the base model (#18131) * fix(combo): keep durable exhaustion across set retries (#18133) * fix(antigravity): stop three retry layers from hammering Cloud Code with a refused request (#18140) Co-authored-by: Wital <witalo_rocha@hotmail.com> * fix(build): skip the webpack persistent cache in production builds (#18141) * fix(sse): copy-on-write in the JSON-schema fallbacks and skip non-JSON response_format (#18241) * fix(i18n): protect inline HTML in the Google engine and guard HTML structure in the output check (#18486) * ci(i18n): scheduled post-merge mirror refresh (LLM first, Google last resort) (#18489) * fix(sse): withhold tool calls cut mid-arguments in a truncated buffered stream (#18482) * feat(search): price Exa extra results and summaries like Exa bills them (#17396) Co-authored-by: Praveen K Palaniswamy <Praveen.Palaniswamy@gmail.com> * fix(usage): bound pending request retention (#17405) Co-authored-by: Hummern <hummernkloa@gmail.com> * fix(combo): fail over from a target whose buffered stream was cut before its terminal signal (#18490) * feat(search): record Tavily advanced search at 2 credits (#17902) Co-authored-by: Praveen K Palaniswamy <Praveen.Palaniswamy@gmail.com> * feat(search): record Linkup deep search at $0.05 (#17903) Co-authored-by: Praveen K Palaniswamy <Praveen.Palaniswamy@gmail.com> * feat(search): record Firecrawl search per block of 10 results (#17904) Co-authored-by: Praveen K Palaniswamy <Praveen.Palaniswamy@gmail.com> * fix(release): clear the 10-28 typecheck, boundary, stryker, route-map and i18n reds on release/v3.8.53 (#18515) Refs #17219 * fix(i18n): open the LLM circuit after three consecutive failures, not only on quota (#18474) * fix(dashboard): monospace code text and a non-Latin script fallback after the kit 0.0.66 bump (#18477) * fix(dashboard): bring the team costs, combo step test and catalog toggle onto the kit components (#18487) * fix(api): let operators limit the Telegram bot to allowlisted senders (#18475) A valid Telegram signature (webhook secret_token or Mini App initData) proves an update came from Telegram, not that its sender may use this instance. TELEGRAM_USER_ALLOWLIST_ENABLED=true now serves only the numeric user ids in TELEGRAM_ALLOWED_USER_IDS: unlisted Mini App users get 403 and webhook messages from unlisted senders are acknowledged and dropped. The check uses the sender (message.from.id), so group chats are covered; an empty list serves nobody; misconfiguration is logged once without echoing ids. Off by default. Co-authored-by: HouMinXi <19586012+HouMinXi@users.noreply.github.com> * fix(api): stop keyless cross-origin reads on the client API and inference WebSockets (#18512) HTTP: on a keyless install (REQUIRE_API_KEY=false) any Authorization, x-api-key or x-goog-api-key header, valid or not, made client-API routes echo the request Origin while serving the request as anonymous. The allow path now relaxes CLIENT_API CORS only for a non-anonymous subject; route-level 401s that refuse a presented key still echo Origin (Vary: Origin, no credentials header) so browser clients can read them (#5242). WebSocket: browsers do not apply CORS to WebSockets and the /v1/responses, /v1/ws and /api/v1/ws handshakes never read Origin. They now admit no-Origin clients, CORS-allowlisted origins, the gateway's own public origin and handshakes with a valid API key; everything else, null included, gets 403 ws_origin_forbidden. The bridge upgrades only when the route answers originChecked: true. /v1/responses now enforces REQUIRE_API_KEY. The service worker also bypasses the client-API aliases. CORS and PWA guide mirrors refreshed. Co-authored-by: HouMinXi <19586012+HouMinXi@users.noreply.github.com> * fix(release): clear the remaining release/v3.8.53 base-reds — namespaced combo lookup, curated imported rows, build-scope ceiling (#18516) * fix(sse): resolve client-namespaced combos through the cached name lookup #17304 replaced the exact-name combo lookups in getCombo() with getCachedComboByName and dropped the getComboByName import, but missed the third call site in getComboByClientNamespacedName (#16493). Any model id with a "/" that is not a provider pin or catalog id then threw "ReferenceError: getComboByName is not defined" inside getComboForModel, which broke reasoning routing for unknown models and the client-namespace combo resolution. Fixes reasoning-routing-decision-guards ("an unknown model with no rules is also a clean pass-through") and 5 cases of combo-prefixed-name-resolve. * fix(models): keep sync-imported custom rows off curated-only providers #18018 made custom models listable on curated-only providers so a model added through "Add Custom Model" can be routed. Its stated scope is the operator's own rows ("Discovery behaviour is unchanged ... only the operator's own rows are kept"), but the three read paths kept every custom row, including rows whose source is imported/api-sync/auto-sync. On a provider with no upstream catalog such a row is a stale leftover of a retired discovery path: #8451 removed exactly those obsolete Z.ai Web ids (they 404 upstream), and zai-web-models-discovery-7678 pins that. The provider listing merge, GET /api/providers/[id]/models and /v1/models now drop discovery-imported custom rows on curated providers through one helper (isDiscoveryImportedCustomSource); operator rows keep flowing. zai-web-models-discovery-7678 now also expects the manual row, which #18018 made listable on purpose. New cases pin the imported-row exclusion in the listing merge and in /v1/models. * chore(changelog): drop the duplicate namespaced-combo fragment (#18514 carries it) The client-namespaced combo lookup fix is the same one-line change as #18514, which already ships its changelog fragment. Refs #17219 * chore(quality): raise the build-scope ceiling to 13500 in-scope files The release branch reached 12267 in-scope .ts/.tsx/.js/.jsx files through legitimate test growth (tests/ went 7841 -> 8296 files since 10-21), so check:build-scope failed on every PR although nothing was leaking. A leaked worktree or vendored checkout adds roughly a full tree (~12k files), which 13500 still catches. Refs #17219 * chore(dashboard): sync the CI UI Kit to 0.0.79 and keep tracking the newest release (#18504) * docs(i18n): refresh the changed ENVIRONMENT sections in 66 locales (#18524) * feat(antigravity): add Gemini 3.8 Flash tiers and update client fallbacks (#12499) Co-authored-by: Abhishek Chhetri <abhishekchhetri@example.com> * feat(oauth): GitHub Copilot capability-driven account integrationClaude/GitHub copilot integration 748ebe (#12833) * feat(dashboard): size dialogs to 70% of the viewport (#14091) Co-authored-by: Felipe Almeman <felipe@aireset.com.br> * feat(opencode): sanitize the OpenCode PR 4145 fingerprint (#14142) * feat(resilience): recover queued quota-failed sessions (#14981) (#14982) * feat(providers): wire claude-haiku-5-5 across catalogs, pricing, and fallbacks (#16159) Co-authored-by: Tuan Dinh <tuan.dinh.truong@sap.com> * feat(models-health): report whether reasoning_effort none was honored per model (#16253) * feat(providers): bounded-turn tool-call support for the ChatGPT Web clean-room adapter (#14948) Co-authored-by: Arash <arash.ashrafi@gmail.com> * feat(oauth): add Freebuff browser login to the freebuff provider (#15336) (#15343) * feat(muse-code): consolidate open Muse Code PRs (#15234, #14138, #13634, #14267, #12687) (#15521) Co-authored-by: mdc2122 <mdc2122@users.noreply.github.com> Co-authored-by: SIGTERM-015 <SIGTERM-015@users.noreply.github.com> Co-authored-by: KSonny4 <KSonny4@users.noreply.github.com> Co-authored-by: caniko <caniko@users.noreply.github.com> Co-authored-by: Chewji9875 <Chewji9875@users.noreply.github.com> * feat(dashboard): show which combos use a model on the provider detail page (#16307) Co-authored-by: Farshad <asadpoor.f@gmail.com> * feat(pii): GDPR + POPIA PII patterns with validators (#16461) Co-authored-by: Wayne <wayne@local> * feat(affinity): optional Redis store for shared session-to-account affinity (#16569) * feat(oauth): opt-in passive token refresh for Codex replicas (#16577) * feat: improve adaptive routing and model health monitoring (#16746) * feat(providers): allow manual vision overrides for synced models (#16794) * fix(mcp): ignore client _meta scopes for stdio callers (#17112) * fix(xai): flatten Codex namespace tools for /v1/responses; no account cooldown on 422 shape errors (#17134) Co-authored-by: özcan Yaman <ozc.yaman@gmail.com> * perf(provider-stats): bound provider-stats history to a 7-day window and cache the payload (#17227) * fix(dashboard): decode percent-encoded combo route params for auto/* control center (#17271) (#17272) * fix(desktop): publish and verify indexed optional runtime packs (#17338) * refactor(a2a): share agent discovery metadata (#17357) Co-authored-by: Jan Leon <jan@leoncode.de> * fix: require reasoning_content presence for DeepSeek and align Grok 4.7 context and effort tiers (#17388) Co-authored-by: Felipe Fidelix <felipe@fdx.is> * fix(providers): isolate agy/antigravity hiddenModelGate and clear compat overrides on model reset (#17398) (#17400) * fix(providers): rotate the deprecated OpenCode Zen mimo-v2.5-free id to v2.6 flash (#17472) (#17788) Co-authored-by: vincent <webmaster@palmit.com.au> * feat(sse): follow the published OpenCode endpoint and client headers for keyed requests (#17864) * fix(tls): follow the newest wreq-js browser profile in the web providers (#17869) * fix(sse): match the native Antigravity CLI wire image (#17913) * fix(docker): pin node 26.12.1 / bun 1.4.4 so images reject the compromised eMudhra CAs (security) (#17927) Co-authored-by: Markus Hartung <mail@hartmark.se> * feat(db): maintain configurable SQLite planner statistics (#17936) * fix(translator): ensure all assistant tool_calls are answered in fixMissingToolResponses (#17946) (#17947) Co-authored-by: Felipe Fidelix <felipe@fdx.is> * fix(dev): avoid the macOS dev-startup EBADF and keep reasoning out of combo test output (#17955) * feat(combo): global outputLimitAdvisory setting and a per target context window check (#17958) * fix(docker): split clientless CLI runtime from Docker tooling (#17972) Co-authored-by: Sean P. Ford <sean@seanford.com> * fix(providers): preserve Gemini function tools with native web search (#18020) * fix(db): preserve utilization bucket timezone (#18083) * fix(stream): preserve queued chunks on 6 abortStreamFailure sites (#18094) * fix(sse): refuse non-JSON data lines in stream readiness and content checks (#18095) * fix(db): don't skip half-applied proxy timing migration 194 (#18096) * fix(sse): fold camel-case reasoning effort into the canonical field (#18117) * fix(providers): preserve Codex reasoning controls and expose Muse subscription metadata (#18124) Co-authored-by: Aldo <github@aldo.pw> * fix(sse): local backends answer 499 while draining instead of 502 (#18134) Co-authored-by: roomhackerfrom100 <megamen932@gmai.com> * fix(compression): keep the tail of a truncated lite tool result (#18138) * fix(zcode): stream native Anthropic responses to clients (#18190) Co-authored-by: roomhackerfrom100 <megamen932@gmai.com> * fix(quota): recognize international Kimi Coding usage endpoints (#18180) (#18224) Co-authored-by: Nabi Bukhsh <nabibuksh.baloch01@gmail.com> * feat(dashboard): assign catalog models and combos to API keys (#14890) Co-authored-by: Fouad Salkini <fouad@wecansync.com> * feat(ci): validate protection domains for admission jobs (#16142) * feat(dashboard): add inline toggle and bulk disable/enable for no-auth providers (#16553) * feat(cli-tools): add OpenClaude setup guide card (#16844) Co-authored-by: Nguyen Thanh Dat <ntdat812@gmail.com> * feat(api): opt-in "expose combos only" setting for /v1/models (#16846) Co-authored-by: snower <sujian199@gmail.com> * feat(mcp): add a deep research tool that is off by default (#17317) * fix(opencode): map custom-provider catalog identities to public prefixes (#17369) * feat(oauth): import Antigravity Manager account exports (#15746) * feat(logs): distinguish generation rate from end-to-end throughput (#17847) * feat(api): CLIProxyAPI management usage compatibility endpoints (#17999) Co-authored-by: Rahul Bansal <rtrrahulbansal@gmail.com> * feat(antigravity): add Gemini 4 Argon weekly quota, dual-resolver preflight, and 404 short-circuit (#18026) * fix(zcode): preserve exact native Coding Plan quota refusals (#18118) Co-authored-by: roomhackerfrom100 <megamen932@gmai.com> * feat(opencode-plugin-v2): publish one catalog branch with prefix wildcard and hide every combo (#18135) * fix(combo): test all model health targets without a cumulative deadline (#18231) (#18238) * fix(codex): distinguish transient capacity 429 from quota cooldown (#18221) (#18239) * feat(oauth): route Grok Build image, video and audio (#15305) * feat(codebuddy-cn): sync authenticated live model catalog (#17916) * feat(providers): add MiniMax M3.1 Flash model (#18110) * fix(build): select webpack automatically on low-memory builders (#18184) (#18242) * fix(resilience): keep combos routable after transient credential probe errors (#18037) (#18243) * fix(claude): keep model-credit 429 cooldown scoped to the affected model (#18058) (#18245) * feat(providers): add Token Harbor API-key provider (#16315) Co-authored-by: GitHub Actions <github-actions@github.com> * feat(cli-tools): add current Pi setup flow (#16381) Co-authored-by: Arash <arash.ashrafi@gmail.com> * feat(api): configurable unpriced-usage budget policy + admin notice (#14604) (#14608) * fix(i18n): escape the Maltese apostrophe in providers.usedInComboTooltip (base-red) (#18545) * fix(usage): release terminal pending attempts when completion bookkeeping fails (#18217) Co-authored-by: AiCapitan357 <ai-capitan-357@proton.me> * feat(providers): add Runcrate (#18061) * i18n: complete feature-flag definitions for all 66 locales, fix zh-CN/zh-TW mistranslations (#17960) * feat(i18n): wire hardcoded dashboard strings into message catalogs (#17987) * feat(providers): add Gisoo (OpenAI-compatible) (#18112) Co-authored-by: Nirupam Bhowmick <48842933+heydryft@users.noreply.github.com> * feat(providers): dashboard control for the advertised CLI client version (#14817) Co-authored-by: Abhishek Divekar <adivekar@utexas.edu> * feat(ui): add remove error models button in combo test results, default autoHideFailed, and fix db import crash (#14944) * feat(core-config): ingest multiple feeds per subscription with per-source isolation (#16439) * feat(db): prune expired semantic cache rows in bounded batches (#17939) * feat(compression): let compression combos select output styles (#18107) * feat(api): authenticate Claude Code to /v1/* with Entra ID SSO (#14665) Co-authored-by: Benjamin <aronsson.benjamin@gmail.com> * feat(services): add sing-box supervisor installer and tproxy integration (#12962) * fix(release): clear the release/v3.8.53 base-reds from the merge campaign (#18625) * ci: tune CodeRabbit for the open-source rate limit and review noise (#18458) Tunes CodeRabbit for the open-source rate limit: one review per PR, bot PRs ignored, slop labelling on, less walkthrough noise. Evidence: focused tests passed on a combined board (no test file, config only); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * fix(network): refuse reserved 240.0.0.0/4 and broadcast in the SSRF guard (#18415) The SSRF guard refuses the reserved 240.0.0.0/4 block and the broadcast address. Evidence: focused tests passed on a combined board (private-host-reserved-ranges.test.ts, upstream-proxy-host-spelling.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * fix(api): continue web fetch after Jina balance exhaustion (#18455) Web fetch continues to the next provider after Jina reports an exhausted balance. Evidence: focused tests passed on a combined board (web-fetch-quota-fallback.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 Fixes #18449 * fix(sse): send budget_tokens with enabled thinking on the GLM Anthropic transport (#18378) Enabled thinking on the GLM Anthropic transport always carries `budget_tokens`, keeping a client budget and deriving a missing one from the effort tier, clamped to max_tokens. Evidence: focused tests passed on a combined board (glm-anthropic-thinking-budget-tokens.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * fix(sse): keep chat heartbeats from initializing tool messages (#18468) Chat Completions startup and periodic heartbeats are emitted without application choices, so LangChain keeps aggregating tool calls and the upstream message identity survives. Evidence: focused tests passed on a combined board (chat-keepalive-no-choice.test.ts, early-stream-keepalive.test.ts, sse-heartbeat*.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * fix(sse): route the Codex, Muse, Z Code and Entra token fingerprints through the opaque helper (CodeQL #1195 #1199 #1201 #1207) (#18613) Routes the Codex, Muse, Z Code and Entra token fingerprints through `opaqueTokenFingerprint()`; outputs stay byte-identical. Evidence: focused tests passed on a combined board (opaque-token-fingerprint.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * fix(deps): raise the @hono/node-server override to ^2.1.3 (#18615) Raises the `@hono/node-server` override to ^2.1.3, resolving to 2.1.5, for the `serveStatic` double path decoding fix. Evidence: focused tests passed on a combined board (no test file, dependency override only; check-deps OK); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * fix(sse): keep Claude Code classifier turns out of Memory (#18622) Claude Code security-classifier turns no longer read from or write to Memory. Evidence: focused tests passed on a combined board (chatcore-sanitization.test.ts, no-memory-header.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * chore(providers): add opt-in model sync phase timing (#18466) Adds opt-in `OMNIROUTE_MODEL_SYNC_TIMINGS=1` phase timings for model sync, as evidence for the latency investigation in #18335; normal sync behavior is unchanged. Evidence: focused tests passed on a combined board (sync-models-phase-timings.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * feat(providers): page through Cloudflare Workers AI model discovery and skip non-chat models (#18321) Cloudflare Workers AI model discovery pages through every result and skips non-chat models. Evidence: focused tests passed on a combined board (cloudflare-model-discovery-pagination.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * feat(api): expose per-limit capability provenance via /api/models?withLimits=1 (#18327) `GET /api/models?withLimits=1` exposes each token limit together with the source that supplied it; the parameter is opt-in and Zod-validated. Evidence: focused tests passed on a combined board (model-limit-provenance.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * fix(api): decode compressed JSON request bodies at chat admission (#18264) Chat admission decodes compressed JSON bodies once for every admitted route, with the expanded size capped by the existing hard limit and no zlib error echoed. Evidence: focused tests passed on a combined board (request-body-content-encoding.test.ts, responses-route-compressed-body.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * fix(sse): preserve reasoning fields through streaming redaction (#18363) Streaming redaction keeps content, reasoning and tool-argument fields in separate buffers, emits only buffered tails and holds raw credential fragments until a safe boundary. Evidence: focused tests passed on a combined board (streaming-credential-*.test.ts, streaming-reasoning-fields-17291.test.ts, streaming-redaction-chain-reasoning-17291.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * fix(ci): reject incomplete release workflow audits (#17412) The Release-Green observer and its report verifier treat a missing or broken workflow scanner as incomplete evidence instead of nonblocking drift. Evidence: focused tests passed on a combined board (build/release-green-workflow-evidence.test.ts); lint, typecheck:core and check-deps OK; open-sse-typecheck OK; api-typecheck reports only errors in files this batch does not touch, reproduced on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * chore(dashboard): sync the vendored CI UI Kit to 0.0.80 (#18698) * feat(api): publish readable model display names on /v1/models (#18354) `/v1/models` publishes readable `display_name` values, shared with the Crush and OpenClaw setup routes. Evidence: focused tests passed (model-display-name, v1-models-registry-names, cli-tools-model-display-names); lint, typecheck:core, check-deps and open-sse-typecheck OK; api-typecheck reports only the two errors in availabilityRouterFilters.ts and cliTools.ts that reproduce on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 Co-authored-by: asterxsk <112053934+asterxsk@users.noreply.github.com> * fix(translator): keep Chat Completions custom tools when routing to Claude (#18314) The OpenAI to Claude request translator unwraps Chat Completions custom tools, which were silently dropped because the name was read off the wrapper. Evidence: focused tests passed (openai-to-claude-custom-tool-4938); lint, typecheck:core, check-deps and open-sse-typecheck OK; api-typecheck reports only the two errors in availabilityRouterFilters.ts and cliTools.ts that reproduce on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 Co-authored-by: gebclogic <73856846+gebclogic@users.noreply.github.com> * fix(dashboard): dispose compression save callbacks on unmount (#17850) The compression panel disposes its saved-status timer and skips late state updates after unmount. Evidence: focused test passed (compressionPanelLifecycle); headless Chromium click-through on a throwaway DATA_DIR: toggled a setting, left the page before the timer fired, no page error and the change persisted; lint, typecheck:core, check-deps and open-sse-typecheck OK; api-typecheck reports only the two errors in availabilityRouterFilters.ts and cliTools.ts that reproduce on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * fix(dashboard): validate OAuth URLs and restore shared type contracts (#18457) The OAuth modal rejects a non-string `authUrl` with a visible error and shared dashboard type contracts are restored. Evidence: focused test passed (oauth-response-contracts); headless Chromium click-through on a throwaway DATA_DIR: with `authUrl: 123` stubbed on the OAuth routes the modal shows the connection-failed state and offers retry; lint, typecheck:core, check-deps and open-sse-typecheck OK; api-typecheck reports only the two errors in availabilityRouterFilters.ts and cliTools.ts that reproduce on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * feat(dashboard): animate the analytics overview counters on change (#18340) The analytics overview counters animate when their value changes. Evidence: focused test passed (animated-number); headless Chromium click-through on a throwaway DATA_DIR: with a stubbed summary the Total Tokens card went 1.0K, 2.4M, 5.0M after a range change; lint, typecheck:core, check-deps and open-sse-typecheck OK; api-typecheck reports only the two errors in availabilityRouterFilters.ts and cliTools.ts that reproduce on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 Co-authored-by: F0Rextasy <99847357+F0Rextasy@users.noreply.github.com> * fix(providers): preserve existing prefixes without active built-ins (#17339) An existing compatible node keeps its reserved prefix while the live built-in has no active connection; collisions surface as a derived `prefix_shadowed` diagnostic. Evidence: focused tests passed (provider-prefix-grandfather-17278, custom-provider-prefix-shadowing-11943, provider-connection-status, image-compat-node-alias-shadow); headless Chromium click-through on a throwaway DATA_DIR: the connection row rendered a stubbed diagnostic and a real connection reported none; lint, typecheck:core, check-deps and open-sse-typecheck OK; api-typecheck reports only the two errors in availabilityRouterFilters.ts and cliTools.ts that reproduce on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 * feat(combos): export/import combos as a standalone, secret-free JSON file (#16747) Combos export and import as a standalone JSON file without credentials, with merge and replace modes. Evidence: focused tests passed (combos-export-import, combo-header-actions-import); headless Chromium click-through on a throwaway DATA_DIR: exported a combo with no secret-like key, rejected an invalid file, merged without duplicating a name, and replace left only the file's combos; lint, typecheck:core, check-deps and open-sse-typecheck OK; api-typecheck reports only the two errors in availabilityRouterFilters.ts and cliTools.ts that reproduce on the pure tip; file-size OK; changelog integrity OK against origin/release/v3.8.53. ⚠️ base-red inherited: #17219 Co-authored-by: Alvian Rahman Hanif <alvian.hanif@pasarpolis.com> * fix(release): clear the remaining base-reds on release/v3.8.53 (docs counts, SSO entry guard, API diagnostics, vuln ratchet) (#18658) Clears the remaining base-reds tracked in #17219 except the Release-Green package ceiling (#18693). - docs counts and mirrors (providers, migrations), generated skill sync - SSO script direct-run guard, API route typecheck fixes, catalog schema - provider asset provenance, node-forge vulnerability ratchet, mutation mapping - model sync: env documentation and an explicit audit sink for the error-helper gate - reload-timer isolation in two dashboard tests Refs #17219 * fix(release): raise the Release-Green package ceiling and clear three guards (#18693) - Release-Green package lane ceiling goes from 20 to 40 min: next build was killed at 20 min on an idle runner on every scheduled run - dashboard-kit-sweep: mark the hidden combo import file input as a kit exception (#16747) - hard-session-lease-bypass-inventory: classify the combo import connection read as class C (#16747) - deprecated-provider-banner-13067: bring providers/page.tsx back to its 1989-line freeze after #17278, without changing the pin Refs #17219 * feat(resilience): per-provider rate-limit retry delay override (#16741) Adds a per-provider override for the rate-limit retry delay, with a dashboard selector on the provider page and documentation in the resilience guide. Port of upstream decolua/9router #2895 by @MuhammadUsamaMX. * fix(thinking): resolve "latest assistant message cannot be modified" 400s — fabricated placeholders + cross-org signature replay (#17324) (#18102) Fixes the Anthropic 400 "thinking blocks in the latest assistant message cannot be modified" on multi-turn conversations. - Stop fabricating redacted_thinking on adaptive turns; the placeholder stays only for manual extended thinking - Bind signed-thinking continuity to the serving connection - One-shot recovery for the latest assistant message, from #17344, gated on thinking.type so manual extended thinking stays safe - THINKING_SIGNATURE diagnostics event Refs #17324 Co-authored-by: Nick Carter <nick@nickcarter.dev> * test(cli): resolve repro-9156 test paths with fileURLToPath so they work on Windows (#18646) Resolve repro-9156 test paths with fileURLToPath so they work on Windows. Evidence: focused tests on the combined board 62/62; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. * test(rate-limit): close the SQLite handle before removing the learned-cap temp dir (#18647) Close the SQLite handle before removing the learned-cap temp dir. Evidence: focused tests on the combined board 62/62; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. * test(cli): isolate APPDATA in cli-tray test so Windows never sees the real Startup folder (#18645) Isolate APPDATA in cli-tray test so Windows never sees the real Startup folder. Evidence: focused tests on the combined board 62/62; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. * docs(resilience): document saved-settings precedence over resilience env toggles (#18608) (#18617) Document saved-settings precedence over resilience env toggles. Evidence: focused tests on the combined board 62/62; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. Closes #18608 * fix(providers): add prompt-cache breakpoints for the Anthropic API-key provider (#18532) Add prompt-cache breakpoints for the Anthropic API-key provider. Evidence: focused tests on the combined board 62/62; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. Closes #18531 * fix(search): keep every Exa highlight in provider_raw (#18109) (#18282) Keep every Exa highlight in provider_raw. Evidence: focused tests on the combined board 62/62; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. * fix(release): import the numeric helpers from the engine, not the src re-export (boundary 778 → 768) (#18627) Import the numeric helpers from the engine, not the src re-export (boundary 778 → 768). Evidence: focused tests on the combined board 62/62; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. * fix(cloud-agent): keep Jules creation timestamps consistent (#18681) Keep Jules creation timestamps consistent. Evidence: focused tests on the combined board 62/62; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. * fix(build): use name-only install-script approvals for npm 12 (#18690) Use name-only install-script approvals for npm 12. Evidence: focused tests on the combined board 62/62; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. * fix(usage): share one spend batch writer per process so graceful shutdown flushes it (#18680) Share one spend batch writer per process so graceful shutdown flushes it. Evidence: focused tests on the combined board 62/62; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. Closes #18678. * chore(pricing): drop six stale zero-priced NVIDIA models (#18500) (#18502) Drop six stale zero-priced NVIDIA models. Evidence: focused tests on the combined board 57/58 with one catalog_build_timeout 503 under host load, covered below; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. tests/unit/codex-account-catalog-routing.test.ts passed 16/16 on isolated rerun with CATALOG_BUILD_TIMEOUT_MS=300000. Closes #18500. * fix(sse): only pin thinking temperature when a sampling param is present (#18636) (#18639) Only pin thinking temperature when a sampling param is present. Evidence: focused tests on the combined board 57/58 with one catalog_build_timeout 503 under host load, covered below; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. tests/unit/codex-account-catalog-routing.test.ts passed 16/16 on isolated rerun with CATALOG_BUILD_TIMEOUT_MS=300000. Fixes #18636 Closes #18636. * fix(sse): treat Leonardo and Ideogram image models as image-only in model tests and chat (#18683) Treat Leonardo and Ideogram image models as image-only in model tests and chat. Evidence: focused tests on the combined board 57/58 with one catalog_build_timeout 503 under host load, covered below; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. tests/unit/codex-account-catalog-routing.test.ts passed 16/16 on isolated rerun with CATALOG_BUILD_TIMEOUT_MS=300000. Closes #18682. * docs(cost): document four-layer pricing precedence and models.dev sync (#18498) (#18501) Document four-layer pricing precedence and models.dev sync. Evidence: focused tests on the combined board 57/58 with one catalog_build_timeout 503 under host load, covered below; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. tests/unit/codex-account-catalog-routing.test.ts passed 16/16 on isolated rerun with CATALOG_BUILD_TIMEOUT_MS=300000. Closes #18498. * fix(sse): persist terminal account failures during combo fallback (#18649) Persist terminal account failures during combo fallback. Evidence: focused tests on the combined board 57/58 with one catalog_build_timeout 503 under host load, covered below; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. tests/unit/codex-account-catalog-routing.test.ts passed 16/16 on isolated rerun with CATALOG_BUILD_TIMEOUT_MS=300000. Fixes #18633 Closes #18633. * fix(antigravity): restore saved Argon cooldowns after restart (#18663) Restore saved Argon cooldowns after restart. Evidence: focused tests on the combined board 57/58 with one catalog_build_timeout 503 under host load, covered below; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. tests/unit/codex-account-catalog-routing.test.ts passed 16/16 on isolated rerun with CATALOG_BUILD_TIMEOUT_MS=300000. * test(sse): cover advertised Claude effort ids against the authoritative catalog (#18611) Cover advertised Claude effort ids against the authoritative catalog. Evidence: focused tests on the combined board 57/58 with one catalog_build_timeout 503 under host load, covered below; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. tests/unit/codex-account-catalog-routing.test.ts passed 16/16 on isolated rerun with CATALOG_BUILD_TIMEOUT_MS=300000. * fix(sse): set X-Accel-Buffering no on self-built SSE responses that bypass the central header path (#18446) Set X-Accel-Buffering no on self-built SSE responses that bypass the central header path. Evidence: focused tests on the combined board 57/58 with one catalog_build_timeout 503 under host load, covered below; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. tests/unit/codex-account-catalog-routing.test.ts passed 16/16 on isolated rerun with CATALOG_BUILD_TIMEOUT_MS=300000. * fix(providers): keep Codex accounts eligible for models no inventory lists (#18367) Keep Codex accounts eligible for models no inventory lists. Evidence: focused tests on the combined board 57/58 with one catalog_build_timeout 503 under host load, covered below; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. tests/unit/codex-account-catalog-routing.test.ts passed 16/16 on isolated rerun with CATALOG_BUILD_TIMEOUT_MS=300000. Closes #18311 * fix(ws): enforce REQUIRE_API_KEY at the /v1/ws bridge handshake (#18540) Enforce REQUIRE_API_KEY at the /v1/ws bridge handshake. Evidence: focused tests on the combined board 57/58 with one catalog_build_timeout 503 under host load, covered below; file-size, changelog integrity, check-deps, lint, typecheck:core, open-sse-typecheck and api-typecheck OK against origin/release/v3.8.53. tests/unit/codex-account-catalog-routing.test.ts passed 16/16 on isolated rerun with CATALOG_BUILD_TIMEOUT_MS=300000. * fix(test): stabilize UI Vitest teardown and provider-stats tests (#18525) Stabilizes UI Vitest suites that failed intermittently on unrelated pull requests. - Studio smoke tests unmount each React root inside act() before removing its container - OmniGlyph cancels the saved-status timer on the next save and on unmount, and ignores a late PUT completion - Provider Stats keeps a dismissed error-only alert closed across background polling; an explicit refresh reopens it - The Provider Stats test uses a stable translator, as next-intl does in the app - Burn-rate chart test waits on real content instead of fixed ticks * fix(sse): strip GHE Copilot URL slashes in linear time (CodeQL #1204 #1200) (#18614) gheUrl was trimmed with /\/+$/, which retries from every slash and goes quadratic on a long slash run that does not reach the end of the string (13 s of CPU on one 100,000-slash value). It now uses the linear stripTrailingSlashes() helper; ordinary URLs resolve the same. The Codex recovery test matches the token host on the parsed URL instead of a substring. * fix(claude): never replay the hardcoded redacted_thinking placeholder (#18036) Stops sending DEFAULT_THINKING_CLAUDE_SIGNATURE to Anthropic. The constant is a real encrypted thought from an unrelated session, and Claude decrypts it as its own reasoning, which derails long agent sessions. - Genuine signed thinking and redacted_thinking blocks are kept verbatim on every turn; unsigned blocks and any block equal to the placeholder are dropped - Nothing is injected on a store miss or during recovery; manual thinking is disabled for the request when the final tool_use turn has no thinking block - Signature 400 recovery now covers Vertex and any model whose targetFormat is claude - Replaces the manual-mode placeholder kept by #18102, whose modified-error recovery and connection binding stay Live coverage: the author reports 0 blobs and 200s on a self-hosted 3.8.52; manual mode has not been verified live by the maintainers. * deps: bump follow-redirects from 1.16.1 to 1.16.2 (#18654) Bumps the transitive follow-redirects from 1.16.1 to 1.16.2 in package-lock.json (Dependabot alert #370, high): cross-realm sensitiveHeaders arrays were discarded and custom credentials could survive a redirect. * feat(db): persist queue wait (start to first upstream dispatch) on ca… (#18402) Persists the queue wait (start to first upstream dispatch) on call-log rows, as a nullable `queue_wait_ms` column. No change on the request path. Maintainer rework: migration renumbered to the next free slot (223); column reconciliation in `schemaColumns.ts`; DB round-trip and chat-path tests; migration count synced in AGENTS.md, llm.txt, README.md and mirrors, digits only, checked by script. Evidence: the lineage test fails with `no such column` against the tip's `schemaColumns.ts`. Gate / CI, Gate / Quality and Merge integrity green on this head. * feat(render): add 180s self-pinger to keep the free web service awake (#18656) Adds an optional self-pinger for the Render free tier. It stays inert unless a URL is configured: no timer, no request, no log. Maintainer rework: config and pinger moved to `scripts/build/runtime-env.mjs` (already shipped in the standalone bundle); `SELF_PING_PATH` can no longer replace the host; logs only on status changes; env vars documented in `.env.example` and ENVIRONMENT.md; 24 tests. Evidence: removing the path guard fails 3 tests. Gate / CI, Gate / Quality and Merge integrity green on this head. Not exercised on a real Render service. * test(compression): verify unchanged-history prefix reuse (#18304) Adds regression coverage for live-zone prefix reuse, including the fail-open case when `instructions` change, for both `messages` and `input`. Test-only. Maintainer rework: added the `instructions` cases; moved the changelog fragment to maintenance. Evidence: removing `instructions` from `STABLE_PREFIX_FIELDS` fails 3 tests. Gate / CI, Gate / Quality and Merge integrity green on this head. * chore(security): accept the minimatch and glob CVEs in the npm bundled in the image (#18766) Accepts CVE-2026-118764 (minimatch 10.2.5, fixed in 11.0.1) and CVE-2026-118773 (glob 13.0.6, fixed in 14.0.2), both medium, in the npm bundled in the image. npm 12.2.1 still declares the vulnerable lines, and an overlay would cross majors outside its ranges. OmniRoute calls npm with fixed subcommands and validated versions, so request input does not reach npm as a glob. Tracking and revisit date (2026-12-02): #18765. * test(ui): stop api-key-redis-auth-cache timing out on a loaded host (#18762) * refactor(dashboard): use the kit Alert dismissible prop for permanent notices (#18764) * test(mutation): register the credit-exhaustion test in the Stryker tap list (#18771) #18649 added a unit test covering two mutated modules without listing it, so check:mutation-test-coverage failed on release/v3.8.53 and on every open PR against it. * ci(dashboard): warn and track it when the UI Kit watch can't read upstream (#18759) * fix(i18n): open the mirror refresh PR with the locales that translated (#18539) Part of #18538. A partial translation run now opens the refresh PR with the units that translated, and failed units stay untouched. Socket resets are retried by the Google engine. * docs(i18n): re-sync the 25 documents that drifted during the week of 2026-10-26 (66 locales; Kimi then Google fallback, references restored) (#18789) * fix(ci): run main-green's suites on hosted runners (#18776) Refs #17267 * fix(ci): raise the Release-Green package lane ceiling to 60 min (#18794) * fix(ui): paginate combo inventory (#17985) Co-authored-by: Sean P. Ford <sean@seanford.com> * fix(compression): estimate automatic-prefix cache eligibility (#17114) * fix: collapse stacked provider-node model prefixes (#17334) * fix(api): preserve search-provider chat rejection responses (#17953) * fix(gemini): preserve cached and reasoning tokens in buffered SSE usage metadata (#18100) * feat(api): System One decisions as a model kind — POST /v1/systemone + /v1/decisions (#13987) (#17994) * feat(combo): add agentic-stall response classifier (#13954) Co-authored-by: Patryk Kopycinski <patryk.kopycinski@elastic.co> * feat(providers): improve Antigravity and Cursor request handling and resilience (#13125) Co-authored-by: Tuan Dinh <tuan.dinh.truong@sap.com> * fix(docs): serve translated /docs pages for the selected locale (#18768) * feat(dashboard): self-host Vazirmatn for Arabic-script RTL locales (#18355) * feat(resilience): payload-aware anti-avalanche failover guard (#15775) * docs(i18n): re-record target_hash for the 3 MCP-SERVER mirrors edited without a re-hash (release prep) (#18807) * test(combo): port the #17945 cooldown-expansion matrix with credit to @skygunner (#18811) Co-authored-by: skygunner <84759+skygunner@users.noreply.github.com> * docs(release): reconcile v3.8.53 — CHANGELOG, contributor credit and README numbers (#18816) * docs(i18n): re-sync ENVIRONMENT and 7 stale documents after the 2026-11-02 merges (structure-safe engine) (#18815) * chore(dashboard): sync the vendored CI UI Kit to 0.0.84 (#18812) * docs(readme): draw the README diagrams in Switzer as vector outlines (#18767) * docs(i18n): re-translate the README mirrors after the week's README changes (66 locales) (#18817) * docs(i18n): retouch the locales the structure-safe engine could not restore (9 documents, 36 mirrors) (#18821) * docs: sync AGENTS.md counts with source (db + services) (#17309) Co-authored-by: Mayank Jaiswal <mayankjaiswal1707@gmail.com> * fix(ci): free hosted runner disk before the unit shards (#18808) Hosted Unit Tests shards ran out of disk while writing raw V8 coverage and died with no test summary. Free preinstalled toolchains first, on hosted runners only. * docs(i18n): re-sync the API_REFERENCE mirrors after the 2026-10/11 API changes (66 locales) (#18822) * docs(i18n): re-sync QUALITY_GATES and DESIGN_SYSTEM mirrors after the 2026-11-03 source changes (#18824) * docs: add the creator credit (KEA-6307) and courtesy credit for #17183 (#18843) * fix(egress): record the observed egress address of each address family (#17326) Merged as part of the v3.8.53 fix sweep (author @maxmad64bis). Co-authored-by: Dizzle <112548150+maxmad64bis@users.noreply.github.com> Co-authored-by: # <docs/i18n/am/README.md> Co-authored-by: # <docs/i18n/ar/README.md> Co-authored-by: # <docs/i18n/az/README.md> Co-authored-by: # <docs/i18n/bg/README.md> Co-authored-by: # <docs/i18n/bn/README.md> Co-authored-by: # <docs/i18n/bs/README.md> Co-authored-by: # <docs/i18n/cs/README.md> Co-authored-by: # <docs/i18n/da/README.md> Co-authored-by: # <docs/i18n/de/README.md> Co-authored-by: # <docs/i18n/el/README.md> Co-authored-by: # <docs/i18n/es/README.md> Co-authored-by: # <docs/i18n/et/README.md> Co-authored-by: # <docs/i18n/fa/README.md> Co-authored-by: # <docs/i18n/fi/README.md> Co-authored-by: # <docs/i18n/fr/README.md> Co-authored-by: # <docs/i18n/ga/README.md> Co-authored-by: # <docs/i18n/gu/README.md> Co-authored-by: # <docs/i18n/ha/README.md> Co-authored-by: # <docs/i18n/he/README.md> Co-authored-by: # <docs/i18n/hi/README.md> Co-authored-by: # <docs/i18n/hr/README.md> Co-authored-by: # <docs/i18n/hu/README.md> Co-authored-by: # <docs/i18n/hy/README.md> Co-authored-by: # <docs/i18n/id/README.md> Co-authored-by: # <docs/i18n/ig/README.md> Co-authored-by: # <docs/i18n/ja/README.md> Co-authored-by: # <docs/i18n/ka/README.md> Co-authored-by: # <docs/i18n/km/README.md> Co-authored-by: # <docs/i18n/kn/README.md> Co-authored-by: # <docs/i18n/ko/README.md> Co-authored-by: # <docs/i18n/lt/README.md> Co-authored-by: # <docs/i18n/lv/README.md> Co-authored-by: # <docs/i18n/ml/README.md> Co-authored-by: # <docs/i18n/mr/README.md> Co-authored-by: # <docs/i18n/ms/README.md> Co-authored-by: # <docs/i18n/mt/README.md> Co-authored-by: # <docs/i18n/my/README.md> Co-authored-by: # <docs/i18n/ne/README.md> Co-authored-by: # <docs/i18n/nl/README.md> Co-authored-by: # <docs/i18n/no/README.md> Co-authored-by: # <docs/i18n/or/README.md> Co-authored-by: # <docs/i18n/pa/README.md> Co-authored-by: # <docs/i18n/phi/README.md> Co-authored-by: # <docs/i18n/pl/README.md> Co-authored-by: # <docs/i18n/pt-BR/README.md> Co-authored-by: # <docs/i18n/pt/README.md> Co-authored-by: # <docs/i18n/ro/README.md> Co-authored-by: # <docs/i18n/ru/README.md> Co-authored-by: # <docs/i18n/si/README.md> Co-authored-by: # <docs/i18n/sk/README.md> Co-authored-by: # <docs/i18n/sl/README.md> Co-authored-by: # <docs/i18n/sr/README.md> Co-authored-by: # <docs/i18n/sv/README.md> Co-authored-by: # <docs/i18n/sw/README.md> Co-authored-by: # <docs/i18n/ta/README.md> Co-authored-by: # <docs/i18n/te/README.md> Co-authored-by: # <docs/i18n/th/README.md> Co-authored-by: # <docs/i18n/tr/README.md> Co-authored-by: # <docs/i18n/uk-UA/README.md> Co-authored-by: # <docs/i18n/ur/README.md> Co-authored-by: # <docs/i18n/uz/README.md> Co-authored-by: # <docs/i18n/vi/README.md> Co-authored-by: # <docs/i18n/yo/README.md> Co-authored-by: # <docs/i18n/zh-CN/README.md> Co-authored-by: # <docs/i18n/zh-TW/README.md> * fix(auth): audit non-inference API-key touches (#17982) Merged as part of the v3.8.53 fix sweep (author @seanford). Co-authored-by: Sean P. Ford <sean@seanford.com> * fix(usage): preserve pending byte accounting across module reloads (#18267) Merged as part of the v3.8.53 fix sweep (author @AiCaptain357). Co-authored-by: AiCapitan357 <ai-capitan-357@proton.me> * fix(compression): honor safe configured downgrade steps (#18279) Merged as part of the v3.8.53 fix sweep (author @trespassmk). Co-authored-by: trespassmk <avtogram@gmail.com> * fix(combo): report the fallback rate as a share of requests (#18284) Merged as part of the v3.8.53 fix sweep (author @HouMinXi). Co-authored-by: Minxi Hou <houminxi@gmail.com> * fix(api): return /v1/messages 401s in Anthropic's error envelope (#18299) Merged as part of the v3.8.53 fix sweep (author @diegosouzapw). Co-authored-by: omar-nahhas <omar@innovativerealities.com> * fix(providers): a provider safety refusal is not an account ban (#18307) Merged as part of the v3.8.53 fix sweep (author @aldoeliacim). Co-authored-by: aldoeliacim <github@aldo.pw> * fix(dashboard): list zed-hosted live models in the combo model picker (#18315) Merged as part of the v3.8.53 fix sweep (author @diegosouzapw). Co-authored-by: Haidar Muhammad Yasin <haidarmy1@gmail.com> * fix(combo): report authentication_rejected when every target fails auth (#18366) Merged as part of the v3.8.53 fix sweep (author @HouMinXi). Co-authored-by: Bob.Hou <houminxi@gmail.com> * fix(combo): fall back from protected priority on structured context overflow (#18368) Merged as part of the v3.8.53 fix sweep (author @RaviTharuma). Co-authored-by: Ravi Tharuma <RaviTharuma@users.noreply.github.com> * fix(resilience): accept globalConcurrentRequests and budgetMs in the settings schema (#18401) Merged as part of the v3.8.53 fix sweep (author @HouMinXi). Co-authored-by: Bob.Hou <houminxi@gmail.com> * fix(autoCombo): keep the readiness gate for auto/<family> pools (#18428) Merged as part of the v3.8.53 fix sweep (author @HouMinXi). Co-authored-by: Bob.Hou <houminxi@gmail.com> * fix(devin): fail with a non-retryable 503 when DEVIN_AGENTIC_HOME is unset or unsafe (#18433) Merged as part of the v3.8.53 fix sweep (author @HouMinXi). Co-authored-by: Bob.Hou <houminxi@gmail.com> Co-authored-by: Bob.Hou <364432949@qq.com> * fix(pricing): price the NVIDIA free catalog models at zero (#18470) Merged as part of the v3.8.53 fix sweep (author @HouMinXi). Co-authored-by: Bob.Hou <houminxi@gmail.com> * fix(api-keys): check resolved models against the key the policy loaded (#18481) Merged as part of the v3.8.53 fix sweep (author @HouMinXi). Co-authored-by: Bob.Hou <houminxi@gmail.com> * fix(logs): show each completed attempt once (#18491) Merged as part of the v3.8.53 fix sweep (author @AiCaptain357). Co-authored-by: AiCapitan357 <ai-capitan-357@proton.me> * typecheck: add a production type ratchet, and pay down 453 -> 272 (#18603) Merged as part of the v3.8.53 fix sweep (author @HouMinXi). Co-authored-by: Minxi Hou <houminxi@gmail.com> * fix(api): drop evidence-free combo members from advertised limits (#18618) Merged as part of the v3.8.53 fix sweep (author @serenity-X). Co-authored-by: serenity-X <295272363+serenity-X@users.noreply.github.com> * docs(providers): document what the claude OAuth route does to client system prompts (#18640) Merged as part of the v3.8.53 fix sweep (author @serenity-X). Co-authored-by: serenity-X <295272363+serenity-X@users.noreply.github.com> * fix(sse): preserve failed empty turns and expose native diagnostics (#18685) Merged as part of the v3.8.53 fix sweep (author @fouadSalkini). Co-authored-by: Fouad Salkini <fouad@wecansync.com> * fix(db): preserve backup archives and unknown formats during retention (#18712) Merged as part of the v3.8.53 fix sweep (author @aldoeliacim). Co-authored-by: aldoeliacim <github@aldo.pw> * test: isolate daily quota clocks and VS Code catalog discovery (#18748) Merged as part of the v3.8.53 fix sweep (author @HouMinXi). Co-authored-by: Minxi Hou <houminxi@gmail.com> * fix(providers): accept Cloudflare test message model IDs (#18752) Merged as part of the v3.8.53 fix sweep (author @trespassmk). Co-authored-by: trespassmk <avtogram@gmail.com> * fix(capabilities): restrict GLM-5.3 vision heuristic to Flash (#18758) Merged as part of the v3.8.53 fix sweep (author @insoln). Co-authored-by: insoln <insoln@ya.ru> * fix(sse): keep in-stream provider safety stops terminal (#18760) Merged as part of the v3.8.53 fix sweep (author @aldoeliacim). Co-authored-by: aldoeliacim <github@aldo.pw> * fix(compression): keep tool results intact unless a request overflows (#18761) Merged as part of the v3.8.53 fix sweep (author @aldoeliacim). Co-authored-by: aldoeliacim <github@aldo.pw> * test(setup): opt-in egress guard for in-process tests, plus the #16631 Claude OAuth frozen-body case (#18819) Merged as part of the v3.8.53 fix sweep (author @AndresDiagoM). Co-authored-by: AndresDiagoM <andresdiag@unicauca.edu.co> * fix(executors): clamp-and-retry max_tokens when upstream advertises a lower ceiling (#18407) Merged as part of the v3.8.53 fix sweep (author @jjxyxsjr). Co-authored-by: 沈俊杰 <shenjunjie@nndrobot.com> * fix(translator): the system-role fold must not drop non-text parts of the first user message (#18437) Merged as part of the v3.8.53 fix sweep (author @jjxyxsjr). Co-authored-by: 沈俊杰 <shenjunjie@nndrobot.com> * fix(auto-combo): treat account-semaphore capacity errors as local queue capacity (#18442) Merged as part of the v3.8.53 fix sweep (author @jjxyxsjr). Co-authored-by: 沈俊杰 <shenjunjie@nndrobot.com> * fix(executors): forward Codex requests as the client sent them (#18274) Merged as part of the v3.8.53 fix sweep (author @aldoeliacim). Co-authored-by: aldoeliacim <github@aldo.pw> * fix(usage): show the Kimi Coding subscription plan (#18578) Merged as part of the v3.8.53 fix sweep (author @AiCaptain357). Co-authored-by: AiCapitan357 <ai-capitan-357@proton.me> * fix(antigravity): isolate consumer generation endpoints (#18706) Merged as part of the v3.8.53 fix sweep (author @AiCaptain357). Co-authored-by: AiCapitan357 <ai-capitan-357@proton.me> * fix(providers): register Codex gpt-6.1-sol as an image model for combos and edits (#18826) Merged as part of the v3.8.53 fix sweep (author @anhtahaylove). Co-authored-by: anhtahaylove <everest.kill1@gmail.com> * ci(dashboard): keep one UI kit sync PR open from the latest upstream release (#18769) The UI Kit upstream watch only opened a tracking issue, so a new kit release still waited for someone to run the sync by hand. It now runs daily and, while the pin is behind, keeps one PR open against the highest release/vX.Y.Z branch through scripts/ci/ui-kit-sync-pr.sh. It never merges: every kit release still needs a visual check on the local VPS. The PR lives on the rolling branch chore/ui-kit-sync-latest because upstream can ship several releases a day. The branch is rebuilt when a newer release is out and left alone otherwise. An open PR with commits pushed by hand isn't overwritten, and a PR that a maintainer closed unmerged stays closed until a newer release. The watch holds while the target release is frozen. When no PR can be opened, the tracking issue says why. It's edited in place, since a comment on every daily run would only be noise. The issue step no longer runs when the check itself failed: an empty state used to fall through to the branch that closes the issue as up to date. Opening the PR needs the new UI_KIT_SYNC_PR_TOKEN secret, because GITHUB_TOKEN can't create PRs in this repository and a PR it opened wouldn't trigger CI. Without it only the branch is pushed. * fix(claude): show a Team seat's own tier and name a member with no seat (#18763) Merged as part of the v3.8.53 fix sweep (author @shipsfromrio). Co-authored-by: Caio Figueiroa <334500047+shipsfromrio@users.noreply.github.com> * docs(i18n): fix typos and broken tables in Uzbek README (#18659) Merged as part of the v3.8.53 fix sweep (author @barkhayot). Co-authored-by: Barkhayot Juraev <coderviewer@gmail.com> * fix(sse): real newlines in the opencode DeepSeek json_schema prompt (#18691) Merged as part of the v3.8.53 fix sweep (author @AndresDiagoM). Co-authored-by: AndresDiagoM <andresdiag@unicauca.edu.co> * fix(sse): let a combo opt out of the cooldown wait (#18708) Merged as part of the v3.8.53 fix sweep (author @stanleytejakusuma). Co-authored-by: Stanley Tejakusuma <70442355+stanleytejakusuma@users.noreply.github.com> * fix(providers): drop retired Mistral devstral-latest (#18792) Merged as part of the v3.8.53 fix sweep (author @costajohnt). Co-authored-by: John Costa <costajohnt@gmail.com> * fix(sync): wire the combo inventory pagination and the dismissed stats error Closes the two gaps left open by the sync commit, and removes a duplicated model-catalog block the merge reintroduced. ## Ported upstream features - Combo inventory pagination is now wired into `combos/page.tsx`: `useComboPagination` over the filtered list, `ComboListToolbar` above the inventory, `ComboPaginationNav` below it, "Reorder all" as the only drag mode, `revealCreatedCombo` selecting the created combo's page (dropping the strategy filter when needed), and `prefetch={false}` on per-combo links. - Provider stats keeps the last good snapshot on a failed poll: the load error is a dismissible banner, polling leaves a dismissal alone, and the header refresh reopens it. ## Merge bug fixed `gpt-6.1-terra*` was present twice in the codex registry (the conflict resolution kept the fork's legacy block next to upstream's single entry) and once more in `modelSpecs`/the OpenAI registry. Those duplicates made an uncatalogued model carry a confirmed 872K cap, which broke the #18609 combo ceiling rule and would have advertised a window upstream does not. ## Tests - `tests/unit/ui/provider-stats-dismissed-error.test.tsx` (new) covers the banner: appears on a failed poll, survives later polls once dismissed, comes back on an explicit refresh. - `tests/unit/ui/combo-pagination.test.tsx` gains the wiring assertions. - `tests/unit/auto-combo-route-param-page.test.tsx` restored: the encoded `/dashboard/combos/auto%2Ffast` crumb fix is ported to `Breadcrumbs` (`decodeRouteParam` + the `costs/teams` label). - 26 upstream dashboard test files deleted: they assert the vendored UI kit's DOM (`data-slot`, `ci-button`, kit popover/dialog semantics) on surfaces this fork renders with its own components. They arrived with this sync and never matched this tree. --------- Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com> Co-authored-by: Junior-HJ <sjaradj@ucvvirtual.edu.pe> Co-authored-by: Muhammad Usama <55662931+MuhammadUsamaMX@users.noreply.github.com> Co-authored-by: Erwan Novianto <smserwan@gmail.com> Co-authored-by: hummern <hummernkloa@gmail.com> Co-authored-by: turbolego <turbolego@gmail.com> Co-authored-by: Mayank Jaiswal <mayankjaiswal1707@gmail.com> Co-authored-by: James Martinez <james-martinez@users.noreply.github.com> Co-authored-by: Praveen K Palaniswamy <praveen.palaniswamy@gmail.com> Co-authored-by: xc0derx <11428624+xc0derx@users.noreply.github.com> Co-authored-by: Anton Shilin <coder.root@gmail.com> Co-authored-by: Dizzle <112548150+maxmad64bis@users.noreply.github.com> Co-authored-by: WITALO ROCHA <witalo_rocha@hotmail.com> Co-authored-by: Bob.Hou <houminxi@gmail.com> Co-authored-by: Andres Felipe Diago Matta <82129635+AndresDiagoM@users.noreply.github.com> Co-authored-by: HouMinXi <19586012+HouMinXi@users.noreply.github.com> Co-authored-by: Abhishekchhetri020 <145480099+Abhishekchhetri020@users.noreply.github.com> Co-authored-by: Abhishek Chhetri <abhishekchhetri@example.com> Co-authored-by: ScottyAmr <scott.kanowski@gmail.com> Co-authored-by: Felipe Almeman <4226997+zhiru@users.noreply.github.com> Co-authored-by: Felipe Almeman <felipe@aireset.com.br> Co-authored-by: Rafa Martins <146174365+rafacpti23@users.noreply.github.com> Co-authored-by: Dongwook <dongwook.chan@gmail.com> Co-authored-by: Tuan Dinh <tuan.dinh.truong@sap.com> Co-authored-by: arashashrafii <arash.ashrafi@gmail.com> Co-authored-by: Pranav Deshpande <134182346+PranavD2905@users.norep…
What this is
Nothing type-checks OmniRoute's production code, and this PR puts a line under
that so it cannot grow.
next buildruns withtypescript.ignoreBuildErrors: true. The blockingtypecheck:coregate covers a curated 27-file allowlist. The dashboard andAPI-route gates each freeze their own existing errors. The root tsconfig would
cover the rest, except that it pulls
tests/in through**/*.tsand cannotfinish on an ordinary machine. The production surface between those was unwatched,
and 453 diagnostics had accumulated there.
Twenty-eight files also opt out of checking entirely with
@ts-nocheckat the top:the token refresh family, the Bedrock executor, the token health checker,
proxyFetch, and the generated docs collection. Removing those 28 directivesraises the count to 326, so 54 errors are hidden there, concentrated in token and
credential handling.
What changed
A new gate,
npm run check:build-typecheck, runstsconfig.build.json(productionscope) and diffs the result against a frozen per-(file, TS code) count baseline.
--updaterewrites the baseline, but refuses while the live run contains a newor raised pair, so making a red build green by widening the baseline has to be
explicit:
--force-regressionsfor a counted error,--force-nocheckfor apermanent silence. A bare
--forceis rejected.@ts-nocheckis scanned across the program and frozen inconfig/quality/ts-nocheck-baseline.json; adding the directive fails, removingone is always allowed
@ts-ignoreand@ts-expect-errorare counted per file againstconfig/quality/ts-suppressions-baseline.json, because one added comment lineremoves a diagnostic and the gate would otherwise read that as progress
frozen in the baseline, so shrinking the program is a failure rather than an
improvement
The gate runs in
ci.ymlandquality.ymland is registered inbaseline-headroom.mjsalongside the three sibling typecheck ratchets.The same guards now cover the API-route gate. It was a blocking CI gate whose whole
--updatepath waswriteBaseline(live); exit 0— no refusal, no@ts-nocheckscan, no suppression accounting — and its baseline froze 283 errors against 180
live, which is 103 units of headroom that would have absorbed any new error without
a word. It shares
scripts/check/ratchet.mjswith the build gate now, has the samefour guards, and its baseline is tightened to the 180 that exist. The extraction cut
check-build-typecheck.mjsfrom 529 lines to 313.Alongside it, 453 -> 254 by fixing the underlying types rather than suppressing
them. The largest single win was one missing type parameter:
SqliteAdapter.preparehad no generic, so five
prepare<Row>(sql)calls produced twenty diagnostics. React19 dropping the global
JSXnamespace accounted for another group.Three behaviour changes
The title says "type ratchet", but three lines in this diff change what the product
does. All three are fixes.
src/app/api/oauth/cursor/login/poll/route.tscalledsyncToCloud()with nomachine id. The function requires it, has no default, and interpolates it into a
request path, so every sync POSTed to
/sync/undefinedand failed. The routecomputed the id two lines earlier for the credential save and passed it nowhere.
src/app/api/providers/[id]/models/route.tspassed an outbound guard as a thirdpositional argument to
safeOutboundFetch(url, options), which readsoptions.guard. The argument was dropped and the request ran on the defaultpolicy. The URL at that call site is a string literal, so nothing was reachable by
an attacker, and 17 sibling call sites in the same file already passed it
correctly. The fix is that the policy the caller asked for is the policy that runs.
ProviderModalsPanel.tsxpassedcopied={externalLinkCopied ? "extlink" : false}to a prop typed
string | falsethat renders only on=== "extlink", so the"copied" indicator on the external-link modal never appeared. It does now.
How it was verified
Each guard was tested by injecting against it:
✗ <file> TS2322 (baseline 0, live 1)--updatewith that error present is refused and leaves the baselineunchanged
@ts-nocheckto a clean file makes it exit 1 and name the file@ts-nocheckbehind a sixty-line banner, past any fixed read window, isstill caught, and
--updatestill refuses\ras the terminator, and// @ts-nocheck: reasonas a form, both of which tsc honours@ts-ignorein the four shapes tsc accepts (leading, trailing,/* */,/** */) is counted, and one added to a clean file fails the gatets-nocheck-baseline.jsonwhile it still carries baselinederrors is caught, on both the verify and the update path
That last case is why the check reads the baseline's file list rather than the live
one: a file that gains the directive is exactly the file that disappears from the
diagnostics, so intersecting against the live run is empty by construction.
Numbers
@ts-nocheckfiles@ts-nocheckThe dashboard tightening was checked pair by pair: zero added, zero raised. The new
build baseline is a frozen raw count, not a relaxed one.
Known limits
of the same code in the same file is not detected. 81 of the files carry exactly
one diagnostic, which is where that limitation is widest. Per-line identity would
be too brittle against unrelated edits.
move any of these numbers. They are cross-checked where that is possible (a file
cannot be both frozen debt and silenced), but the intent is review, not
tamper-proofing.
.mjsfiles are in the program but are not checked:allowJsis on andcheckJsis off, so TypeScript parses them without reporting. TurningcheckJson is its own change.
src/app/.well-known/agent-card.json/route.tsis outside the program becauseTypeScript's
**does not descend into dot-directories. It is real code that nogate has ever checked.
src/lib/source.tsimports the fumadocs collection in.source/, which isgenerated and gitignored. The gate regenerates it before compiling so the verdict
does not depend on whether someone ran
next build, but the coupling isunchanged.
tsconfig.build.jsonneeds several GB of heap, so the step carriestimeout-minutes: 5and runs a full (non-incremental) compile on purpose. Averdict that depends on which
.tsbuildinfohappened to be present is not averdict.
one unfrozen error that this commit clears. A plain
git revertneeds thedashboard baseline restored with it.
Not in this PR
The remaining 254 diagnostics. Clearing them is the point of the baseline, and they
land in follow-ups.