Remediate the real findings the now-functional osv-scanner and zizmor gates
surfaced on release/v3.8.26.
Deps (osv-scanner, 2 HIGH -> 0):
- form-data 4.0.5 -> ^4.0.6 (GHSA-hmw2-7cc7-3qxx, transitive via axios)
- vite 8.0.5 -> ^8.0.16 (GHSA-fx2h-pf6j-xcff HIGH + GHSA-v6wh-96g9-6wx3
MODERATE; dev-only via vitest/@vitejs/plugin-react/fumadocs-mdx)
Applied via package.json overrides of existing deps (no new allowlist entry
needed). vulnCount 13 -> 10; build:cli + vitest MCP suite (16 files/187 tests)
green post-bump.
Workflows (zizmor, 195 -> 187):
- env-harden 7 template-injection findings by moving each ${{ ... }} into env:
and referencing "$VAR" in the script (GitHub-documented mitigation):
ci.yml i18n; electron-release.yml validate/build/release steps.
- allowlist 1 dangerous-triggers FP: deploy-vps.yml on:workflow_run is guarded
on conclusion=='success' and deploys via SSH without checking out untrusted
code. Added .zizmor.yml rules.dangerous-triggers.ignore with justification.
Tighten baselines to the improved state (direction: down): vulnCount 13 -> 10,
zizmorFindings 195 -> 187. secretFindings (3) and bundleSize (5601) unchanged.
* 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.)
The headless GitHub macos-arm64 runner crashes Electron's GPU process
(gpu_process_host exit_code=15 → network service crash → no rendezvous
client), so the smoke can't reach 127.0.0.1:20128 in 60s and the whole
job fails → Create Release is skipped → no desktop binaries on the release.
The identical bundle is still smoke-gated on macos-intel + linux, so
per-OS packaging stays verified; extend the existing windows best-effort
exception to macos-arm64 so its runner flakiness no longer blocks releases.
Windows CI requestSingleInstanceLock() reliably fails because the
USERPROFILE sanitization (needed for Next.js build) persists across
steps. The lock mechanism uses a named pipe tied to userData path,
which doesn't work with the synthetic USERPROFILE.
Linux and macOS smoke tests remain required gates.
Windows smoke test exits code=0 because requestSingleInstanceLock()
fails silently when the APPDATA/<productName> directory doesn't exist.
Pre-create the directory so the lock file can be written.
Also enables ELECTRON_SMOKE_STREAM_LOGS=1 in CI for better debugging.
Integrated into release/v3.7.1 — fixes Electron installer shipping empty node_modules. Adds separate extraResources FileSet, CI smoke test job, and cross-platform packaged app validation script. Closes#1636.
- Use ProviderIcon for internal .png paths solving SVG provider 404 images (#745).
- Add id-token: write and packages: write permissions to .github/workflows/electron-release.yml to fix permissions denied failure when calling the reusable workflow npm-publish.yml (#761).
- Fix tests and ESM resolution for autoUpdate.ts override logic.
CI Lint fixes:
- docs/openapi.yaml: bump version 2.2.0 → 2.2.3 (was out of sync with package.json)
- CHANGELOG.md: add '## [Unreleased]' as first section (required by check:docs-sync)
Electron Linux fix:
- electron-release.yml: add 'gem install fpm' step for Linux builds
fpm is required by electron-builder to package .deb installers;
ubuntu-latest runners don't have it pre-installed
Docker publish:
- docker-publish.yml: add DOCKER_BUILDKIT_INLINE_CACHE env; prev 502 was
a transient Docker Hub network error, no code change needed
## CI Fixes
- fix(lint): check:docs-sync — bump docs/openapi.yaml version to 2.1.2 + add [Unreleased] to CHANGELOG
- fix(ci): npm-publish.yml — use 'npm ci --ignore-scripts' to skip prepublishOnly during install, then run prepublish.mjs explicitly with JWT_SECRET; prevents double-build loop that caused all npm CI publishes to fail
- fix(ci): docker-publish.yml — replace two-job digest approach (required ubuntu-24.04-arm, unavailable on public repos) with single-job QEMU-based multi-arch build (linux/amd64 + linux/arm64 on standard ubuntu-latest)
- fix(ci): electron-release.yml — add .deb target to Linux electron-builder, collect .deb files in release-assets step, attach *.deb to GitHub release assets
## Documentation
- fix(docs): README.md language bar — fix 29 broken links (README.<lang>.md → docs/i18n/<lang>/README.md)
- fix(docs): docs/i18n/*/README.md — update back-links to ../../README.md and cross-links between languages
- fix(docs): electron/package.json — add deb target (x64+arm64) to linux build config
- Add 'Sync version in electron/package.json' step before build so
electron-builder names binaries with the correct release version
(was generating OmniRoute-2.0.13.dmg for v2.0.16 release).
- Remove duplicate *-arm64.dmg pattern from release files (*.dmg
already matches arm64 dmg files), which was causing 404 on
overwrite-asset API call.
- Add fail_on_unmatched_files: false so missing .blockmap files
don't fail the release step.
GitHub retired all macos-13 variants. The new officially supported
Intel x64 runner is macos-15-intel (GA since April 2025, supported
until August 2027). This replaces the deprecated macos-13 runner.
macos-13 runner was retired by GitHub Actions infrastructure.
All other platforms (linux, macos-arm64, windows) built successfully.
Using macos-13-large which maintains x64 Intel architecture.
fix(electron-ci): add GH_TOKEN to Build Electron step
- electron-builder requires GH_TOKEN env when publish.provider is
'github'. Without it every build failed with 'GitHub Personal Access
Token is not set'. This was blocking Electron binary generation since
v2.0.11. Fixed by passing secrets.GITHUB_TOKEN to the build step.
fix(images): NanoBanana async task polling (PR #247 by @hijak)
- NanoBanana returns taskId requiring /record-info polling until
successFlag=1 instead of image payload on first response.
- Backward compatible: sync payload path preserved.
- Includes aspect ratio/resolution inference from size field.
fix(ci): security test import + route validation + deploy-vps
- inputSanitizer.js → .ts fix
- validateBody added to acp/agents POST (139 routes pass t06)
- deploy-vps continue-on-error + command_timeout
Version: 2.0.15 → 2.0.16
- Sync electron package.json version with root to fix artifact collection
- Separate mac x64 and arm64 targets into dedicated runner jobs
- Use macos-13 (Intel) runner for x64 build to prevent cross-compilation timeouts
Duplicate release-assets/OmniRoute.exe glob caused softprops/action-gh-release
to attempt a second upload of the same asset, triggering a 404 Not Found error
on the GitHub release asset update API. The file is already covered by the
*.exe glob pattern above it.
electron-builder produces 'OmniRoute 1.6.9.exe' (with version) as the
portable exe, not 'OmniRoute.exe'. The hardcoded check failed, returning
exit code 1 and breaking every Windows build in the release workflow.
Now finds the portable exe by excluding 'Setup' (NSIS installer) and
blockmap files, then copies it as OmniRoute.exe for the release assets.
The Next.js build in electron-release.yml fails because the secrets
validator detects missing JWT_SECRET and exits with code 1. This adds
the env var to the build step, matching the pattern used in ci.yml.
- Trigger on git tags (v*) instead of release.published
- Add manual workflow_dispatch for re-runs
- Add version validation step
- Use artifact upload/download pattern
- Single release job ensures all platforms complete first
- Prevents partial releases if one platform fails