From ec0be07682ba3b3ea4617024c353e2aaaefe447f Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza Date: Sat, 25 Jul 2026 10:35:05 -0300 Subject: [PATCH 1/6] chore(deps): patch js-yaml + postcss for 2 high Dependabot alerts (#8572) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit js-yaml 5.2.1 -> 5.2.2 (GHSA-pm4m-ph32-ghv5, CWE-407: exponential parsing time in flow collections — a <200-byte payload hangs load()). postcss 8.5.14 -> 8.5.23 (GHSA-r28c-9q8g-f849, CWE-22: path traversal via auto-loaded sourceMappingURL discloses arbitrary .map files). Scoped override keeps promptfoo off its exact js-yaml@5.2.1 pin while holding @apidevtools/json-schema-ref-parser on js-yaml ^4.2.0, so the nested override does not major that subtree. Lockfile diff is exactly three versions (plus postcss's own nanoid); nothing added or removed. check:lockfile passes. Closes Dependabot #146 and #148. --- package-lock.json | 24 ++++++++++++------------ package.json | 12 +++++++++--- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index a668a06640..9013afaec5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "ink-text-input": "^6.0.0", "ioredis": "^5.10.1", "jose": "^6.2.3", - "js-yaml": "^5.0.0", + "js-yaml": "^5.2.2", "jsonc-parser": "^3.3.1", "lowdb": "^7.0.1", "lucide-react": "^1.21.0", @@ -103,7 +103,7 @@ "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@types/better-sqlite3": "^7.6.13", - "@types/bun": "*", + "@types/bun": "latest", "@types/node": "^26.1.0", "@types/react": "^19.2.15", "@types/react-dom": "^19.2.3", @@ -23683,9 +23683,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.2.1.tgz", - "integrity": "sha512-zfLtNfQqxVqq3uaTqSkh4x4hZw3KHobGUA0fJUj4wawW8bsQLTVqpHdXSIzidh7o+4lEW36tANuAGdaFx6Zgnw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-5.2.2.tgz", + "integrity": "sha512-dayzUzKkJ1MkuUtZglSebU43utNXH0OWQByK9rKOOuYIO8M5TV1y+n8ALMdG0rdzBnfNkOmZEqrURepb0ejqBw==", "funding": [ { "type": "github", @@ -27778,9 +27778,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", "funding": [ { "type": "github", @@ -30080,9 +30080,9 @@ } }, "node_modules/postcss": { - "version": "8.5.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", - "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "funding": [ { "type": "opencollective", @@ -30099,7 +30099,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, diff --git a/package.json b/package.json index 80b95385ca..acfa0e9336 100644 --- a/package.json +++ b/package.json @@ -265,7 +265,7 @@ "ink-text-input": "^6.0.0", "ioredis": "^5.10.1", "jose": "^6.2.3", - "js-yaml": "^5.0.0", + "js-yaml": "^5.2.2", "jsonc-parser": "^3.3.1", "lowdb": "^7.0.1", "lucide-react": "^1.21.0", @@ -394,7 +394,7 @@ "dompurify": "^3.4.12", "fast-xml-parser": "^5.10.1", "sharp": "^0.35.0", - "postcss": "^8.5.14", + "postcss": "^8.5.18", "ip-address": "10.2.0", "qs": "^6.15.2", "uuid": "^14.0.0", @@ -418,6 +418,12 @@ "concurrently": { "shell-quote": "^1.9.0" }, - "adm-zip": "^0.6.0" + "adm-zip": "^0.6.0", + "promptfoo": { + "js-yaml": "^5.2.2", + "@apidevtools/json-schema-ref-parser": { + "js-yaml": "^4.2.0" + } + } } } From 278640b438799e0adaff7a04ba974282216f3b86 Mon Sep 17 00:00:00 2001 From: MumuTW <42820974+MumuTW@users.noreply.github.com> Date: Sat, 25 Jul 2026 22:10:33 +0800 Subject: [PATCH 2/6] chore(ci): resync stale no-explicit-any suppression count for proxy-registry.test.ts (#8544) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(ci): resync stale no-explicit-any suppression count for proxy-registry.test.ts tests/unit/proxy-registry.test.ts is frozen at 55 no-explicit-any violations but only has 54 since #8447 (d7f947586) removed one. ESLint fails the run with "There are suppressions left that do not occur anymore", making `npm run lint` exit 2 on release/v3.8.49 for every PR that branches off it. Same class as #8007 / #8490, different file: no code to fix here — the count simply drifted down, so this resyncs it via --prune-suppressions. Base-red inherited from release/v3.8.49; both the suppressions file and proxy-registry.test.ts are byte-identical to that branch. * docs(changelog): add fragment for this PR --- .../maintenance/lint-suppression-resync-proxy-registry.md | 1 + config/quality/eslint-suppressions.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 changelog.d/maintenance/lint-suppression-resync-proxy-registry.md diff --git a/changelog.d/maintenance/lint-suppression-resync-proxy-registry.md b/changelog.d/maintenance/lint-suppression-resync-proxy-registry.md new file mode 100644 index 0000000000..f6a8269335 --- /dev/null +++ b/changelog.d/maintenance/lint-suppression-resync-proxy-registry.md @@ -0,0 +1 @@ +- chore(ci): resync the stale `no-explicit-any` suppression count for `tests/unit/proxy-registry.test.ts` (frozen at 55, actual 54 since #8447) — ESLint was failing the whole run with "There are suppressions left that do not occur anymore", turning `npm run lint` red on `release/v3.8.49` for every PR branched off it diff --git a/config/quality/eslint-suppressions.json b/config/quality/eslint-suppressions.json index ae3515df20..6ce99f9919 100644 --- a/config/quality/eslint-suppressions.json +++ b/config/quality/eslint-suppressions.json @@ -1937,7 +1937,7 @@ }, "tests/unit/proxy-registry.test.ts": { "@typescript-eslint/no-explicit-any": { - "count": 55 + "count": 54 } }, "tests/unit/proxy-resolution-status-filter.test.ts": { From d06d3fb67d8e2194559ece9a868c48ce9006b0d7 Mon Sep 17 00:00:00 2001 From: MumuTW <42820974+MumuTW@users.noreply.github.com> Date: Sat, 25 Jul 2026 22:10:44 +0800 Subject: [PATCH 3/6] test(sse): update three backoff assertions stale since the #8396 cooldown cap (#8539) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These three cases assert that a transient-error cooldown keeps doubling to baseCooldownMs * 2^maxLevel — roughly 45.5h at the default constants. That is precisely the blackout #8396 removed: capScaledCooldownMs (open-sse/services/accountFallback/cooldownCap.ts) now bounds every scaled cooldown by profile.maxCooldownMs, falling back to BACKOFF_CONFIG.max when the profile does not configure one. All three call checkFallbackError with a null provider, so the fallback ceiling applies and the observed value is BACKOFF_CONFIG.max. The backoff-level clamping each case was written to guard is unchanged and still asserted; only the expected duration moved. The expressions keep the original formula wrapped in the cap so the relationship stays readable, and the first case gains a precondition assertion so it cannot silently become vacuous if the constants change. Fixes the error-classification (x2) and thundering-herd (x1) failures that are red on release/v3.8.49 at its own HEAD. --- tests/unit/error-classification.test.ts | 18 ++++++++++++++++-- tests/unit/thundering-herd.test.ts | 8 +++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/tests/unit/error-classification.test.ts b/tests/unit/error-classification.test.ts index bc267a4050..90d18f7c4d 100644 --- a/tests/unit/error-classification.test.ts +++ b/tests/unit/error-classification.test.ts @@ -98,13 +98,21 @@ test("502 transient: exponential backoff doubles until the configured max backof assert.equal(result.newBackoffLevel, level + 1); assert.equal(result.reason, RateLimitReason.SERVER_ERROR); } + // #8396: the scaled cooldown is now clamped by capScaledCooldownMs + // (open-sse/services/accountFallback/cooldownCap.ts). With no provider the + // ceiling is BACKOFF_CONFIG.max, so the doubling stops there instead of + // running on to transientInitial * 32. + assert.ok( + COOLDOWN_MS.transientInitial * 32 > BACKOFF_CONFIG.max, + "precondition: the 6th step must exceed the cap, or this test proves nothing" + ); assert.deepEqual(cooldowns, [ COOLDOWN_MS.transientInitial, COOLDOWN_MS.transientInitial * 2, COOLDOWN_MS.transientInitial * 4, COOLDOWN_MS.transientInitial * 8, COOLDOWN_MS.transientInitial * 16, - COOLDOWN_MS.transientInitial * 32, + BACKOFF_CONFIG.max, ]); }); @@ -237,8 +245,14 @@ test("subscription quota uses long cooldown when upstream retry hints are disabl test("high transient backoff levels clamp to the configured maxBackoffSteps", () => { const result = checkFallbackError(502, "", BACKOFF_CONFIG.maxLevel + 5, null, null); assert.equal(result.newBackoffLevel, BACKOFF_CONFIG.maxLevel); + // #8396: the level still clamps at maxLevel, but the resulting duration is + // additionally capped — unclamped this would be ~45.5h, which is the blackout + // that PR removed. assert.equal( result.cooldownMs, - COOLDOWN_MS.transientInitial * Math.pow(2, BACKOFF_CONFIG.maxLevel) + Math.min( + COOLDOWN_MS.transientInitial * Math.pow(2, BACKOFF_CONFIG.maxLevel), + BACKOFF_CONFIG.max + ) ); }); diff --git a/tests/unit/thundering-herd.test.ts b/tests/unit/thundering-herd.test.ts index e3af4f81f1..140efa04a6 100644 --- a/tests/unit/thundering-herd.test.ts +++ b/tests/unit/thundering-herd.test.ts @@ -39,9 +39,15 @@ test("API profile has shorter transient cooldown", () => { test("Exponential backoff clamps to the configured maxBackoffLevel", () => { const result = checkFallbackError(502, "", 20, null, null); assert.equal(result.newBackoffLevel, BACKOFF_CONFIG.maxLevel); + // #8396: the level still clamps at maxLevel, but capScaledCooldownMs also + // bounds the duration — with no provider profile the ceiling is + // BACKOFF_CONFIG.max rather than the unbounded baseCooldownMs * 2^level. assert.equal( result.cooldownMs, - COOLDOWN_MS.transientInitial * Math.pow(2, BACKOFF_CONFIG.maxLevel) + Math.min( + COOLDOWN_MS.transientInitial * Math.pow(2, BACKOFF_CONFIG.maxLevel), + BACKOFF_CONFIG.max + ) ); }); From c447be4329f8e2c536a413404b612d425328b555 Mon Sep 17 00:00:00 2001 From: MumuTW <42820974+MumuTW@users.noreply.github.com> Date: Sat, 25 Jul 2026 22:10:48 +0800 Subject: [PATCH 4/6] fix(db): classify compressionDetailNormalizers as db-internal in check-db-rules (#8534) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(db): classify compressionDetailNormalizers as db-internal in check-db-rules check:db-rules fails on release/v3.8.49 at its own HEAD: the module added by #8404 is neither re-exported from localDb.ts nor listed in INTENTIONALLY_INTERNAL, so the gate blocks every PR->release run and tests/unit/check-db-rules.test.ts fails its live-repo case. Its only importer is its sibling src/lib/db/compression.ts, via a relative import inside src/lib/db/ — the db-internal classification the list already uses for apiKeyColumnFallbacks and caseMapping. Re-exporting it from localDb.ts would instead advertise pure normalizer helpers as part of the compat surface, which Hard Rule #2 discourages. * test(db): mirror compressionDetailNormalizers in the INTENTIONALLY_INTERNAL audit The classification guard asserts the exact audited set. Adding the module to check-db-rules.mjs without the mirror left the exact-list/exact-size assertion red; both assertions stay exact (37 entries). Co-authored-by: diegosouzapw --------- Co-authored-by: diegosouzapw --- scripts/check/check-db-rules.mjs | 1 + tests/unit/check-db-rules-classification.test.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/check/check-db-rules.mjs b/scripts/check/check-db-rules.mjs index f90417be78..cc348d69f5 100644 --- a/scripts/check/check-db-rules.mjs +++ b/scripts/check/check-db-rules.mjs @@ -48,6 +48,7 @@ export const INTENTIONALLY_INTERNAL = new Set([ "comboForecast", // intentionally-internal: src/lib/usage/comboForecast.ts "commandCodeAuth", // intentionally-internal: 5 API routes em /api/providers/command-code/auth/* "compression", // intentionally-internal: 2 API routes (settings/compression, context/rtk/config) + "compressionDetailNormalizers", // db-internal: importado só por db/compression.ts (normalizeSessionDedupConfig/normalizeCcrConfig/buildDetailConfigDefaults/applyDetailConfigUpdate — normalizadores do detail-config split do compression.ts, #8404) "vacuumScheduler", // intentionally-internal: src/instrumentation-node.ts (dynamic import, lifecycle wiring per Rule #2) "detailedLogs", // intentionally-internal: 3 callers (callLogs.ts, logs/detail route, embeddings handler) "discovery", // DEAD?: 0 importers na auditoria de 2026-06-11; lib/discovery/index.ts não usa db/discovery diff --git a/tests/unit/check-db-rules-classification.test.ts b/tests/unit/check-db-rules-classification.test.ts index d04935e71e..3c22485d1c 100644 --- a/tests/unit/check-db-rules-classification.test.ts +++ b/tests/unit/check-db-rules-classification.test.ts @@ -121,7 +121,7 @@ test("INTENTIONALLY_INTERNAL is exported from check-db-rules.mjs", () => { assert.ok(INTENTIONALLY_INTERNAL.size > 0, "INTENTIONALLY_INTERNAL must not be empty"); }); -test("INTENTIONALLY_INTERNAL contains the expected 36 audited modules", () => { +test("INTENTIONALLY_INTERNAL contains the expected 37 audited modules", () => { const expected = [ "_rowTypes", "accessTokens", @@ -133,6 +133,7 @@ test("INTENTIONALLY_INTERNAL contains the expected 36 audited modules", () => { "comboForecast", "commandCodeAuth", "compression", + "compressionDetailNormalizers", "detailedLogs", "discovery", "domainState", From cc63ac9f53d59b412166549436ac0b8b35b364ae Mon Sep 17 00:00:00 2001 From: MumuTW <42820974+MumuTW@users.noreply.github.com> Date: Sat, 25 Jul 2026 22:10:52 +0800 Subject: [PATCH 5/6] test(sse): register #8396 and #8376 unit tests in stryker tap.testFiles (#8538) * test(sse): register #8396 and #8376 unit tests in stryker tap.testFiles check:mutation-test-coverage fails on release/v3.8.49 at its own HEAD: two unit tests cover mutated modules but are absent from tap.testFiles, so their mutant kills do not count and the drift gate blocks every PR->release run. - tests/unit/8396-cooldown-429-cap.test.ts covers open-sse/services/accountFallback.ts (imports checkFallbackError) - tests/unit/8376-econnrefused-breaker.test.ts covers open-sse/services/combo/comboPredicates.ts (imports shouldRecordProviderBreakerFailure) Both inserted in the array's existing sorted position; no other key touched. * test(sse): register repro-7503-no-choices in stryker tap.testFiles --- stryker.conf.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stryker.conf.json b/stryker.conf.json index 557e4d1031..342fd18fa5 100644 --- a/stryker.conf.json +++ b/stryker.conf.json @@ -49,6 +49,8 @@ "tests/unit/8247-accountfallback-model-unhealthy.test.ts", "tests/unit/8248-accountfallback-nvidia-degraded.test.ts", "tests/unit/8332-combo-vision-fallback.test.ts", + "tests/unit/8376-econnrefused-breaker.test.ts", + "tests/unit/8396-cooldown-429-cap.test.ts", "tests/unit/account-fallback-anthropic-quota.test.ts", "tests/unit/account-fallback-lockout-eviction.test.ts", "tests/unit/account-fallback-retry-after-json.test.ts", @@ -251,6 +253,7 @@ "tests/unit/rate-limit-enhanced.test.ts", "tests/unit/rate-limit-manager.test.ts", "tests/unit/rate-limit-queue-timeout-lockout.test.ts", + "tests/unit/repro-7503-no-choices.test.ts", "tests/unit/repro-antigravity-404-family-cooldown-hijack.test.ts", "tests/unit/responses-handler.test.ts", "tests/unit/rotation-config-omniroute.test.ts", From 4053e2314a1cc1b4caba96c0d72bf614c0c38eb3 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 25 Jul 2026 17:25:14 +0300 Subject: [PATCH 6/6] chore(quality): rebaseline file-size for inherited base growth (#8561) check:file-size fails on the pristine release/v3.8.49 tip (30709255), which takes the whole Fast Quality Gates job down for every PR against the branch. Both offenders grew after the last rebaseline (_rebaseline_2026_07_25_v3849_basered_filesize, measured at 36f8fd10) and both came from already-merged PRs, so there is no offending branch left to fix: src/lib/tokenHealthCheck.ts 841 -> 843 (#8426, 4528fc455) src/app/(dashboard)/dashboard/providers/page.tsx 1927 -> 1990 (#8349, 58ab8b1d2) Trust-but-verify: both values measured on the pristine tip with an empty working tree. Same situation and remedy as the entry cited above and as _rebaseline_2026_07_02_5798_release_green. This commit is deliberately last and self-contained: drop it if the captain would rather move the frozen values separately. Structural reduction of the 1990-line providers page is not attempted here. Co-authored-by: alexey.nazarov@softmg.ru Co-authored-by: Claude Opus 5 --- config/quality/file-size-baseline.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/config/quality/file-size-baseline.json b/config/quality/file-size-baseline.json index 3656958eeb..a76747350b 100644 --- a/config/quality/file-size-baseline.json +++ b/config/quality/file-size-baseline.json @@ -253,7 +253,7 @@ "src/app/(dashboard)/dashboard/providers/[id]/hooks/useProviderSettings.ts": 264, "src/app/(dashboard)/dashboard/providers/[id]/providerPageHelpers.ts": 1054, "src/app/(dashboard)/dashboard/providers/components/onboarding/ProviderOnboardingWizard.tsx": 948, - "src/app/(dashboard)/dashboard/providers/page.tsx": 1927, + "src/app/(dashboard)/dashboard/providers/page.tsx": 1990, "src/app/(dashboard)/dashboard/runtime/RuntimePageClient.tsx": 1201, "src/app/(dashboard)/dashboard/settings/components/AppearanceTab.tsx": 819, "src/app/(dashboard)/dashboard/settings/components/ComboDefaultsTab.tsx": 903, @@ -324,7 +324,7 @@ "open-sse/executors/huggingchat.ts": 813, "_rebaseline_2026_07_01_v3843_release_5609": "Rebaseline v3.8.43 (PR #5609 release reconciliation). DRIFT dos 109 commits do ciclo: 8 god-files existentes cresceram (ApiManagerPageClient 2983->3017, combos/page 4594->4608, AddApiKeyModal 868->869, providerPageHelpers 974->996, chat.ts 1635->1647, auth.ts 2401->2403, batchProcessor 828->915, combo.ts 3368->3387) + 2 novos acima do cap (huggingchat.ts 813, tests web-cookie-providers-new 827) + 4 test files cresceram. Modularizacao deferida (blast-radius mid-release); congelado no estado atual p/ o proximo ciclo ratchetar daqui.", "src/lib/providers/validation/webProvidersA.ts": 809, - "src/lib/tokenHealthCheck.ts": 841, + "src/lib/tokenHealthCheck.ts": 843, "_rebaseline_2026_07_09_6587_kiro_api_key_auth": "PR #6587 (@strangersp) own growth for Kiro long-lived API-key auth, merged onto v3.8.47 tip: openai-to-kiro.ts 890->912 (+22, auth-header selection for API-key-vs-OAuth-token connections), providerLimits.ts 998->1000 (+2, API-key auth-type branch), translator-openai-to-kiro.test.ts 1234->1257 (+23), providers-page-utils.test.ts 1109->1107 (net -2 after merging with parallel release drift; connectionMatchesProviderCard api_key coverage added), provider-validation-specialty.test.ts 2856->2980 (+124 net after merge with parallel release drift; this PR also removed the file's `@typescript-eslint/no-explicit-any` eslint-suppression entry by fixing all `any` usages, adding typed replacements). Cohesive additive feature growth, well tested; not extractable without splitting the existing chokepoints mid-merge.", "_rebaseline_2026_07_19_7787_ic2_localdb_reexports": "PR #7787 (IC2 raw connections cache + lazy-decrypt) own growth: localDb.ts 805->807 (gate units, +2). localDb.ts is the re-export-only layer (hard rule #2 — no logic); the PR adds 4 new db/readCache re-exports (touchConnectionLastUsed, getCachedRawProviderConnections, getCachedProviderConnectionById, getCachedProviderNodes) required by existing barrel importers. Irreducible for a re-export list; frozen so it can only shrink.", "_rebaseline_2026_07_20_7819_autocandidateoverrides_reexport": "PR for #7819 (Level 1+2: read-only auto/* candidate transparency + per-API-key exclusions) own growth: localDb.ts 807->808 (+1). Adds a single `export * from \"./db/autoCandidateOverrides\"` barrel re-export (hard rule #2 — no logic) for the new DB module backing per-apiKey candidate exclusions. Irreducible for a re-export list; frozen so it can only shrink.", @@ -470,5 +470,6 @@ "_rebaseline_2026_07_23_v3849_merge_train_15": "Own-growth do merge-train de 15 PRs (2026-07-23), medido na tip combinada, release pura abaixo do baseline (auth.ts 2448, muse-spark 1393, translator-test 1523). auth.ts 2462->2475 (#8321 cookie-auth 401 cooldown-em-vez-de-terminal + #8324 noauth opencode-zen via proxy — wiring de classificação no chokepoint getProviderCredentials/markAccountUnavailable, não extraível), muse-spark-web.ts 1394->1396 (#8298 sanitizeErrorMessage runtime repairs isolados do #8177), tests/unit/translator-openai-to-gemini.test.ts 1553->1616 (#8312 cobertura do cap de thinking budget no path budget_tokens explícito). Owner-approved. Frozen; shrink estrutural em #3501.", "_rebaseline_2026_07_22_providerLimits_webcookie_chain": "providerLimits.ts 1003->1005: own-growth from web-cookie provider usage-fetcher entries (#7994/#8006/#8027 chain) landing after the prior rebaseline.", "_rebaseline_2026_07_22_8056_headroom_minrows": "#8056 (@RaviTharuma, persist Headroom minRows) own growth: src/lib/db/compression.ts 850->866 (+16 HeadroomConfig+DEFAULT_HEADROOM_CONFIG+normalize/store in get/updateCompressionSettings) and open-sse/services/compression/strategySelector.ts 1054->1060 (+6 merge settings.headroom into stacked stepConfig). Cohesive settings-persistence + stacked-merge wiring at existing chokepoints, frozen at new size.", - "_rebaseline_2026_07_25_v3849_basered_filesize": "Base-red unblock (2026-07-25): check:file-size was failing on release/v3.8.49 at its own HEAD (36f8fd10), so the quality.yml fast-gates job was red for EVERY PR->release regardless of content — growth inherited from already-merged PRs, with no offending PR branch left to fix (same situation as _rebaseline_2026_07_02_5798_release_green). Prod frozen raised to the current base values: src/lib/tokenHealthCheck.ts 832->841, src/sse/handlers/chat.ts 1865->1866, src/sse/services/auth.ts 2475->2486, open-sse/services/accountFallback.ts 1941->1966, open-sse/services/combo.ts 3630->3642. accountFallback.ts was first frozen here at 1960 (the base value at 36f8fd10) and re-measured to 1966 at base tip 1cafd328c a few hours later — the same inherited drift this entry exists for, since check:file-size does not run on the PR->release fast path and so accrues unmeasured between release rebaselines. These files remain frozen and cannot grow further; any in-flight PR that adds lines to them (e.g. #8482 touches accountFallback.ts and combo.ts) bumps its own entry as usual. The release captain rebaseline-at-release supersedes this note." + "_rebaseline_2026_07_25_v3849_basered_filesize": "Base-red unblock (2026-07-25): check:file-size was failing on release/v3.8.49 at its own HEAD (36f8fd10), so the quality.yml fast-gates job was red for EVERY PR->release regardless of content — growth inherited from already-merged PRs, with no offending PR branch left to fix (same situation as _rebaseline_2026_07_02_5798_release_green). Prod frozen raised to the current base values: src/lib/tokenHealthCheck.ts 832->841, src/sse/handlers/chat.ts 1865->1866, src/sse/services/auth.ts 2475->2486, open-sse/services/accountFallback.ts 1941->1966, open-sse/services/combo.ts 3630->3642. accountFallback.ts was first frozen here at 1960 (the base value at 36f8fd10) and re-measured to 1966 at base tip 1cafd328c a few hours later — the same inherited drift this entry exists for, since check:file-size does not run on the PR->release fast path and so accrues unmeasured between release rebaselines. These files remain frozen and cannot grow further; any in-flight PR that adds lines to them (e.g. #8482 touches accountFallback.ts and combo.ts) bumps its own entry as usual. The release captain rebaseline-at-release supersedes this note.", + "_rebaseline_2026_07_25_v3849_basered_filesize_2": "Base-red unblock (2026-07-25, second pass): after _rebaseline_2026_07_25_v3849_basered_filesize (measured at 36f8fd10) two more already-merged PRs grew frozen files on release/v3.8.49, so check:file-size — and with it the whole Fast Quality Gates job — is red for EVERY PR->release again, with no offending PR branch left to fix. src/lib/tokenHealthCheck.ts 841->843 (#8426 4528fc455, excludes local CLI providers from expiration) and src/app/(dashboard)/dashboard/providers/page.tsx 1927->1990 (#8349 58ab8b1d2, scroll-position restore on provider-card back-navigation). Trust-but-verify: both values measured on the pristine release tip 30709255 with no working-tree changes. Same situation and remedy as _rebaseline_2026_07_02_5798_release_green. Structural reduction of providers/page.tsx stays tracked separately — it is a 1990-line page, not something to extract inside a base-repair PR." }