Skip to content

fix(combo): return replay response in round-robin to avoid locked stream 500 - #3811

Merged
diegosouzapw merged 3 commits into
cheaper-inference:release/v3.8.25from
0xtbug:main
Jun 14, 2026
Merged

diegosouzapw merged 3 commits into
cheaper-inference:release/v3.8.25from
0xtbug:main

Conversation

@0xtbug

@0xtbug 0xtbug commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Summary

When a combo using the round-robin strategy served a streaming response, the
endpoint returned a 500 even though the upstream provider call succeeded and quota
was available. The combo's validateResponseQuality() peeks streaming bodies via
response.body.getReader() to detect empty/content-filtered streams. That call
locks result.body and hands back a replay stream in quality.clonedResponse.

The priority strategy already returns quality.clonedResponse ?? result, but the
round-robin path returned the original (now-locked) result. Next.js then failed to
pipe it (TypeError: Invalid state: The ReadableStream is locked,
ERR_INVALID_STATE) and surfaced a 500. Non-combo chat was unaffected because it
never runs quality validation.

This change makes the round-robin success path return quality.clonedResponse ?? result,
mirroring the priority strategy.

Before

Zed_sipxZVETXM

After

Zed_UshZnODwcf

Related Issues

  • Closes #
  • Related to

Validation

  • npm run lint
  • npm run test:unit
  • npm run test:coverage
  • Coverage is still >= 60% for statements, lines, functions, and branches
  • SonarQube PR analysis is green or any remaining issues are explicitly documented below

Tests Added Or Updated

  • No automated tests added in this PR. The change is a one-line return-value fix in the
    round-robin combo path; recommend a follow-up streaming-combo regression test that asserts
    the returned Response body is unlocked and forwards buffered + remaining SSE chunks.

Coverage Notes

  • Touches open-sse/services/combo.ts only. The fix is exercised by any combo using the
    round-robin strategy with a streaming (text/event-stream) response — it now returns the
    replay stream produced by validateResponseQuality instead of the locked original.
  • No coverage regression expected; no lines were removed, only the returned value was corrected.

Reviewer Notes

  • Risk area: streaming response lifecycle in combo.ts. The replay stream
    (buildReplayResponse) re-emits buffered prefix chunks then forwards the original reader,
    so byte-for-byte output is preserved.
  • Behavior now matches the priority strategy path (return { ok: true, response: quality.clonedResponse ?? result }).
  • The 499 client-disconnect early-return in round-robin is unchanged and safe — it lives in
    the !result.ok branch, so validateResponseQuality never ran and the body was never locked.
  • Manual validation: send a streaming request through a round-robin combo and confirm a 200
    with the full streamed body instead of a 500.

…eam 500

validateResponseQuality peeks streaming bodies via getReader(), locking result.body and returning a replay stream in quality.clonedResponse. The round-robin success path returned the original locked result, causing Next.js to throw 'ReadableStream is locked' and surface a 500 on combo routes despite a successful upstream call. Mirror the priority strategy by returning quality.clonedResponse ?? result.
@0xtbug
0xtbug requested a review from diegosouzapw as a code owner June 14, 2026 04:14
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@diegosouzapw
diegosouzapw changed the base branch from main to release/v3.8.25 June 14, 2026 11:42
diegosouzapw and others added 2 commits June 14, 2026 09:37
…r-inference#3811)

Round-robin combos serving a streaming response must return the unlocked
quality.clonedResponse, not the original result whose body was locked by
validateResponseQuality's getReader() peek. Fails (body locked) without the
one-line fix, passes with it.

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
@diegosouzapw
diegosouzapw merged commit 5ace548 into cheaper-inference:release/v3.8.25 Jun 14, 2026
1 check passed
@diegosouzapw

Copy link
Copy Markdown
Collaborator

Merged into release/v3.8.25 🎉 — thanks @0xtbug! Excellent root-cause: validateResponseQuality() locks result.body via getReader() and hands back the replay in quality.clonedResponse, and the round-robin path was returning the locked original (priority already did the right thing). I added a regression test that fails (body locked) without your one-line fix and passes with it, crediting you as author. Validated: typecheck + lint clean. Ships in v3.8.25. 🙌

