fix(ci): clear the release/v3.8.51 base-reds on the PR fast path - #13635
diegosouzapw merged 21 commits into
Conversation
…diagrams and llm.txt mirrors
…r the open-sse typecheck
…ce module to break the models/providers cycle
…o gitleaks stays at zero
…the captured token window
… and restore the zh-TW glossary term
… execution pipeline
… modules and refresh the translate-path golden
…detail client bundle
…ards with their merged contracts
|
@diegosouzapw the PR focuses to fix existing issues in 3.8.51 branch |
|
Heads-up: this now conflicts with
Several pieces here are not on the tip in any form and are worth keeping after a rebase: the For the rebase: I ran the full slow gate set on an idle box against |
#13248 (#12849) added the override for when a connection's synced model list stops being authoritative, but neither .env.example nor ENVIRONMENT.md lists it, so the env/docs contract gate reports it as code-only. The other five vars that gate reports are already added by #13635 and #13361; this touches a different region of .env.example so it does not collide with either. Refs #12732
Resolves the 11 conflicts that blocked diegosouzapw#13635. Both sides had fixed several of the same base-reds independently, so no single "take ours/theirs" rule was correct; each hunk was decided against the merged tree. Taken from the release branch: - pack-artifact-policy.ts: same allowlist entry, the base adds the rationale. - activeSyncedCatalog.ts: the base adds the synced_models_at column; this side only reformatted. - injection-guard-scan-bound-3932.test.ts: identical logic, fuller comment. - autoCombo.test.ts: this side added errorRate inside the conflict while the base had already added it just below, so taking this side would have put a duplicate errorRate key in 7 ProviderCandidate literals. Kept from this branch: - provider-node-reserved-prefix.test.ts: RESERVED_PREFIX_COUNT measured 412 on the merged tree (Arcee AI present); the base's 410 is stale. - providers-constants-split.test.ts: APIKEY_PROVIDERS measured 240; both sides agree, this side centralizes it in one constant. - glm-sse-transform-arity.test.ts: asserts call/helper arity and the suppressThinkClose position — the original bug was an arity mismatch; the base variant only checks string containment. - combo-provider-cooldown-sibling.test.ts, chatcore-hierarchical-admission .test.ts: per-call-site checks and the two-leg sendProviderAttempt wiring, stronger than the base's per-file checks. Both verified passing on the merged code. - providerExecutionPipeline.ts: uses this side's readUpstreamErrorFields helper; taking the base would have left it as dead code. The non-JSON error body fix from diegosouzapw#12945 is preserved. - stryker.conf.json: superset of the base list; the 4 extra files exist. Only conflicting hunks were resolved, never whole files, so non-conflicting changes on both sides are intact. Verified: 64/64 across the resolved suites, autoCombo.test.ts 63/63, check:open-sse-typecheck 0 errors.
|
Resolvi os 11 conflitos que travavam esta PR, direto na sua branch e como merge fast-forward ( Os dois lados tinham consertado vários dos mesmos base-reds de forma independente, então nenhuma regra fixa de "fica com um lado" servia. Cada bloco foi decidido contra a árvore mergeada: Da
Desta branch (mantidos):
Resolvi só os blocos em conflito, nunca o arquivo inteiro, para não apagar mudanças não conflitantes de nenhum dos lados. Verificação: 64/64 nas suítes resolvidas · Uma observação à parte: o |
9442bde
into
diegosouzapw:release/v3.8.51
…bo catalog event-loop pin, unweighted quota-share, resilience key set, pack-gate stamp, synced-catalog env doc (#13678) * fix(combo): rotate unweighted quota-share targets instead of pinning the first The combo resolver turns an unset step weight into 0 (comboStructure.ts), and #10881 made normalizeWeight treat 0 as disabled plus return definition order when the total weight is 0. A quota-share combo without explicit weights therefore had no DRR quanta and dispatched every request to its first target — the combo-matrix/quota-share integration suite saw openai six times out of six. An all-zero set is now an unweighted combo and shares evenly; an explicit 0 still disables a target when its siblings are weighted. Refs #12732 * fix(models): resolve auto-combo target metadata once per catalog build #12046 derives vision/modalities for the built-in auto/* combos by resolving catalog metadata for every target of every combo. The ~40 auto combos share one candidate pool and the loop neither memoized nor yielded, so the #9147 fixture (60 connections, 720 synced models) went from a ~4s build with a 167ms longest event-loop gap to ~11s and a 860-1070ms gap on an idle box — past the 800ms contract and past #12628's 8s cold-build bound, which is why the test came back 500 catalog_build_timeout on every release-green run. Metadata depends only on the target's provider/model/connection scope within a build, so memoize it per build and yield between misses. Same fixture: 2.3-3.1s build, 56-72ms longest gap. The 9147 test is unchanged. Refs #12732 * test(resilience): list credentialHealthCheck in the configuration-only key set #12043 added credentialHealthCheck.intervalMinutes to DEFAULT_RESILIENCE_SETTINGS and to the /api/resilience GET projection. It is operator configuration (the background sweep cadence), not runtime breaker state, but the exact key-set assertion was never updated, so resilience-http-e2e failed on the release tip. The providerBreakers/runtime absence checks stay as they were. Refs #12732 * fix(ci): stamp BUILD_SHA before the release-green pack gate validates check:pack-artifact assembles dist/ through build:cli, which never writes dist/BUILD_SHA (only build:release does). #12959 pointed the provenance ref at HEAD, but the #10427 guard still stops at 'dist/BUILD_SHA is missing' before it ever reaches the ancestry check — reproduced on tip + #13635 + #13436, the first tree whose Turbopack build compiles. ci.yml sequences build -> stamp -> validate; the validator now does the same in both entry points, keeping PACK_GATE_ENV for the validate step. The guard is unchanged: an unstamped dist/ or one built from another commit still fails. On that tree the stamped gate passes: 'BUILD_SHA 5cb3ae5d9 is on the release line'. Refs #12732 * docs(env): document OMNIROUTE_SYNCED_CATALOG_STALE_AFTER_MS #13248 (#12849) added the override for when a connection's synced model list stops being authoritative, but neither .env.example nor ENVIRONMENT.md lists it, so the env/docs contract gate reports it as code-only. The other five vars that gate reports are already added by #13635 and #13361; this touches a different region of .env.example so it does not collide with either. Refs #12732
…(stryker, CLI i18n, paid-target fixture, call-log traceId, Jina prefix, callLogStats import, gitleaks) (#13747) * fix(ci): clear the release/v3.8.51 base-reds left by the 09-15 batch — stryker coverage, CLI ready_timeout key, paid-target fixture, call-log traceId, Jina custom prefix Every PR into release/v3.8.51 pushed after #13635/#13678 still failed Fast Quality Gates and all four Unit fast-path shards on the same 16 tests. Each one reproduces on the pure tip; none is a product defect: - mutation-test-coverage: noauth-model-lockout and local-token-budget-429-skips-cooldown (#13606) were missing from stryker.conf.json tap.testFiles. - cli-i18n-catalog: --ready-timeout calls t("serve.ready_timeout") with no catalog entry; added to en, zh-CN and zh-TW (the parity-checked locales). - paid-model-target(-routes)-6540: #13407 removed Together's one-time credit from the free catalog, so "together/..." classifies as unknown and the save-time guard correctly lets it through. Fixture is now gemini/gemini-3.1-pro-preview, plus a precondition test on the fixtures. - attempt-logging-early-keepalive-merge / video-bridge-log-redaction: #13546 keys the call-log row on traceId; baseCtx now defaults traceId to pendingRequestId (same pattern as chatcore-attempt-logging). The keepalive test also moves to the 30s wall-clock poll deadline video-bridge uses. - models-catalog-route: custom Jina rows keep the jina-ai/ prefix; #13403 changed the custom assertion to jina/ (only synced rows use the alias). Refs #12732 * fix(ci): clear the four reds the first r4 CI run surfaced — callLogStats duplicate import, Uzbek gitleaks false positive, redaction probe traceId, file-size - src/lib/db/callLogStats.ts: the #13641 merge left ERROR_TYPE_CONTRACT imported twice (TS2300), failing API Route Typecheck and check:dashboard-typecheck on every PR. - .gitleaks.toml: the Uzbek catalog from #13727 translates outputTokenDesc as "Yakunlash/javob tokenlari"; generic-api-key reads it as a token value. - dashboard-request-failed-redaction-probe: reads the persisted row by traceId (#13546); with pendingRequestId it asserts null. - models-catalog-route: drop the explanatory comment, which pushed the frozen file over its size cap; the rationale lives in the changelog fragment. Refs #12732 * fix(ci): re-freeze the two test files #13748/#13749 grew past their file-size caps PR-mode check:file-size relaxes source files against the base but not testFrozen, so image-generation-handler.test.ts (2133->2235, #13748) and batch_api.test.ts (1345->1348, #13749) failed Fast Quality Gates on every PR, this one included. Caps set to the merged LOC, with the justification entry. Refs #12732 * fix(ci): register free-badge-provider-gate (#13645) in stryker tap.testFiles #13645 landed a covering test for src/sse/services/auth.ts without the stryker entry, so the strict mutation-test-coverage gate went red again. Refs #12732 * fix(ci): clear two more base-reds the #13440/#13439 merges added - stryker.conf.json: register daily-reset-tz-threading (#13440), which covers accountFallback.ts and rrState.ts. - .gitleaks.toml: allowlist the PROTECTED_PRIORITY_INFRA_502_ENABLED flag id (#13439); generic-api-key reads its key: as a token (secrets ratchet 0 -> 1). Refs #12732 * docs(changelog): tidy the stryker base-red fragment wording Refs #12732
Merge the current release tip into the security hardening branch and reconcile 57 conflicting files. Most of this PR's original scope landed on the tip while it sat: #12506/#12945/ #13635 shipped a stricter public error boundary (allowlist-based `isSafePublicErrorIdentifier`, `errorSanitization.ts`, `errorPathRedaction.ts`, `upstreamErrorResponse.ts`), #12429 migrated the web-cookie TLS transport to wreq-js, and #11754 retired the common ChatGPT Web executor. Those parts are resolved to the tip, which is strictly more restrictive in every case, and the now-dead tls-client provenance stream is dropped (the tip's `tls-client-wreq-residue` guard forbids reintroducing `tls-client-node`). What survives is the part the tip does not cover: - chatCore reads rejection metadata through `getSafeErrorMetadata`, wraps `isLocalStreamLifecycleError`/`formatProviderError` so a hostile Proxy cannot escape the boundary, sanitizes the failure message before call logs and console, projects the failure-usage code through the bounded vocabulary, and sanitizes the upstream body before it reaches the persisted attempt logs. - Perplexity's non-streaming quota/upstream error body sanitizes the upstream message and projects the provider-supplied code (`toPublicPerplexityErrorCode`). - Arena (lmarena) maps every public failure onto a fixed vocabulary instead of echoing upstream text; `lmarena_stream_error` is registered in the public identifier allowlist. - Notion keeps the tip's fail-closed transport (no plain-fetch proxy bypass) and sanitizes the transport error before the response body. - `chatgptWebTools` returns a non-ok buffered response untouched. Tests for superseded behaviour are dropped; the surviving contributions keep their tests, split into `lmarena-public-error-boundary-11742` and `perplexity-web-public-error-boundary-11742` to stay under the test size cap. Prunes three now-stale eslint suppression entries: notion-web.ts no longer has an unused var after this merge, and the two chipotle entries were left behind by the tip's own provider removal (#13913).
…gosouzapw#13635) * docs: bring the provider count to the live 358 across the reference, diagrams and llm.txt mirrors * chore(skills): regenerate the cli-tunnel SKILL.md for the tunnel create positional * test: clear the ESLint errors in the volcengine upsert and resource-pressure tests * test(autoCombo): complete the mode-pack ProviderCandidate fixtures for the open-sse typecheck * fix(ci): allow the opencode-plugin-v2 workspace package in the pack artifact policy * docs: list the WAL, vacuum, sql.js and pressure self-restart env vars in .env.example * refactor(db): move the synced-model provider purge into its persistence module to break the models/providers cycle * test(memory): use a plain label for the rerank loopback key fixture so gitleaks stays at zero * chore(ci): register the eleven covering unit tests in stryker tap.testFiles * test(grok-cli): run the reset-credit tests on a fixture clock inside the captured token window * test(combo): seed real provider connections for the reset-aware strategy tests * fix(db): keep operator custom models out of the listing-only synced catalog reader * fix(i18n): translate the new settings and combo keys for vi and pt-BR and restore the zh-TW glossary term * fix(sse): carry the upstream error code and type through the provider execution pipeline * test(sse): re-point the chatCore and combo source guards at the split modules and refresh the translate-path golden * fix(oauth): keep the server-only OAuth constants out of the provider detail client bundle * test: align the sql.js, webpack, injection-scan and error-boundary guards with their merged contracts * docs(changelog): record the v3.8.51 base-red sweep * fix(sse): anchor the glued-prefix sk- credential pattern so error redaction scans in linear time * docs(changelog): note the linear credential scan in the base-red sweep --------- Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
…bo catalog event-loop pin, unweighted quota-share, resilience key set, pack-gate stamp, synced-catalog env doc (diegosouzapw#13678) * fix(combo): rotate unweighted quota-share targets instead of pinning the first The combo resolver turns an unset step weight into 0 (comboStructure.ts), and diegosouzapw#10881 made normalizeWeight treat 0 as disabled plus return definition order when the total weight is 0. A quota-share combo without explicit weights therefore had no DRR quanta and dispatched every request to its first target — the combo-matrix/quota-share integration suite saw openai six times out of six. An all-zero set is now an unweighted combo and shares evenly; an explicit 0 still disables a target when its siblings are weighted. Refs diegosouzapw#12732 * fix(models): resolve auto-combo target metadata once per catalog build diegosouzapw#12046 derives vision/modalities for the built-in auto/* combos by resolving catalog metadata for every target of every combo. The ~40 auto combos share one candidate pool and the loop neither memoized nor yielded, so the diegosouzapw#9147 fixture (60 connections, 720 synced models) went from a ~4s build with a 167ms longest event-loop gap to ~11s and a 860-1070ms gap on an idle box — past the 800ms contract and past diegosouzapw#12628's 8s cold-build bound, which is why the test came back 500 catalog_build_timeout on every release-green run. Metadata depends only on the target's provider/model/connection scope within a build, so memoize it per build and yield between misses. Same fixture: 2.3-3.1s build, 56-72ms longest gap. The 9147 test is unchanged. Refs diegosouzapw#12732 * test(resilience): list credentialHealthCheck in the configuration-only key set diegosouzapw#12043 added credentialHealthCheck.intervalMinutes to DEFAULT_RESILIENCE_SETTINGS and to the /api/resilience GET projection. It is operator configuration (the background sweep cadence), not runtime breaker state, but the exact key-set assertion was never updated, so resilience-http-e2e failed on the release tip. The providerBreakers/runtime absence checks stay as they were. Refs diegosouzapw#12732 * fix(ci): stamp BUILD_SHA before the release-green pack gate validates check:pack-artifact assembles dist/ through build:cli, which never writes dist/BUILD_SHA (only build:release does). diegosouzapw#12959 pointed the provenance ref at HEAD, but the diegosouzapw#10427 guard still stops at 'dist/BUILD_SHA is missing' before it ever reaches the ancestry check — reproduced on tip + diegosouzapw#13635 + diegosouzapw#13436, the first tree whose Turbopack build compiles. ci.yml sequences build -> stamp -> validate; the validator now does the same in both entry points, keeping PACK_GATE_ENV for the validate step. The guard is unchanged: an unstamped dist/ or one built from another commit still fails. On that tree the stamped gate passes: 'BUILD_SHA 5cb3ae5d9 is on the release line'. Refs diegosouzapw#12732 * docs(env): document OMNIROUTE_SYNCED_CATALOG_STALE_AFTER_MS diegosouzapw#13248 (diegosouzapw#12849) added the override for when a connection's synced model list stops being authoritative, but neither .env.example nor ENVIRONMENT.md lists it, so the env/docs contract gate reports it as code-only. The other five vars that gate reports are already added by diegosouzapw#13635 and diegosouzapw#13361; this touches a different region of .env.example so it does not collide with either. Refs diegosouzapw#12732
…(stryker, CLI i18n, paid-target fixture, call-log traceId, Jina prefix, callLogStats import, gitleaks) (diegosouzapw#13747) * fix(ci): clear the release/v3.8.51 base-reds left by the 09-15 batch — stryker coverage, CLI ready_timeout key, paid-target fixture, call-log traceId, Jina custom prefix Every PR into release/v3.8.51 pushed after diegosouzapw#13635/diegosouzapw#13678 still failed Fast Quality Gates and all four Unit fast-path shards on the same 16 tests. Each one reproduces on the pure tip; none is a product defect: - mutation-test-coverage: noauth-model-lockout and local-token-budget-429-skips-cooldown (diegosouzapw#13606) were missing from stryker.conf.json tap.testFiles. - cli-i18n-catalog: --ready-timeout calls t("serve.ready_timeout") with no catalog entry; added to en, zh-CN and zh-TW (the parity-checked locales). - paid-model-target(-routes)-6540: diegosouzapw#13407 removed Together's one-time credit from the free catalog, so "together/..." classifies as unknown and the save-time guard correctly lets it through. Fixture is now gemini/gemini-3.1-pro-preview, plus a precondition test on the fixtures. - attempt-logging-early-keepalive-merge / video-bridge-log-redaction: diegosouzapw#13546 keys the call-log row on traceId; baseCtx now defaults traceId to pendingRequestId (same pattern as chatcore-attempt-logging). The keepalive test also moves to the 30s wall-clock poll deadline video-bridge uses. - models-catalog-route: custom Jina rows keep the jina-ai/ prefix; diegosouzapw#13403 changed the custom assertion to jina/ (only synced rows use the alias). Refs diegosouzapw#12732 * fix(ci): clear the four reds the first r4 CI run surfaced — callLogStats duplicate import, Uzbek gitleaks false positive, redaction probe traceId, file-size - src/lib/db/callLogStats.ts: the diegosouzapw#13641 merge left ERROR_TYPE_CONTRACT imported twice (TS2300), failing API Route Typecheck and check:dashboard-typecheck on every PR. - .gitleaks.toml: the Uzbek catalog from diegosouzapw#13727 translates outputTokenDesc as "Yakunlash/javob tokenlari"; generic-api-key reads it as a token value. - dashboard-request-failed-redaction-probe: reads the persisted row by traceId (diegosouzapw#13546); with pendingRequestId it asserts null. - models-catalog-route: drop the explanatory comment, which pushed the frozen file over its size cap; the rationale lives in the changelog fragment. Refs diegosouzapw#12732 * fix(ci): re-freeze the two test files diegosouzapw#13748/diegosouzapw#13749 grew past their file-size caps PR-mode check:file-size relaxes source files against the base but not testFrozen, so image-generation-handler.test.ts (2133->2235, diegosouzapw#13748) and batch_api.test.ts (1345->1348, diegosouzapw#13749) failed Fast Quality Gates on every PR, this one included. Caps set to the merged LOC, with the justification entry. Refs diegosouzapw#12732 * fix(ci): register free-badge-provider-gate (diegosouzapw#13645) in stryker tap.testFiles diegosouzapw#13645 landed a covering test for src/sse/services/auth.ts without the stryker entry, so the strict mutation-test-coverage gate went red again. Refs diegosouzapw#12732 * fix(ci): clear two more base-reds the diegosouzapw#13440/diegosouzapw#13439 merges added - stryker.conf.json: register daily-reset-tz-threading (diegosouzapw#13440), which covers accountFallback.ts and rrState.ts. - .gitleaks.toml: allowlist the PROTECTED_PRIORITY_INFRA_502_ENABLED flag id (diegosouzapw#13439); generic-api-key reads its key: as a token (secrets ratchet 0 -> 1). Refs diegosouzapw#12732 * docs(changelog): tidy the stryker base-red fragment wording Refs diegosouzapw#12732
Summary
This clears every inherited red on
release/v3.8.51that shows up on feature PRs today: Docs Gates, Merge integrity, No new ESLint warnings, five Fast Quality Gates, and the 51 failing unit tests in the 4 fast-path shards. I reproduced each failure on the untouched tip152d95108before fixing it. Every fix is cut from that tip, so it merges cleanly, unlike the older sweeps (see Reviewer Notes).Most of the 51 unit failures were tests that went stale after intentional merges. Six were real regressions:
[A-Za-z0-9]{3,}sk[-_]…inSTRONG_CREDENTIAL_TOKENwas unanchored, so on a long alphanumeric run it rescanned from every start position. A 50k run took 1,096 ms incontainsStrongCredentialToken, andsanitizeErrorMessagespent about 40 ms on every long message (under 0.05 ms before fix(security): harden public error boundaries #12506). On loaded CI runners that is what trips thesanitizers.propertyReDoS guard: it failed twice on this PR at 260 to 264 ms against its 250 ms bound, and also today onfix/latch-interchunks. The alternative now carries the same(?<![A-Za-z0-9])lookbehind as its plainsk-sibling. A match of this alternative can only start at the beginning of an alphanumeric run, so the matches are the same: 300,000 fuzzed strings gave identicalreplaceandtestresults for the old and new pattern.sanitizeErrorMessagedrops to about 17 ms, and that remainder is the linear labeled-assignment scanner.error.code/error.type(fix(chat): continue after a server-owned tool on Chat Completions #12867).isAntigravityMissingProjectErrorcould never match, so a config-class Antigravity 422 fell into a generic account cooldown.providerExecutionPipeline.tsnow reads message, code and type from the parsed body and passes them tocreateErrorResult.node:fsto the browser (fix(oauth): align codebuddy-cn OAuth User-Agent with chat/usage (#12702) #13264). The codebuddy-cn registry entry imported the server-onlysrc/lib/oauth/constants/oauth.ts, which pulls incursorAgentCliVersion.ts. Every dashboard route then failed in dev with anode:fsmodule error.CODEBUDDY_CN_USER_AGENTmoved toopen-sse/config/providerHeaderProfiles.ts, where the other CLI user-agent pins live, andoauth.tsre-exports it./v1/modelslisted custom Jina models twice (fix(catalog): union picker customModels into the dispatch-time live catalog (#12597) #12934). Custom models were unioned intogetAllActiveSyncedModels(), a listing-only reader, as well as the dispatch catalog that needed them. Custom models now go only into the dispatch catalog, which fix(backend): chat dispatch ignores model-picker additions (customModels vs syncedAvailableModels) #12597 needs.models.ts→providers.ts→providers/deletion.ts→models.ts(fix(dashboard): list and purge leftover gemini-cli rows #13197).deleteSyncedAvailableModelsForProvidermoved intomodels/syncedAvailableModelPersistence.ts, next to the write helper it already used.models.tsstill re-exports it.@omniroute/opencode-plugin-v2(feat(opencode): opencode v2 plugin publishing the OmniRoute catalog #12870). The package ships throughpackage.jsonfiles, but its prefix was never allowlisted. The prefix is added, plus a test that fails when any shipped@omniroute/*workspace package has no prefix.Related Issues
What was red and why
npm run gen:provider-reference, then the numeral in 6 SVGs, README alt text, AGENTS.md,llm.txt+ 50 mirrors,package.jsondescriptioncheck:agent-skills-syncskills/cli-tunnel/SKILL.mdwith--applyno-explicit-any, 1 unused import__testing.upsertConnectionis already typed) and the unused type importopen-sse-typecheckTS2739 x7provider,model,errorRatepack-policycyclessecrets(1 generic-api-key)sk-internal-test-key-12745fixture in a vitest file undersrc/loopback-internal-key, no allowlist entrymutation-test-coveragetap.testFilesnowMs, ort.mock.timersforDate)persistAttemptLogsredactionstreamBufferBytesGLM_STREAM_BUFFER_BYTESin the last slot/v1/models.env.example.env.exampleNo assertion was removed, skipped or loosened, and no baseline was widened. One ESLint suppression (
combo-strategies.test.ts, the unused import) was pruned because the violation is gone.Validation
npm run lint:json -- --max-warnings 0,npm run typecheck:core,tsc -p open-sse/tsconfig.json(0 errors)quality.ymlrun locally: provider-consistency, provider-asset-provenance, fetch-targets, deps, error-helper, migration-numbering, public-creds, db-rules, known-symbols, route-guard-membership, test-discovery, test-runner-api, any-budget:t11, build-scope, pack-policy, model-lifecycle, cycles, compression-budget,file-size --base-ref,complexity-ratchets --base-ref(complexityNewCode=0, cognitiveComplexityNewCode=0), knip (no new unused exports in touched files),check:secrets --ratchetwith gitleaks 8.30.1 (0 findings), mutation drift (none),check:docs-all,check:api-docs-refs,check:agent-skills-sync,check:changelog-integrityrelease/v3.8.51tip152d95108npm run dev, freshDATA_DIR): login renders and signs in,/dashboard/providers/codebuddy-cnrenders,/api/health/ping200,/v1/models401 without a key, and the dev log has nonode:fsor module-not-found errors. On the tip, the same dashboard routes failed to render.lockfile,duplicationandtype-coveragecould not run on my Windows machine (spawn errors). CI runs them.Tests Added Or Updated
tests/unit/strong-credential-token-linear-scan.test.ts(a 200k alphanumeric run must scan in under 500 ms, and glued-prefix keys are still detected and fully redacted. It failed on the tip), the workspace-package coverage test intests/unit/pack-artifact-policy.test.ts, and R11 intests/unit/upstream-status-restatement.test.tstests/unit/antigravity-missing-project-chat.test.tstests/unit/:chatcore-hierarchical-admission,combo-provider-cooldown-sibling,combo-strategies,dashboard-request-failed-redaction(+tests/fixtures/dashboard-request-failed-redaction-probe.ts),glm-sse-transform-arity,grok-cli-provider-limits,grok-reset-credits-{connection,frame,redeem},hard-session-lease-bypass-inventory,injection-guard-scan-bound-3932,provider-node-reserved-prefix,providers-constants-split,resource-pressure-self-restart,sqljs-build-warning-8135,universal-quota-aware-routing,volcengine-plan-binding-upsert,webpack-create-require-warning,tests/unit/fixtures/error-public-boundaries-hardening.fixture.ts,open-sse/services/autoCombo/__tests__/autoCombo.test.ts,src/lib/memory/__tests__/rerank-loopback-auth-12745.test.ts,tests/snapshots/provider/translate-path.jsonCoverage Notes
providerExecutionPipeline.ts:antigravity-missing-project-chat,provider-execution-pipeline, new R11providerHeaderProfiles.ts,codebuddy-cnregistry/usage,oauth.ts:media-page-client-browser-bundle, the codebuddy-cn provider testsactiveSyncedCatalog.ts:models-catalog-route,custom-models-live-catalog-12597,synced-auto-aliasesmodels.ts,syncedAvailableModelPersistence.ts,providers/deletion.ts:db-synced-model-catalog-invalidation-8728,deprecated-provider-by-provider-cleanup-13067,db-providers-crud,delete-provider-connection-*scripts/build/pack-artifact-policy.ts:pack-artifact-policyopen-sse/utils/errorSanitization.ts:strong-credential-token-linear-scan,error-sanitizer-sk-key-qv45,correctness/sanitizers.property,error-message-sanitization,rule12-error-sanitization-sweep,error-public-boundaries-hardening(67/67)Reviewer Notes
AGENTS.md,llm.txt(+ mirrors) andskills/cli-tunnel/SKILL.mdare in the diff. InAGENTS.mdandllm.txtonly the provider numeral changes (356 to 358). The skill file is generator output. Per the review rules this needs explicit operator approval before merge. Check withgh pr diff <this PR> -- AGENTS.md llm.txt skills/cli-tunnel/SKILL.md.chatCore.tsrewrite. The remaining tests pass without it, andchatCore.tsis untouched here. Items that fix(ci): clear two base-reds on release/v3.8.51 — mutation-coverage gate + image-only-model guard #12945 and fix(tests): align model-sync log assertion to shipped path redaction (base-red #12732) #13227 already landed are not repeated. If this merges first, those four can be closed or rebased down to anything they still add.batch E2E/chatCore compression combo,Package artifactTurbopack build, full unit suite hitting its 4800 s ceiling,provider-family-combosvitest). None of them is on the PR fast path. Theopen-sse/utils/stream.tsfile-size drift is non-blocking and gets rebaselined at release.