Skip to content

Release v3.8.50 - #8875

Draft
diegosouzapw wants to merge 2297 commits into
mainfrom
release/v3.8.50
Draft

Release v3.8.50#8875
diegosouzapw wants to merge 2297 commits into
mainfrom
release/v3.8.50

Conversation

@diegosouzapw

@diegosouzapw diegosouzapw commented Jul 28, 2026

Copy link
Copy Markdown
Owner

🚀 Release v3.8.50

Living release notes — reconciled 2026-08-14 against the full cycle (cycle open ed2db6cb19 → tip). Mirrors the ## [3.8.50] CHANGELOG section 1:1.

📊 What is in this release

Category Count
✨ New Features 137
🐛 Bug Fixes 449
📝 Maintenance 140
Total documented changes 726

830 commits since the cycle open (892 including merge commits) · 761 merged PRs · 161 credited contributors plus the maintainer.

Highlights: the OmniConductor integration (A2A inbound delegation, fleet skills on the Agent Card, dashboard Conductor panel with Faro push-to-talk voice chat — #8080/#8119/#8221/#8222/#8223), canonical provider-grouped /v1/models ordering (#9215), encrypted reasoning replay opt-in (#9601 via #9876), adaptive admission & overload protection with atomic RPM rolling leases (#9259/#9262), a provider wave (Novita catalog expanded to 19 curated models #8913, UnoRouter #8978, Regolo AI #9031, Openference OAuth #9722, DeepAI multimodal #6671), Electron remote server mode (#8799), the GHE Copilot OAuth lifecycle repair (#8970) plus OpenAI model lifecycle enforcement without silent reroutes (#8627), and the cycle-long TypeScript 7 typing campaign + measured quality-gate ceilings (#9529 and the TS7 series).

🆕 Landed since the 2026-08-12 reconciliation

✅ Reconciliation status — 2026-08-14

Re-reconciled after the cycle advanced by ~105 merged PRs since the 2026-08-12 pass:

node scripts/release/list-uncovered-commits.mjs
# before: 832 commits · covered 683 · uncovered 149
# after:  832 commits · covered 770 · uncovered  62

75 user-facing commits gained a bullet with author attribution; the 45 ref-less direct pushes and 29 chore/ci/test/docs commits were consolidated into rollup bullets. The contributors table grew from 147 to 161 rows — 14 people who had landed work with no credit at all (among them @amartinawi, @pacocartones and @excessivechaos) are now credited. The remaining 62 commits carry no PR/issue ref, which is the ceiling of ref-based coverage.

CHANGELOG.md and its i18n mirrors are now in .prettierignore: check:changelog-integrity compares base bullets as exact strings and Prettier rewrites markdown emphasis inside them (*from*_from_), so any PR that staged the changelog turned the merge-integrity job red.

🔎 Reconciliation notes (2026-08-12)

Coverage was measured over the real cycle range (ed2db6cb19..HEAD, resolved by package.json content, not git describe --tags) with scripts/release/list-uncovered-commits.mjs. The audit found 467 cycle commits with no CHANGELOG bullet and 224 external PRs with no credit (108 people). All closed that day:

  • The [Unreleased] placeholder had no emoji headings, so the fragment aggregator's first-heading match pointed inside the published [3.8.49] section — aggregating would have silently corrupted released notes. The ## [3.8.50] living section was created first, position-proven with the aggregator's own insertBullets, and only then were the 276 pending changelog.d/ fragments folded in.
  • 2 live fragments restored that a stale-sweep had deleted by PR-number collision: the Novita catalog fragment (filename said 8862 — a prior-cycle PR by another author; real PR is Expand the Novita AI model catalog #8913 by @jax-novita) and the catalog provider-grouped ordering fragment (filename said 8072 — the umbrella issue; real PR is fix(models): canonical provider-grouped catalog ordering #9215 by @nguyenha935, confirmed against the PR body).
  • 373 additional merged PRs got reconstructed bullets with author attribution; 59 cherry-pick carrier PRs (cherry-pick(pr-N) / maint: follow-up #N) were re-attributed to the original contributor's own PR number, resolved via the GitHub GraphQL API rather than subject parsing.
  • Coverage after: every commit that carries a PR/issue ref is covered (663 of 728). The remaining 65 are ref-less direct pushes to the release branch (base-red/gate repairs, i18n entity fixes, repo hygiene, CI re-triggers) — documented in dedicated "direct pushes" rollup bullets, which is as far as #ref-based coverage can reach.
  • The contributors table went from ~20 parseable entries to 146 external contributors (365 per-bullet credits); a 10-row sample was verified against the GitHub API (10/10 correct, including one issue-reporter credit). No one was removed.
  • 13 unprefixed changelog.d/ fragments were renamed to the canonical <PR>-<slug>.md (one kept unprefixed: a direct push with no PR).

📖 Full per-PR changelog with author attribution: CHANGELOG.md[3.8.50] — 726 bullets, too large to inline, mirrored across the i18n copies.

@steveepreston

Copy link
Copy Markdown

Hey, please if possible do a release, we are died behind v3.8.48 still

Comment thread open-sse/services/adobeFireflyBrowserLogin.ts Fixed
Comment thread src/app/api/services/dario/admin/import-from-omniroute/route.ts Fixed
Comment thread docker/devin-bridge/network-guard/proxy.mjs Dismissed
Comment thread open-sse/services/raycast.ts Dismissed
Comment thread open-sse/services/raycast.ts Fixed
Comment thread open-sse/services/tokenRefresh/providers/copilot.ts Dismissed
Comment thread scripts/raycast/extract-credentials.mjs Dismissed
Comment thread open-sse/executors/devin-cli-agentic.ts Dismissed
Comment thread open-sse/executors/raycast.ts Fixed
Comment thread open-sse/executors/raycast.ts Dismissed
Comment thread open-sse/services/raycast.ts Dismissed
Comment thread tests/unit/antigravity-quota-host-8965.test.ts Dismissed
Comment thread tests/unit/antigravity-quota-host-8965.test.ts Dismissed
Comment thread tests/unit/antigravity-quota-host-8965.test.ts Dismissed
Comment thread tests/unit/antigravity-quota-host-8965.test.ts Dismissed
Comment thread open-sse/executors/raycast.ts Dismissed
@diegosouzapw

Copy link
Copy Markdown
Owner Author

Thanks for sending this PR. Please resolve mandatory items and retest. Re-open after cleanup if scope/mergeability blocking is fixed.

@diegosouzapw diegosouzapw changed the title Release v3.8.50 [defer] Release v3.8.50 Aug 9, 2026
@diegosouzapw diegosouzapw added merge-train-deferred PR ejetada do merge-train — triagem separada deferred-v3.8.50 Adiada para o ciclo v3.8.50 (validacao VPS, refactor, ou escopo grande) labels Aug 9, 2026
@diegosouzapw

Copy link
Copy Markdown
Owner Author

Thanks for sending this PR. Please resolve mandatory items and retest. Re-open after cleanup if scope/mergeability blocking is fixed.

@diegosouzapw

Copy link
Copy Markdown
Owner Author

test step5

@diegosouzapw

Copy link
Copy Markdown
Owner Author

Thanks for sending this PR. Please resolve mandatory items and retest. Re-open after cleanup if scope/mergeability blocking is fixed.

1 similar comment
@diegosouzapw

Copy link
Copy Markdown
Owner Author

Thanks for sending this PR. Please resolve mandatory items and retest. Re-open after cleanup if scope/mergeability blocking is fixed.

Comment thread open-sse/services/adobeFireflyBrowserLogin.ts Dismissed
Comment thread open-sse/services/adobeFireflyBrowserLogin.ts Fixed
Comment thread open-sse/services/adobeFireflyClient.ts Fixed
Comment thread open-sse/services/adobeFireflyClient.ts Fixed
Comment thread open-sse/services/adobeFireflyClient.ts Fixed
Comment thread open-sse/services/adobeFireflyClient.ts Fixed
Comment thread open-sse/services/adobeFireflySession.ts Dismissed
@diegosouzapw diegosouzapw changed the title [defer] Release v3.8.50 Release v3.8.50 Aug 9, 2026
Comment thread src/shared/middleware/chatBodyAdmission.ts Dismissed
Comment thread src/shared/middleware/chatBodyAdmission.ts Dismissed
backryun and others added 30 commits August 14, 2026 21:00
… language matrix (#10425)

i-have-adhd shipped in #10271 with en + pt-BR only; it now covers vi/ja/id as well,
matching ponytail. Every level keeps the SHARED_BOUNDARIES clause.

Adds a per-MATRIX guard (output-styles-i18n-matrix.test.ts). Every existing test is
per-style, which is how less-code stayed English-only since the 9router port without
anyone noticing. The guard fails on: a new style without pt-BR, a style losing a
translation it had, a translation missing an intensity level, a translation that dropped
the boundaries clause, and a stale KNOWN_ENGLISH_ONLY entry.

Proven by mutation, not just by passing: dropping less-code from the allowlist and
renaming the vi key both turned it red with the expected messages.

less-code stays English-only as declared debt (KNOWN_ENGLISH_ONLY + comment); the
remaining coverage work is tracked in #10426.
…unded (#10423)

* fix(db): prune pre-migration backups so db_backups stops growing unbounded

createPreMigrationBackup() wrote a VACUUM INTO snapshot on every migration run
and never pruned. On a long-lived instance db_backups/ reached 48.999 files /
204 GB against a 5,3 MB live database; a second devbox showed the same shape
(5.711 files / 24 GB).

The retention policy already existed in cleanupDbBackups() but nothing on the
migration path reached it — its only callers are backup.ts and the
/api/db-backups route, neither of which runs during a migration.

migrationRunner.ts cannot import backup.ts: core.ts imports migrationRunner.ts
and backup.ts imports core.ts, so that edge would close a cycle. The policy
therefore moves to a new core-free module, backupRetention.ts, which both call
sites share — cleanupDbBackups() now delegates to it rather than duplicating it.

At the migration call site the operator's maxFiles/retentionDays are read
through the adapter already open for the run; going through getDbInstance()
would re-enter database initialization. Pruning never throws, so housekeeping
cannot fail a migration.

Closes #10421

* chore(db): declare backupRetention as an intentionally-internal db module

check:db-rules requires every src/lib/db/ module to be either re-exported by
localDb.ts or listed in INTENTIONALLY_INTERNAL. backupRetention.ts is a shared
primitive consumed only by db/backup.ts and db/migrationRunner.ts — the same
category as the migrationRunner entry — so it belongs in the allowlist rather
than in the public re-export surface.

* test(db): include backupRetention in the audited INTENTIONALLY_INTERNAL list

check-db-rules-classification.test.ts freezes the exact membership of
INTENTIONALLY_INTERNAL, so adding the 40th entry has to be reflected there too
— the gate script and this test pin the same contract from opposite sides.

---------

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
…429/400/401) (#10112)

* docs: add rate limiting guide for free providers (429/400/401)

Community-reported troubleshooting for auto-discovered issues when
rotating through free/no-auth providers (opencode, felo-web, auggie).
Documents the verified env-var combo that eliminates
intermittent 429/400/401 failures in cron/agent automation:
OMNIROUTE_ROTATE_ON_400=true,
OMNIROUTE_CHAT_MAX_HEAVY_IN_FLIGHT=4,
OMNIROUTE_STRUCTURE_LIMIT=off

Includes root-cause breakdown (provider quota vs passthrough 401 vs
concurrency amplification), verification steps via /monitoring/health,
and escalation for hard quota exhaustion.

* docs(providers): fix fabricated env var and breaker states in rate-limit guide

Replace OMNIROUTE_STRUCTURE_LIMIT (does not exist in the codebase) with
OMNIROUTE_CHAT_ADMISSION_QUEUE_MS and document the real rate-limit knobs
(RATE_LIMIT_MAX_WAIT_MS / RATE_LIMIT_MAX_QUEUE_DEPTH / RATE_LIMIT_AUTO_ENABLE).
Correct the circuit breaker states to the actual enum (CLOSED/DEGRADED/OPEN/HALF_OPEN)
and point the health-check note at circuitBreakers.providerBreakers[].state.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: Bruno <bruno@nousresearch.com>
Co-authored-by: mrcram2021 <mrcram2021@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: adevwithpurpose <adevwithpurpose@users.noreply.github.com>
…e the free-forever number (#10433)

Audit of every numeric claim in the README, AGENTS.md and the README SVGs against
live code, plus a changelog/credit reconciliation over the full v3.8.50 cycle.

Corrected numbers (all measured, not estimated):

- Provider circuit breaker thresholds were scaled up in code for 500+ connection
  deployments (`providerFailureThreshold`: OAuth 3 -> 10, API key 5 -> 15) but the
  docs still published the pre-scale values. Fixed in AGENTS.md (now a table that
  also separates the provider-level threshold from the per-connection one and lists
  the provider cooldowns), in the README alt text and inside resilience-layers.svg
  (visible label and aria-label).
- "40+ free forever" was unsourced. Measured from the free-tier catalog as every
  provider whose free access renews or needs no key (recurring-monthly, -daily,
  -uncapped, -credit, keyless; one-time signup credits and discontinued pools
  excluded): 56. Updated in the README and promise-pillars.svg.
- Cycle-evolution table: v3.8.49 shipped 290 providers, not 291, and the model row
  compared the v3.8.49 free-tier catalog (516) against today's full catalog. Both
  columns now use the same metric - distinct documented models, 1185 -> 1202.
- Tech-stack row: 95 domain modules -> 117.

The free-forever count is now enforced by check:docs-counts so it cannot drift
again; it is derived from freeType in the live catalog, like every other gated
number.

Changelog reconciliation (`scripts/release/list-uncovered-commits.mjs`):
uncovered cycle commits drop from 149 to 62. 75 user-facing commits gained a bullet
with author attribution, the 45 ref-less direct pushes and 29 chore/ci/test/docs
commits were consolidated into rollup bullets, and the contributors table grew from
147 to 161 rows - 14 contributors who had landed work with no credit at all
(including @amartinawi, @pacocartones and @excessivechaos) are now credited.
The remaining 62 carry no PR/issue ref, which is the ceiling of ref-based coverage.

CHANGELOG.md and its i18n mirrors are added to .prettierignore: check:changelog-
integrity compares base bullets as exact strings, and Prettier normalizes markdown
emphasis inside them (*from* -> _from_), so any PR that staged the changelog turned
the merge-integrity job red. scripts/release/* is the changelog's formatter of
record, the same precedent already used for ENVIRONMENT.md and PROVIDER_REFERENCE.md.

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
…oss-cumulative-integration

# Conflicts:
#	README.md
#	docs/diagrams/promise-pillars.svg
Integrates the reviewed F2-F7 and Radar hardening stack into release/v3.8.50 after exact-head CI and freeze gates.
Any process that opened the DB without setting DATA_DIR resolved to ~/.omniroute/storage.sqlite — the operator's live database, provider credentials included. tests/_setup/isolateDataDir.ts only covers the npm scripts; the documented single-file test command and ad-hoc probes bypassed it (one did exactly that during #10334).

resolveWritableDataDir now redirects a test-context process with no DATA_DIR to a throwaway temp dir, stable per process. Redirect rather than throw, so the documented single-file command keeps working; OMNIROUTE_ALLOW_DEFAULT_DATA_DIR=1 opts back in and records the intent.

Closes #10428
…10444)

The packaged artifact stamped dist/BUILD_SHA but nothing verified the SHA belonged to the release line, so a tarball built from a feature branch installed and served traffic indistinguishably from a release build. That is how the internal gateway ended up running a build that predated #10373 and answered every request with 502 'Executor result must contain a Response' — identifying it required SSH plus grepping the compiled chunks.

scripts/build/buildProvenance.ts classifies a build SHA against the release ref (pure functions, injected git probe). A missing SHA fails even with the canary override: an unidentifiable artifact cannot be vouched for. validate-pack-artifact enforces it on real packs (skipped under --policy-only, which runs without a build); OMNIROUTE_ALLOW_CANARY_BUILD=1 records a deliberate off-release-line build instead of failing it. /api/monitoring/health now exposes system.buildSha — absent when unknown, never fabricated.

Closes #10427
…k anchor (#10446)

Deploying the internal gateway was a manual build/pack/scp/npm-i/pm2-restart sequence with no record of what landed and no proof it served traffic. On 2026-08-14 that shipped a package built from a branch predating #10373: the process came up, health said 'healthy', and every request returned 502 until a human hit it.

scripts/ops/deployCanary.ts holds the policy as pure functions — refuse an artifact that is not traceable to the release line (reusing #10427), and grade the deploy on health PLUS at least one real completion. Zero probes fails: 'no probe ran' must never read as 'everything is fine', which is exactly how a broken egress path hides behind a green health check. Remote steps are argv arrays, never shell strings (Hard Rule #13), ordered so the rollback anchor is captured before the install overwrites it.

scripts/ops/deploy-canary.mjs performs the side effects, supports --dry-run, and prints the rollback command when the smoke fails.

Closes #10429
)

* feat(providers): add tencent-aistudio-web cookie provider (tasw)

* fix(sse): remove orphaned DevinDesktopExecutor import from executor index

The "devin-desktop" executor key is unused (devin-desktop provider config
resolves to executor "devin-cli"); the imported ./devin-desktop.ts file
was never present, so executors/index.ts failed to load (ERR_MODULE_NOT_FOUND)
and broke every unit test that imports the executor registry (e.g.
tests/unit/deepseek-web.test.ts). Stale base sync carried this into the branch.
Remove the dead import/registration/export.

* fix(providers): restore DevinDesktopExecutor registration in executor index

The previous commit removed the devin-desktop executor import/registration/
export from open-sse/executors/index.ts, but the devin-desktop provider
registry still resolves executor "devin-desktop" and
tests/unit/devin-providers.test.ts asserts hasSpecializedExecutor("devin-desktop")
is true. The removal broke 6 tests in that file. Restore the three lines so
the live Devin Desktop executor keeps serving the provider.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* fix(providers): correct tencent-aistudio-web wrapper shape + provider count sync

Return {response,url,headers,transformedBody} instead of a raw fetch Response
(the executor contract every other executor in this file follows) and
re-wrap the upstream body so it uses the local Response constructor, not the
undici-patched one from globalThis.fetch.

Regenerate docs/reference/PROVIDER_REFERENCE.md and sync the 339->340
provider-count claims (README, AGENTS.md, llm.txt + 42 i18n mirrors,
package.json, promise-pillars/comparison-table/cli-terminal SVGs) that this
PR's new provider invalidated.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* docs(providers): sync readme-hero.svg provider count claim (339->340)

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* fix(providers): register tencent-aistudio-web web-session credential metadata + golden

Add the WEB_SESSION_CREDENTIAL_REQUIREMENTS entry for tencent-aistudio-web
(cookie-based, matching the executor's raw Cookie-header credential) and
regenerate the translate-path golden snapshot to include the new provider —
both were failing CI unit tests that enumerate every registered provider.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* fix(providers): align tencent-aistudio-web test with the wrapper-shape contract

The test asserted res.status/res.json() directly against executor.execute()'s
return value, matching the pre-fix (broken) raw-Response shape. Update it to
read res.response.status/res.response.json() — the {response,url,headers,
transformedBody} contract every executor in this codebase follows.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: openhands <openhands@all-hands.dev>
Co-authored-by: MeRezaRezaei <MeRezaRezaei@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: adevwithpurpose <adevwithpurpose@users.noreply.github.com>
Co-authored-by: Xiangzhe <bakryun0718@proton.me>
Auto combos (virtual auto/* pools via virtualFactory and pure-auto named
combos via expandAutoComboCandidatePool) expanded their candidate pool from
the provider's STATIC registry catalog, which can include models the operator
never synced or approved (e.g. openrouter/auto). The visibility filter
(getHiddenModelsByProvider) only caught models explicitly flagged isHidden,
so catalog-only models passed through and got routed upstream.

Build the credentialed pool from the models the user actually has available
(synced + custom non-hidden), falling back to the static catalog only when
the operator has no synced/custom models for that provider. Applies to every
provider uniformly (openai, kilocode, openrouter, ...), with per-connection
scoping for synced models. Provider wildcards (providerWildcard.ts) already
used the active synced catalog as the authoritative source.

Regression coverage: tests/unit/combo-auto-pool-visible-only.test.ts

Co-authored-by: herjarsa <herjarsa@users.noreply.github.com>
The upstream Messages API rejects directive-style messages (empty content
array with a message-level output_config) when they sit at messages[0] —
the initial system prompt position — while accepting the form at any other
position. Measured in production: 122x 400 on the offical-claude combo in
one hour.

The mid-conversation-system passthrough (official provider + 1M-context
beta models) keeps system-role messages inside messages[], so a directive
that arrived first went upstream unchanged. relocateDirectiveOnlyMessages()
moves the whole leading run of empty system messages: directive-only ones
past the first real turn, plain empties dropped. extractSystemRoleMessages()
now folds a directive's output_config into the top-level parameter instead
of silently discarding it.

Signed-off-by: Minxi Hou <houminxi@gmail.com>
…h (400 regression) (#10458)

* fix(kilocode): strip unsupported response_format for DeepSeek (400 regression)

kilocode's DeepSeek V4 Flash rejects ANY response_format — both
json_schema AND json_object 400 with 'Invalid input: response_format'
(verified live 2026-08-15 via the Hindsight fact-extraction path on
kilocode/deepseek/deepseek-v4-flash). The default executor's
applyJsonSchemaFallback only covered openai-compatible-* providers and
only downgraded json_schema -> json_object, so kilocode forwarded the
unsupported format raw. Same bug class as the opencode fix #9992.

For kilocode: strip response_format entirely and inject the schema (or a
plain 'valid JSON only' instruction for json_object) into the system
prompt. openai-compatible-* keeps the existing json_schema downgrade and
json_object passthrough (they accept both).

Regression tests: kilocode json_schema is stripped + schema-injected;
kilocode json_object is stripped + JSON-only instruction; both verified
to fail without the fix (sabotage: 2 fail). All 49 executor-default-base
tests pass.

* fix(kilocode): drop as-any casts in new tests to clear the frozen ESLint baseline

The file's frozen no-explicit-any baseline is count 42; the new kilocode
strip tests added 3 net-new 'as any' casts, tripping the --max-warnings 0
lint-guard. Replace them with typed assertions that carry the same checks.

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

---------

Co-authored-by: benzntech <benzntech@users.noreply.github.com>
Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
…exhausted lock (#10445)

* fix(sse): let :free OpenRouter models bypass connection-wide credits_exhausted lock

A 402 from one paid OpenRouter model correctly locks the whole connection
as credits_exhausted for an hour (intentional, per #6842), but that lock
was also blocking every :free model on the same connection even though
OpenRouter bills free models separately from account credits.

Reconstructed clean against release/v3.8.50 by the maintainer: the author's
original branch predated a large auth.ts import refactor; the same delta was
re-applied onto the current tip and the TDD test still passes.

TDD: tests/unit/openrouter-free-model-credits-exhausted.test.ts
reproduces the bug (fails before the fix, passes after) and covers the
three guard cases above.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* test(mutation): register openrouter-free-model-credits-exhausted in stryker tap.testFiles

The new unit test covers src/sse/services/auth.ts, which is one of the 31
stryker-mutated modules — per check-mutation-test-coverage every covering
test must be listed in tap.testFiles or its mutant kills stop counting.
Registered the file so the blocking mutation-test-coverage gate passes.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: killmonger2317-coder <282069920+killmonger2317-coder@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: Xiangzhe <bakryun0718@proton.me>
Implements the secure, opt-in Video Bridge for issue #9760, including bounded FFmpeg frame extraction, capability-aware routing, telemetry, settings UI, localization, documentation, and regression coverage.
resolvePortPid shelled out to lsof alone. On a host without it, spawn
raises ENOENT, the error handler turned that into null, and the caller
could not tell 'nothing holds this port' from 'I have no way to look' -
so a service adopted on a supervisor restart kept pid: null forever,
silently, which is the regression the adopt-branch test guards against.

Probes lsof, then ss, then netstat, sharing one deadline so the whole
lookup still costs at most PID_RESOLVE_TIMEOUT_MS. Output parsing for
each is a pure exported function so the formats are unit-testable
without the binary being installed.

netstat cannot filter by port, so its parser matches the local-address
column rather than scanning the line, keeping a foreign address that
ends in the same number from being read as a listener.
…-status

fix(video-bridge): restore runtime extraction and remote status
…lf-loop

fix(video-bridge): route captions through provider connections
…nks (#10512)

Co-authored-by: Xiangzhe <bakryun0718@proton.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deferred-v3.8.50 Adiada para o ciclo v3.8.50 (validacao VPS, refactor, ou escopo grande) merge-train-deferred PR ejetada do merge-train — triagem separada

Projects

None yet

Development

Successfully merging this pull request may close these issues.