diegosouzapw added a commit to artickc/OmniRoute that referenced this pull request Jun 14, 2026
…inference#3835)

pricing.ts 1470→1508 (own growth: missing Kiro rows). Also carries inherited
release/v3.8.25 drift (RequestLoggerV2.tsx 1276→1282 cheaper-inference#3820, combo.ts 5198→5203
cheaper-inference#3811) so Fast Quality Gates passes on the current base.

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
diegosouzapw added a commit that referenced this pull request Jun 15, 2026
…ributors

Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section
was missing: a New Features section (compression engines + Compression Studios
#3848, compression UI #3860, injection-guard #3857, kiro discovery #3836, Veo
#3839, mimocode proxy #3837, Arena ELO flag #3821), 9 more Fixed entries
(#3811/#3807/#3759/#3849/#3838/#3835/#3814/#3820/#3819), a Security section
(CCR IDOR #3859, supply-chain #3824), and an Internal/Quality section. Every
contributor and issue reporter is now credited.
@diegosouzapw diegosouzapw mentioned this pull request Jun 15, 2026
diegosouzapw added a commit that referenced this pull request Jun 15, 2026
* chore(release): continue v3.8.25 development cycle after main code-sync (r5)

main fast-forwarded to release/v3.8.25 (#3863): unblocked Build+Docker via
#3864, plus #3837 (mimocode proxy) and #3862 (trivy bump). This marker
re-opens the umbrella PR for further v3.8.25 work. No version bump.

* fix(db): persist the Keep-latest-backups retention setting (#3834) (#3867)

* fix(oauth): clear GitLab Duo setup message instead of 500 (#3861) (#3868)

* test(oauth): prove refresh_token preserved on real gemini-cli/antigravity dispatch (#3850) (#3869)

* feat(compression-ui): unified compression config UI — per-engine pages + combos editor + menu + WS default-on (#3860)

Integrated into release/v3.8.25 — feat(compression-ui): unified compression configuration UI (Compression Hub + per-engine Lite/Aggressive/Ultra pages + combos editor + sidebar entry + live-WS default-on). File-size re-baselined for sidebarVisibility.ts/chatCore.ts growth; orphan ws test relocated to a collected path.

* docs(changelog): complete the v3.8.25 release notes + credit all contributors

Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section
was missing: a New Features section (compression engines + Compression Studios
#3848, compression UI #3860, injection-guard #3857, kiro discovery #3836, Veo
#3839, mimocode proxy #3837, Arena ELO flag #3821), 9 more Fixed entries
(#3811/#3807/#3759/#3849/#3838/#3835/#3814/#3820/#3819), a Security section
(CCR IDOR #3859, supply-chain #3824), and an Internal/Quality section. Every
contributor and issue reporter is now credited.

* docs(changelog): restore + complete the v3.8.25 release notes

Re-adds CHANGELOG.md (a prior server-side commit accidentally dropped it) with
the complete, audited [3.8.25] section: New Features, the full Fixed list,
Security & Hardening, and Internal/Quality — every contributor and issue
reporter credited.

* chore(release): finalize v3.8.25 — reconcile CHANGELOG + i18n mirrors, document OMNIROUTE_MAX_PENDING_MIGRATIONS, green the unit suite

Release-gate reconciliation for v3.8.25:
- CHANGELOG: dated 2026-06-14, linked #3826, rolled up file-size re-baselines (#3823/#3833),
  recorded the test-greening; re-synced all 41 i18n CHANGELOG mirrors.
- Documented OMNIROUTE_MAX_PENDING_MIGRATIONS (#3416) in .env.example + ENVIRONMENT.md.
- Greened the unit suite (was merged red on 4 CI shards): aligned 10 stale tests to this
  cycle's intended behavior (#3838/#3822/#3501/SOCKS5/Vertex-Express/Antigravity) and the
  same-provider 503 fall-through test; de-flaked the compression benchmark reproducibility
  and ServiceSupervisor crash tests. No production code changed.

* ci(security): clear OpenSSF Scorecard code-scanning noise + harden workflow token permissions

The Security tab held 155 open alerts, ALL from the advisory OpenSSF Scorecard tool
(#3824) — supply-chain/posture scores, not code vulnerabilities — which drowned out
real CodeQL findings.

- scorecard.yml: stop uploading SARIF to the code-scanning tab (drop the upload-sarif
  step + the now-unused security-events: write). The run still produces the OpenSSF
  badge (publish_results) and a downloadable SARIF artifact.
- TokenPermissions hardening (the high-severity, genuinely-valuable subset): set each
  workflow's top-level token to read-only and grant the exact writes at the job level
  that needs them — npm-publish (id-token/packages on publish jobs), docker-publish
  (packages on build), electron-release (contents on build/release, id-token/packages
  on publish-npm), build-fork (packages on build), claude (empty top-level; job grants
  its own). The 155 existing alerts were dismissed.

Not adopting repo-wide SHA-pinning (143 PinnedDependencies advisories) — declined.

* test(integration): align stale wiring/socks5 integration tests to this cycle's behavior

These were red on the CI Integration job (pre-existing). No production code changed:
- integration-wiring: the combos page no longer renders a per-page EmailPrivacyToggle
  (#3822 consolidated it into Settings → Appearance); the provider-detail test-result
  masking and upstream-proxy copy moved to decomposed components (#3501
  BatchTestResultsModal / UpstreamProxyCard) — assertions now read the owning files.
- api-routes-critical: SOCKS5 is now enabled by default (opt-out), so the disabled-
  rejection test must set ENABLE_SOCKS5_PROXY=false explicitly (an unset env now means
  enabled).

(The ~32 live-Gemini integration tests are gated on OMNIROUTE_API_KEY and skip in CI;
they only 'fail' locally when that key is present without a running server.)
@diegosouzapw diegosouzapw mentioned this pull request Jun 16, 2026
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
…aper-inference#3811)

A round-robin combo serving a streaming response returned a 500
(TypeError: ReadableStream is locked). validateResponseQuality() peeks streaming
bodies via getReader(), which locks result.body and returns an unlocked replay in
quality.clonedResponse. The priority strategy already returns
`quality.clonedResponse ?? result`, but the round-robin success path returned the
locked original. This mirrors the priority strategy so the body pipes downstream.

Added a regression test (cheaper-inference#3811) that fails (body locked) without the fix.

Integrated into release/v3.8.25.

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
* chore(release): continue v3.8.25 development cycle after main code-sync (r5)

main fast-forwarded to release/v3.8.25 (cheaper-inference#3863): unblocked Build+Docker via
cheaper-inference#3864, plus cheaper-inference#3837 (mimocode proxy) and cheaper-inference#3862 (trivy bump). This marker
re-opens the umbrella PR for further v3.8.25 work. No version bump.

* fix(db): persist the Keep-latest-backups retention setting (cheaper-inference#3834) (cheaper-inference#3867)

* fix(oauth): clear GitLab Duo setup message instead of 500 (cheaper-inference#3861) (cheaper-inference#3868)

* test(oauth): prove refresh_token preserved on real gemini-cli/antigravity dispatch (cheaper-inference#3850) (cheaper-inference#3869)

* feat(compression-ui): unified compression config UI — per-engine pages + combos editor + menu + WS default-on (cheaper-inference#3860)

Integrated into release/v3.8.25 — feat(compression-ui): unified compression configuration UI (Compression Hub + per-engine Lite/Aggressive/Ultra pages + combos editor + sidebar entry + live-WS default-on). File-size re-baselined for sidebarVisibility.ts/chatCore.ts growth; orphan ws test relocated to a collected path.

* docs(changelog): complete the v3.8.25 release notes + credit all contributors

Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section
was missing: a New Features section (compression engines + Compression Studios
cheaper-inference#3848, compression UI cheaper-inference#3860, injection-guard cheaper-inference#3857, kiro discovery cheaper-inference#3836, Veo
cheaper-inference#3839, mimocode proxy cheaper-inference#3837, Arena ELO flag cheaper-inference#3821), 9 more Fixed entries
(cheaper-inference#3811/cheaper-inference#3807/cheaper-inference#3759/cheaper-inference#3849/cheaper-inference#3838/cheaper-inference#3835/cheaper-inference#3814/cheaper-inference#3820/cheaper-inference#3819), a Security section
(CCR IDOR cheaper-inference#3859, supply-chain cheaper-inference#3824), and an Internal/Quality section. Every
contributor and issue reporter is now credited.

* docs(changelog): restore + complete the v3.8.25 release notes

Re-adds CHANGELOG.md (a prior server-side commit accidentally dropped it) with
the complete, audited [3.8.25] section: New Features, the full Fixed list,
Security & Hardening, and Internal/Quality — every contributor and issue
reporter credited.

* chore(release): finalize v3.8.25 — reconcile CHANGELOG + i18n mirrors, document OMNIROUTE_MAX_PENDING_MIGRATIONS, green the unit suite

Release-gate reconciliation for v3.8.25:
- CHANGELOG: dated 2026-06-14, linked cheaper-inference#3826, rolled up file-size re-baselines (cheaper-inference#3823/cheaper-inference#3833),
  recorded the test-greening; re-synced all 41 i18n CHANGELOG mirrors.
- Documented OMNIROUTE_MAX_PENDING_MIGRATIONS (cheaper-inference#3416) in .env.example + ENVIRONMENT.md.
- Greened the unit suite (was merged red on 4 CI shards): aligned 10 stale tests to this
  cycle's intended behavior (cheaper-inference#3838/cheaper-inference#3822/cheaper-inference#3501/SOCKS5/Vertex-Express/Antigravity) and the
  same-provider 503 fall-through test; de-flaked the compression benchmark reproducibility
  and ServiceSupervisor crash tests. No production code changed.

* ci(security): clear OpenSSF Scorecard code-scanning noise + harden workflow token permissions

The Security tab held 155 open alerts, ALL from the advisory OpenSSF Scorecard tool
(cheaper-inference#3824) — supply-chain/posture scores, not code vulnerabilities — which drowned out
real CodeQL findings.

- scorecard.yml: stop uploading SARIF to the code-scanning tab (drop the upload-sarif
  step + the now-unused security-events: write). The run still produces the OpenSSF
  badge (publish_results) and a downloadable SARIF artifact.
- TokenPermissions hardening (the high-severity, genuinely-valuable subset): set each
  workflow's top-level token to read-only and grant the exact writes at the job level
  that needs them — npm-publish (id-token/packages on publish jobs), docker-publish
  (packages on build), electron-release (contents on build/release, id-token/packages
  on publish-npm), build-fork (packages on build), claude (empty top-level; job grants
  its own). The 155 existing alerts were dismissed.

Not adopting repo-wide SHA-pinning (143 PinnedDependencies advisories) — declined.

* test(integration): align stale wiring/socks5 integration tests to this cycle's behavior

These were red on the CI Integration job (pre-existing). No production code changed:
- integration-wiring: the combos page no longer renders a per-page EmailPrivacyToggle
  (cheaper-inference#3822 consolidated it into Settings → Appearance); the provider-detail test-result
  masking and upstream-proxy copy moved to decomposed components (cheaper-inference#3501
  BatchTestResultsModal / UpstreamProxyCard) — assertions now read the owning files.
- api-routes-critical: SOCKS5 is now enabled by default (opt-out), so the disabled-
  rejection test must set ENABLE_SOCKS5_PROXY=false explicitly (an unset env now means
  enabled).

(The ~32 live-Gemini integration tests are gated on OMNIROUTE_API_KEY and skip in CI;
they only 'fail' locally when that key is present without a running server.)
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
…aper-inference#3811)

A round-robin combo serving a streaming response returned a 500
(TypeError: ReadableStream is locked). validateResponseQuality() peeks streaming
bodies via getReader(), which locks result.body and returns an unlocked replay in
quality.clonedResponse. The priority strategy already returns
`quality.clonedResponse ?? result`, but the round-robin success path returned the
locked original. This mirrors the priority strategy so the body pipes downstream.

Added a regression test (cheaper-inference#3811) that fails (body locked) without the fix.

Integrated into release/v3.8.25.

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
* chore(release): continue v3.8.25 development cycle after main code-sync (r5)

main fast-forwarded to release/v3.8.25 (cheaper-inference#3863): unblocked Build+Docker via
cheaper-inference#3864, plus cheaper-inference#3837 (mimocode proxy) and cheaper-inference#3862 (trivy bump). This marker
re-opens the umbrella PR for further v3.8.25 work. No version bump.

* fix(db): persist the Keep-latest-backups retention setting (cheaper-inference#3834) (cheaper-inference#3867)

* fix(oauth): clear GitLab Duo setup message instead of 500 (cheaper-inference#3861) (cheaper-inference#3868)

* test(oauth): prove refresh_token preserved on real gemini-cli/antigravity dispatch (cheaper-inference#3850) (cheaper-inference#3869)

* feat(compression-ui): unified compression config UI — per-engine pages + combos editor + menu + WS default-on (cheaper-inference#3860)

Integrated into release/v3.8.25 — feat(compression-ui): unified compression configuration UI (Compression Hub + per-engine Lite/Aggressive/Ultra pages + combos editor + sidebar entry + live-WS default-on). File-size re-baselined for sidebarVisibility.ts/chatCore.ts growth; orphan ws test relocated to a collected path.

* docs(changelog): complete the v3.8.25 release notes + credit all contributors

Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section
was missing: a New Features section (compression engines + Compression Studios
cheaper-inference#3848, compression UI cheaper-inference#3860, injection-guard cheaper-inference#3857, kiro discovery cheaper-inference#3836, Veo
cheaper-inference#3839, mimocode proxy cheaper-inference#3837, Arena ELO flag cheaper-inference#3821), 9 more Fixed entries
(cheaper-inference#3811/cheaper-inference#3807/cheaper-inference#3759/cheaper-inference#3849/cheaper-inference#3838/cheaper-inference#3835/cheaper-inference#3814/cheaper-inference#3820/cheaper-inference#3819), a Security section
(CCR IDOR cheaper-inference#3859, supply-chain cheaper-inference#3824), and an Internal/Quality section. Every
contributor and issue reporter is now credited.

* docs(changelog): restore + complete the v3.8.25 release notes

Re-adds CHANGELOG.md (a prior server-side commit accidentally dropped it) with
the complete, audited [3.8.25] section: New Features, the full Fixed list,
Security & Hardening, and Internal/Quality — every contributor and issue
reporter credited.

* chore(release): finalize v3.8.25 — reconcile CHANGELOG + i18n mirrors, document OMNIROUTE_MAX_PENDING_MIGRATIONS, green the unit suite

Release-gate reconciliation for v3.8.25:
- CHANGELOG: dated 2026-06-14, linked cheaper-inference#3826, rolled up file-size re-baselines (cheaper-inference#3823/cheaper-inference#3833),
  recorded the test-greening; re-synced all 41 i18n CHANGELOG mirrors.
- Documented OMNIROUTE_MAX_PENDING_MIGRATIONS (cheaper-inference#3416) in .env.example + ENVIRONMENT.md.
- Greened the unit suite (was merged red on 4 CI shards): aligned 10 stale tests to this
  cycle's intended behavior (cheaper-inference#3838/cheaper-inference#3822/cheaper-inference#3501/SOCKS5/Vertex-Express/Antigravity) and the
  same-provider 503 fall-through test; de-flaked the compression benchmark reproducibility
  and ServiceSupervisor crash tests. No production code changed.

* ci(security): clear OpenSSF Scorecard code-scanning noise + harden workflow token permissions

The Security tab held 155 open alerts, ALL from the advisory OpenSSF Scorecard tool
(cheaper-inference#3824) — supply-chain/posture scores, not code vulnerabilities — which drowned out
real CodeQL findings.

- scorecard.yml: stop uploading SARIF to the code-scanning tab (drop the upload-sarif
  step + the now-unused security-events: write). The run still produces the OpenSSF
  badge (publish_results) and a downloadable SARIF artifact.
- TokenPermissions hardening (the high-severity, genuinely-valuable subset): set each
  workflow's top-level token to read-only and grant the exact writes at the job level
  that needs them — npm-publish (id-token/packages on publish jobs), docker-publish
  (packages on build), electron-release (contents on build/release, id-token/packages
  on publish-npm), build-fork (packages on build), claude (empty top-level; job grants
  its own). The 155 existing alerts were dismissed.

Not adopting repo-wide SHA-pinning (143 PinnedDependencies advisories) — declined.

* test(integration): align stale wiring/socks5 integration tests to this cycle's behavior

These were red on the CI Integration job (pre-existing). No production code changed:
- integration-wiring: the combos page no longer renders a per-page EmailPrivacyToggle
  (cheaper-inference#3822 consolidated it into Settings → Appearance); the provider-detail test-result
  masking and upstream-proxy copy moved to decomposed components (cheaper-inference#3501
  BatchTestResultsModal / UpstreamProxyCard) — assertions now read the owning files.
- api-routes-critical: SOCKS5 is now enabled by default (opt-out), so the disabled-
  rejection test must set ENABLE_SOCKS5_PROXY=false explicitly (an unset env now means
  enabled).

(The ~32 live-Gemini integration tests are gated on OMNIROUTE_API_KEY and skip in CI;
they only 'fail' locally when that key is present without a running server.)
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…ributors

Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section
was missing: a New Features section (compression engines + Compression Studios
cheaper-inference#3848, compression UI cheaper-inference#3860, injection-guard cheaper-inference#3857, kiro discovery cheaper-inference#3836, Veo
cheaper-inference#3839, mimocode proxy cheaper-inference#3837, Arena ELO flag cheaper-inference#3821), 9 more Fixed entries
(cheaper-inference#3811/cheaper-inference#3807/cheaper-inference#3759/cheaper-inference#3849/cheaper-inference#3838/cheaper-inference#3835/cheaper-inference#3814/cheaper-inference#3820/cheaper-inference#3819), a Security section
(CCR IDOR cheaper-inference#3859, supply-chain cheaper-inference#3824), and an Internal/Quality section. Every
contributor and issue reporter is now credited.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…aper-inference#3811)

A round-robin combo serving a streaming response returned a 500
(TypeError: ReadableStream is locked). validateResponseQuality() peeks streaming
bodies via getReader(), which locks result.body and returns an unlocked replay in
quality.clonedResponse. The priority strategy already returns
`quality.clonedResponse ?? result`, but the round-robin success path returned the
locked original. This mirrors the priority strategy so the body pipes downstream.

Added a regression test (cheaper-inference#3811) that fails (body locked) without the fix.

Integrated into release/v3.8.25.

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
* chore(release): continue v3.8.25 development cycle after main code-sync (r5)

main fast-forwarded to release/v3.8.25 (cheaper-inference#3863): unblocked Build+Docker via
cheaper-inference#3864, plus cheaper-inference#3837 (mimocode proxy) and cheaper-inference#3862 (trivy bump). This marker
re-opens the umbrella PR for further v3.8.25 work. No version bump.

* fix(db): persist the Keep-latest-backups retention setting (cheaper-inference#3834) (cheaper-inference#3867)

* fix(oauth): clear GitLab Duo setup message instead of 500 (cheaper-inference#3861) (cheaper-inference#3868)

* test(oauth): prove refresh_token preserved on real gemini-cli/antigravity dispatch (cheaper-inference#3850) (cheaper-inference#3869)

* feat(compression-ui): unified compression config UI — per-engine pages + combos editor + menu + WS default-on (cheaper-inference#3860)

Integrated into release/v3.8.25 — feat(compression-ui): unified compression configuration UI (Compression Hub + per-engine Lite/Aggressive/Ultra pages + combos editor + sidebar entry + live-WS default-on). File-size re-baselined for sidebarVisibility.ts/chatCore.ts growth; orphan ws test relocated to a collected path.

* docs(changelog): complete the v3.8.25 release notes + credit all contributors

Audited every commit since v3.8.24 and filled the gaps the [3.8.25] section
was missing: a New Features section (compression engines + Compression Studios
cheaper-inference#3848, compression UI cheaper-inference#3860, injection-guard cheaper-inference#3857, kiro discovery cheaper-inference#3836, Veo
cheaper-inference#3839, mimocode proxy cheaper-inference#3837, Arena ELO flag cheaper-inference#3821), 9 more Fixed entries
(cheaper-inference#3811/cheaper-inference#3807/cheaper-inference#3759/cheaper-inference#3849/cheaper-inference#3838/cheaper-inference#3835/cheaper-inference#3814/cheaper-inference#3820/cheaper-inference#3819), a Security section
(CCR IDOR cheaper-inference#3859, supply-chain cheaper-inference#3824), and an Internal/Quality section. Every
contributor and issue reporter is now credited.

* docs(changelog): restore + complete the v3.8.25 release notes

Re-adds CHANGELOG.md (a prior server-side commit accidentally dropped it) with
the complete, audited [3.8.25] section: New Features, the full Fixed list,
Security & Hardening, and Internal/Quality — every contributor and issue
reporter credited.

* chore(release): finalize v3.8.25 — reconcile CHANGELOG + i18n mirrors, document OMNIROUTE_MAX_PENDING_MIGRATIONS, green the unit suite

Release-gate reconciliation for v3.8.25:
- CHANGELOG: dated 2026-06-14, linked cheaper-inference#3826, rolled up file-size re-baselines (cheaper-inference#3823/cheaper-inference#3833),
  recorded the test-greening; re-synced all 41 i18n CHANGELOG mirrors.
- Documented OMNIROUTE_MAX_PENDING_MIGRATIONS (cheaper-inference#3416) in .env.example + ENVIRONMENT.md.
- Greened the unit suite (was merged red on 4 CI shards): aligned 10 stale tests to this
  cycle's intended behavior (cheaper-inference#3838/cheaper-inference#3822/cheaper-inference#3501/SOCKS5/Vertex-Express/Antigravity) and the
  same-provider 503 fall-through test; de-flaked the compression benchmark reproducibility
  and ServiceSupervisor crash tests. No production code changed.

* ci(security): clear OpenSSF Scorecard code-scanning noise + harden workflow token permissions

The Security tab held 155 open alerts, ALL from the advisory OpenSSF Scorecard tool
(cheaper-inference#3824) — supply-chain/posture scores, not code vulnerabilities — which drowned out
real CodeQL findings.

- scorecard.yml: stop uploading SARIF to the code-scanning tab (drop the upload-sarif
  step + the now-unused security-events: write). The run still produces the OpenSSF
  badge (publish_results) and a downloadable SARIF artifact.
- TokenPermissions hardening (the high-severity, genuinely-valuable subset): set each
  workflow's top-level token to read-only and grant the exact writes at the job level
  that needs them — npm-publish (id-token/packages on publish jobs), docker-publish
  (packages on build), electron-release (contents on build/release, id-token/packages
  on publish-npm), build-fork (packages on build), claude (empty top-level; job grants
  its own). The 155 existing alerts were dismissed.

Not adopting repo-wide SHA-pinning (143 PinnedDependencies advisories) — declined.

* test(integration): align stale wiring/socks5 integration tests to this cycle's behavior

These were red on the CI Integration job (pre-existing). No production code changed:
- integration-wiring: the combos page no longer renders a per-page EmailPrivacyToggle
  (cheaper-inference#3822 consolidated it into Settings → Appearance); the provider-detail test-result
  masking and upstream-proxy copy moved to decomposed components (cheaper-inference#3501
  BatchTestResultsModal / UpstreamProxyCard) — assertions now read the owning files.
- api-routes-critical: SOCKS5 is now enabled by default (opt-out), so the disabled-
  rejection test must set ENABLE_SOCKS5_PROXY=false explicitly (an unset env now means
  enabled).

(The ~32 live-Gemini integration tests are gated on OMNIROUTE_API_KEY and skip in CI;
they only 'fail' locally when that key is present without a running server.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants