Skip to content

fix(ci): clear the release/v3.8.51 base-reds on the PR fast path - #13635

Merged
diegosouzapw merged 21 commits into
diegosouzapw:release/v3.8.51from
dpozimski:fix/release-v3.8.51-basereds
Sep 15, 2026
Merged

diegosouzapw merged 21 commits into
diegosouzapw:release/v3.8.51from
dpozimski:fix/release-v3.8.51-basereds

Conversation

@dpozimski

@dpozimski dpozimski commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This clears every inherited red on release/v3.8.51 that shows up on feature PRs today: Docs Gates, Merge integrity, No new ESLint warnings, five Fast Quality Gates, and the 51 failing unit tests in the 4 fast-path shards. I reproduced each failure on the untouched tip 152d95108 before fixing it. Every fix is cut from that tip, so it merges cleanly, unlike the older sweeps (see Reviewer Notes).

⚠️ base-red inherited: #12732

Most of the 51 unit failures were tests that went stale after intentional merges. Six were real regressions:

  • Error redaction ran a quadratic regex (fix(security): harden public error boundaries #12506). The glued-prefix alternative [A-Za-z0-9]{3,}sk[-_]… in STRONG_CREDENTIAL_TOKEN was unanchored, so on a long alphanumeric run it rescanned from every start position. A 50k run took 1,096 ms in containsStrongCredentialToken, and sanitizeErrorMessage spent about 40 ms on every long message (under 0.05 ms before fix(security): harden public error boundaries #12506). On loaded CI runners that is what trips the sanitizers.property ReDoS guard: it failed twice on this PR at 260 to 264 ms against its 250 ms bound, and also today on fix/latch-interchunks. The alternative now carries the same (?<![A-Za-z0-9]) lookbehind as its plain sk- sibling. A match of this alternative can only start at the beginning of an alphanumeric run, so the matches are the same: 300,000 fuzzed strings gave identical replace and test results for the old and new pattern. sanitizeErrorMessage drops to about 17 ms, and that remainder is the linear labeled-assignment scanner.
  • Provider pipeline dropped the upstream error.code / error.type (fix(chat): continue after a server-owned tool on Chat Completions #12867). isAntigravityMissingProjectError could never match, so a config-class Antigravity 422 fell into a generic account cooldown. providerExecutionPipeline.ts now reads message, code and type from the parsed body and passes them to createErrorResult.
  • The provider detail page shipped node:fs to the browser (fix(oauth): align codebuddy-cn OAuth User-Agent with chat/usage (#12702) #13264). The codebuddy-cn registry entry imported the server-only src/lib/oauth/constants/oauth.ts, which pulls in cursorAgentCliVersion.ts. Every dashboard route then failed in dev with a node:fs module error. CODEBUDDY_CN_USER_AGENT moved to open-sse/config/providerHeaderProfiles.ts, where the other CLI user-agent pins live, and oauth.ts re-exports it.
  • /v1/models listed custom Jina models twice (fix(catalog): union picker customModels into the dispatch-time live catalog (#12597) #12934). Custom models were unioned into getAllActiveSyncedModels(), a listing-only reader, as well as the dispatch catalog that needed them. Custom models now go only into the dispatch catalog, which fix(backend): chat dispatch ignores model-picker additions (customModels vs syncedAvailableModels) #12597 needs.
  • Import cycle models.ts → providers.ts → providers/deletion.ts → models.ts (fix(dashboard): list and purge leftover gemini-cli rows #13197). deleteSyncedAvailableModelsForProvider moved into models/syncedAvailableModelPersistence.ts, next to the write helper it already used. models.ts still re-exports it.
  • Pack policy rejected @omniroute/opencode-plugin-v2 (feat(opencode): opencode v2 plugin publishing the OmniRoute catalog #12870). The package ships through package.json files, but its prefix was never allowlisted. The prefix is added, plus a test that fails when any shipped @omniroute/* workspace package has no prefix.

Related Issues

What was red and why

Gate / test Cause Fix
Docs Gates: provider count 356 vs 358 EURouter #13025 and GreenPT #13024 npm run gen:provider-reference, then the numeral in 6 SVGs, README alt text, AGENTS.md, llm.txt + 50 mirrors, package.json description
Merge integrity: check:agent-skills-sync #13009 surfaced positional args regenerated skills/cli-tunnel/SKILL.md with --apply
ESLint: 3 no-explicit-any, 1 unused import test files removed the casts (__testing.upsertConnection is already typed) and the unused type import
open-sse-typecheck TS2739 x7 #12731 fixtures missing provider, model, errorRate filled with values identical across each comparison, so rankings are unaffected
pack-policy #12870 prefix + coverage test (above)
cycles #13197 function move (above)
secrets (1 generic-api-key) sk-internal-test-key-12745 fixture in a vitest file under src/ plain label loopback-internal-key, no allowlist entry
mutation-test-coverage 11 covering tests missing from tap.testFiles added
grok reset-credit tests (11) #12805 fixtures use a real token that expired 2026-09-12 fixed clock inside the captured grant/expiry window (decoder nowMs, or t.mock.timers for Date)
reset-aware strategy tests (12) #13006 now skips pinned connections with no active DB row tests create real connections
Antigravity missing-project 422 #12867 production fix (above)
composite slot, R10 restatement, combo cooldown source guard code moved by #12867, #13069 and the combo split guards follow the new files and are at least as strict. Added R11 for the pipeline
hard-lease inventory new sites from #13069, #13259, #12653 counts updated
persistAttemptLogs redaction #12506 redacts stored call-log errors on purpose asserts the exact redacted string
GLM arity #12925 added streamBufferBytes call arity must equal helper arity, with GLM_STREAM_BUFFER_BYTES in the last slot
GOLDEN translate-path arcee-ai #13277, eurouter, greenpt regenerated. +69 lines, no existing row changed
APIKEY count 238, reserved prefix set size #13024, #13025, #13277 240 and 412, each with a history line
Jina duplicate in /v1/models #12934 production fix (above)
vi / pt-BR / zh-TW locale tests #13270, #13287, #13288 added untranslated keys; #13034 used a retired zh-TW term 7 vi keys, 4 pt-BR keys, 3 zh-TW values back to 提供者
env/doc contract (2 tests) 6 vars documented in ENVIRONMENT.md but missing from .env.example added to .env.example
provider detail bundle #13264 production fix (above)
sqljs #8135, webpack warning, 16 KB injection cap, public error boundaries #13035, #13272, #13104, #13069 changed these contracts on purpose guards narrowed to the original hazard, or re-pointed at the moved code

No assertion was removed, skipped or loosened, and no baseline was widened. One ESLint suppression (combo-strategies.test.ts, the unused import) was pruned because the violation is gone.

Validation

  • Change type: other (base-red sweep across routing, DB, i18n, build policy, docs)
  • Focused tests: the 35 files that held the 51 failures plus the new tests, 344/344 on this branch (50 failing on the tip). Sibling suites for every changed production module: 1502 tests across 228 chatCore/combo/pipeline files, 190 catalog tests across 23 files, 181 i18n tests, 85 DB provider/model tests.
  • npm run lint:json -- --max-warnings 0, npm run typecheck:core, tsc -p open-sse/tsconfig.json (0 errors)
  • Gate loop from quality.yml run locally: provider-consistency, provider-asset-provenance, fetch-targets, deps, error-helper, migration-numbering, public-creds, db-rules, known-symbols, route-guard-membership, test-discovery, test-runner-api, any-budget:t11, build-scope, pack-policy, model-lifecycle, cycles, compression-budget, file-size --base-ref, complexity-ratchets --base-ref (complexityNewCode=0, cognitiveComplexityNewCode=0), knip (no new unused exports in touched files), check:secrets --ratchet with gitleaks 8.30.1 (0 findings), mutation drift (none), check:docs-all, check:api-docs-refs, check:agent-skills-sync, check:changelog-integrity
  • Cut from the current release/v3.8.51 tip 152d95108
  • Production-code changes include a test: the Antigravity 422 test, the provider detail bundle test and the Jina catalog test each failed on the tip and pass here, and the new pack-policy coverage test fails without the prefix
  • e2e on localhost (npm run dev, fresh DATA_DIR): login renders and signs in, /dashboard/providers/codebuddy-cn renders, /api/health/ping 200, /v1/models 401 without a key, and the dev log has no node:fs or module-not-found errors. On the tip, the same dashboard routes failed to render.

lockfile, duplication and type-coverage could not run on my Windows machine (spawn errors). CI runs them.

Tests Added Or Updated

  • Added: tests/unit/strong-credential-token-linear-scan.test.ts (a 200k alphanumeric run must scan in under 500 ms, and glued-prefix keys are still detected and fully redacted. It failed on the tip), the workspace-package coverage test in tests/unit/pack-artifact-policy.test.ts, and R11 in tests/unit/upstream-status-restatement.test.ts
  • Unchanged but now passing as the regression test for the pipeline fix: tests/unit/antigravity-missing-project-chat.test.ts
  • Updated under tests/unit/: chatcore-hierarchical-admission, combo-provider-cooldown-sibling, combo-strategies, dashboard-request-failed-redaction (+ tests/fixtures/dashboard-request-failed-redaction-probe.ts), glm-sse-transform-arity, grok-cli-provider-limits, grok-reset-credits-{connection,frame,redeem}, hard-session-lease-bypass-inventory, injection-guard-scan-bound-3932, provider-node-reserved-prefix, providers-constants-split, resource-pressure-self-restart, sqljs-build-warning-8135, universal-quota-aware-routing, volcengine-plan-binding-upsert, webpack-create-require-warning, tests/unit/fixtures/error-public-boundaries-hardening.fixture.ts, open-sse/services/autoCombo/__tests__/autoCombo.test.ts, src/lib/memory/__tests__/rerank-loopback-auth-12745.test.ts, tests/snapshots/provider/translate-path.json

Coverage Notes

  • providerExecutionPipeline.ts: antigravity-missing-project-chat, provider-execution-pipeline, new R11
  • providerHeaderProfiles.ts, codebuddy-cn registry/usage, oauth.ts: media-page-client-browser-bundle, the codebuddy-cn provider tests
  • activeSyncedCatalog.ts: models-catalog-route, custom-models-live-catalog-12597, synced-auto-aliases
  • models.ts, syncedAvailableModelPersistence.ts, providers/deletion.ts: db-synced-model-catalog-invalidation-8728, deprecated-provider-by-provider-cleanup-13067, db-providers-crud, delete-provider-connection-*
  • scripts/build/pack-artifact-policy.ts: pack-artifact-policy
  • open-sse/utils/errorSanitization.ts: strong-credential-token-linear-scan, error-sanitizer-sk-key-qv45, correctness/sanitizers.property, error-message-sanitization, rule12-error-sanitization-sweep, error-public-boundaries-hardening (67/67)

Reviewer Notes

…ce module to break the models/providers cycle
… modules and refresh the translate-path golden
@dpozimski dpozimski closed this Sep 14, 2026
@dpozimski dpozimski reopened this Sep 14, 2026
@dpozimski

Copy link
Copy Markdown
Contributor Author

@diegosouzapw the PR focuses to fix existing issues in 3.8.51 branch

@diegosouzapw

Copy link
Copy Markdown
Owner

Heads-up: this now conflicts with release/v3.8.51. Two base-red PRs landed today with overlapping fixes, so git can no longer merge it: #13349 (the #12867 provider-pipeline error.code/error.type restoration, the listing-only custom-models union, the hierarchical-admission and lease-inventory tests) and #12959 (pack policy, doc counts). Conflicting files against the current tip 895dda383:

  • open-sse/handlers/chatCore/providerExecutionPipeline.ts
  • open-sse/services/autoCombo/__tests__/autoCombo.test.ts
  • scripts/build/pack-artifact-policy.ts
  • src/lib/db/models/activeSyncedCatalog.ts
  • tests/unit/chatcore-hierarchical-admission.test.ts

Several pieces here are not on the tip in any form and are worth keeping after a rebase: the STRONG_CREDENTIAL_TOKEN lookbehind (the quadratic scan behind the sanitizers.property ReDoS flake), the codebuddy-cn user-agent move out of oauth.ts, the Jina duplicate listing, and the grok test alignments.

For the rebase: I ran the full slow gate set on an idle box against f7dbfc88 plus this branch. Unit, integration and pack-artifact still had reds that are not yours; they are listed with owners in #13678. One measured interaction: tip + this PR + #13436 is the first combination whose Turbopack build compiles and passes pack policy. #13565 collides with this PR on src/lib/oauth/constants/oauth.ts.

diegosouzapw added a commit that referenced this pull request Sep 14, 2026
#13248 (#12849) added the override for when a connection's synced model list
stops being authoritative, but neither .env.example nor ENVIRONMENT.md lists it,
so the env/docs contract gate reports it as code-only. The other five vars that
gate reports are already added by #13635 and #13361; this touches a different
region of .env.example so it does not collide with either.

Refs #12732
Resolves the 11 conflicts that blocked diegosouzapw#13635. Both sides had fixed several of
the same base-reds independently, so no single "take ours/theirs" rule was
correct; each hunk was decided against the merged tree.

Taken from the release branch:
- pack-artifact-policy.ts: same allowlist entry, the base adds the rationale.
- activeSyncedCatalog.ts: the base adds the synced_models_at column; this
  side only reformatted.
- injection-guard-scan-bound-3932.test.ts: identical logic, fuller comment.
- autoCombo.test.ts: this side added errorRate inside the conflict while the
  base had already added it just below, so taking this side would have put a
  duplicate errorRate key in 7 ProviderCandidate literals.

Kept from this branch:
- provider-node-reserved-prefix.test.ts: RESERVED_PREFIX_COUNT measured 412 on
  the merged tree (Arcee AI present); the base's 410 is stale.
- providers-constants-split.test.ts: APIKEY_PROVIDERS measured 240; both
  sides agree, this side centralizes it in one constant.
- glm-sse-transform-arity.test.ts: asserts call/helper arity and the
  suppressThinkClose position — the original bug was an arity mismatch; the
  base variant only checks string containment.
- combo-provider-cooldown-sibling.test.ts, chatcore-hierarchical-admission
  .test.ts: per-call-site checks and the two-leg sendProviderAttempt wiring,
  stronger than the base's per-file checks. Both verified passing on the
  merged code.
- providerExecutionPipeline.ts: uses this side's readUpstreamErrorFields
  helper; taking the base would have left it as dead code. The non-JSON error
  body fix from diegosouzapw#12945 is preserved.
- stryker.conf.json: superset of the base list; the 4 extra files exist.

Only conflicting hunks were resolved, never whole files, so non-conflicting
changes on both sides are intact.

Verified: 64/64 across the resolved suites, autoCombo.test.ts 63/63,
check:open-sse-typecheck 0 errors.
@diegosouzapw

Copy link
Copy Markdown
Owner

Resolvi os 11 conflitos que travavam esta PR, direto na sua branch e como merge fast-forward (c7c6cb69..940c136a, sem force-push) — seu histórico e crédito ficam intactos.

Os dois lados tinham consertado vários dos mesmos base-reds de forma independente, então nenhuma regra fixa de "fica com um lado" servia. Cada bloco foi decidido contra a árvore mergeada:

Da release/v3.8.51:

  • pack-artifact-policy.ts — mesma entrada; a base traz o comentário com o motivo.
  • activeSyncedCatalog.ts — a base adiciona a coluna synced_models_at; aqui era só reformatação.
  • injection-guard-scan-bound-3932.test.ts — lógica idêntica, comentário mais completo.
  • autoCombo.test.ts — aqui o errorRate foi adicionado dentro do bloco, mas a base já o tinha adicionado logo abaixo, fora do conflito. Ficar com este lado deixaria errorRate duplicado em 7 literais de ProviderCandidate.

Desta branch (mantidos):

  • provider-node-reserved-prefix.test.ts — medi RESERVED_PREFIX_COUNT = 412 na árvore mergeada (Arcee AI presente). O 410 da base estava desatualizado.
  • providers-constants-split.test.ts — medi 240; os dois lados concordam e você centralizou numa constante.
  • glm-sse-transform-arity.test.ts — seu teste guarda a aridade entre chamada e helper e a posição do suppressThinkClose. O bug original era justamente de aridade; a variante da base só casava string.
  • combo-provider-cooldown-sibling.test.ts e chatcore-hierarchical-admission.test.ts — suas checagens por chamada e das duas pernas são mais fortes que as da base, por arquivo. Conferi que passam no código mergeado.
  • providerExecutionPipeline.ts — usa seu helper readUpstreamErrorFields; ficar com a base o deixaria como código morto. O conserto de corpo de erro não-JSON da fix(ci): clear two base-reds on release/v3.8.51 — mutation-coverage gate + image-only-model guard #12945 foi preservado.
  • stryker.conf.json — superconjunto da lista da base; conferi que os 4 arquivos extras existem.

Resolvi só os blocos em conflito, nunca o arquivo inteiro, para não apagar mudanças não conflitantes de nenhum dos lados.

Verificação: 64/64 nas suítes resolvidas · autoCombo.test.ts 63/63 · check:open-sse-typecheck 0 erros. O hard-session-lease-bypass-inventory, que havia regredido no tip, voltou a passar com a atualização de inventário que você já tinha feito.

Uma observação à parte: o SKILL.md do cli-serve também está desatualizado e não é coberto por esta PR — abri a #13722 separada para ele.

@diegosouzapw
diegosouzapw merged commit 9442bde into diegosouzapw:release/v3.8.51 Sep 15, 2026
8 of 16 checks passed
diegosouzapw added a commit that referenced this pull request Sep 15, 2026
…bo catalog event-loop pin, unweighted quota-share, resilience key set, pack-gate stamp, synced-catalog env doc (#13678)

* fix(combo): rotate unweighted quota-share targets instead of pinning the first

The combo resolver turns an unset step weight into 0 (comboStructure.ts), and
#10881 made normalizeWeight treat 0 as disabled plus return definition order when
the total weight is 0. A quota-share combo without explicit weights therefore had
no DRR quanta and dispatched every request to its first target — the
combo-matrix/quota-share integration suite saw openai six times out of six.

An all-zero set is now an unweighted combo and shares evenly; an explicit 0 still
disables a target when its siblings are weighted.

Refs #12732

* fix(models): resolve auto-combo target metadata once per catalog build

#12046 derives vision/modalities for the built-in auto/* combos by resolving
catalog metadata for every target of every combo. The ~40 auto combos share one
candidate pool and the loop neither memoized nor yielded, so the #9147 fixture
(60 connections, 720 synced models) went from a ~4s build with a 167ms longest
event-loop gap to ~11s and a 860-1070ms gap on an idle box — past the 800ms
contract and past #12628's 8s cold-build bound, which is why the test came back
500 catalog_build_timeout on every release-green run.

Metadata depends only on the target's provider/model/connection scope within a
build, so memoize it per build and yield between misses. Same fixture: 2.3-3.1s
build, 56-72ms longest gap. The 9147 test is unchanged.

Refs #12732

* test(resilience): list credentialHealthCheck in the configuration-only key set

#12043 added credentialHealthCheck.intervalMinutes to DEFAULT_RESILIENCE_SETTINGS
and to the /api/resilience GET projection. It is operator configuration (the
background sweep cadence), not runtime breaker state, but the exact key-set
assertion was never updated, so resilience-http-e2e failed on the release tip.
The providerBreakers/runtime absence checks stay as they were.

Refs #12732

* fix(ci): stamp BUILD_SHA before the release-green pack gate validates

check:pack-artifact assembles dist/ through build:cli, which never writes
dist/BUILD_SHA (only build:release does). #12959 pointed the provenance ref at
HEAD, but the #10427 guard still stops at 'dist/BUILD_SHA is missing' before it
ever reaches the ancestry check — reproduced on tip + #13635 + #13436, the first
tree whose Turbopack build compiles.

ci.yml sequences build -> stamp -> validate; the validator now does the same in
both entry points, keeping PACK_GATE_ENV for the validate step. The guard is
unchanged: an unstamped dist/ or one built from another commit still fails.
On that tree the stamped gate passes: 'BUILD_SHA 5cb3ae5d9 is on the release line'.

Refs #12732

* docs(env): document OMNIROUTE_SYNCED_CATALOG_STALE_AFTER_MS

#13248 (#12849) added the override for when a connection's synced model list
stops being authoritative, but neither .env.example nor ENVIRONMENT.md lists it,
so the env/docs contract gate reports it as code-only. The other five vars that
gate reports are already added by #13635 and #13361; this touches a different
region of .env.example so it does not collide with either.

Refs #12732
diegosouzapw added a commit that referenced this pull request Sep 16, 2026
…(stryker, CLI i18n, paid-target fixture, call-log traceId, Jina prefix, callLogStats import, gitleaks) (#13747)

* fix(ci): clear the release/v3.8.51 base-reds left by the 09-15 batch — stryker coverage, CLI ready_timeout key, paid-target fixture, call-log traceId, Jina custom prefix

Every PR into release/v3.8.51 pushed after #13635/#13678 still failed Fast
Quality Gates and all four Unit fast-path shards on the same 16 tests. Each one
reproduces on the pure tip; none is a product defect:

- mutation-test-coverage: noauth-model-lockout and
  local-token-budget-429-skips-cooldown (#13606) were missing from
  stryker.conf.json tap.testFiles.
- cli-i18n-catalog: --ready-timeout calls t("serve.ready_timeout") with no
  catalog entry; added to en, zh-CN and zh-TW (the parity-checked locales).
- paid-model-target(-routes)-6540: #13407 removed Together's one-time credit
  from the free catalog, so "together/..." classifies as unknown and the
  save-time guard correctly lets it through. Fixture is now
  gemini/gemini-3.1-pro-preview, plus a precondition test on the fixtures.
- attempt-logging-early-keepalive-merge / video-bridge-log-redaction: #13546
  keys the call-log row on traceId; baseCtx now defaults traceId to
  pendingRequestId (same pattern as chatcore-attempt-logging). The keepalive
  test also moves to the 30s wall-clock poll deadline video-bridge uses.
- models-catalog-route: custom Jina rows keep the jina-ai/ prefix; #13403
  changed the custom assertion to jina/ (only synced rows use the alias).

Refs #12732

* fix(ci): clear the four reds the first r4 CI run surfaced — callLogStats duplicate import, Uzbek gitleaks false positive, redaction probe traceId, file-size

- src/lib/db/callLogStats.ts: the #13641 merge left ERROR_TYPE_CONTRACT
  imported twice (TS2300), failing API Route Typecheck and
  check:dashboard-typecheck on every PR.
- .gitleaks.toml: the Uzbek catalog from #13727 translates outputTokenDesc as
  "Yakunlash/javob tokenlari"; generic-api-key reads it as a token value.
- dashboard-request-failed-redaction-probe: reads the persisted row by
  traceId (#13546); with pendingRequestId it asserts null.
- models-catalog-route: drop the explanatory comment, which pushed the frozen
  file over its size cap; the rationale lives in the changelog fragment.

Refs #12732

* fix(ci): re-freeze the two test files #13748/#13749 grew past their file-size caps

PR-mode check:file-size relaxes source files against the base but not
testFrozen, so image-generation-handler.test.ts (2133->2235, #13748) and
batch_api.test.ts (1345->1348, #13749) failed Fast Quality Gates on every PR,
this one included. Caps set to the merged LOC, with the justification entry.

Refs #12732

* fix(ci): register free-badge-provider-gate (#13645) in stryker tap.testFiles

#13645 landed a covering test for src/sse/services/auth.ts without the
stryker entry, so the strict mutation-test-coverage gate went red again.

Refs #12732

* fix(ci): clear two more base-reds the #13440/#13439 merges added

- stryker.conf.json: register daily-reset-tz-threading (#13440), which covers
  accountFallback.ts and rrState.ts.
- .gitleaks.toml: allowlist the PROTECTED_PRIORITY_INFRA_502_ENABLED flag id
  (#13439); generic-api-key reads its key: as a token (secrets ratchet 0 -> 1).

Refs #12732

* docs(changelog): tidy the stryker base-red fragment wording

Refs #12732
diegosouzapw added a commit that referenced this pull request Sep 17, 2026
Merge the current release tip into the security hardening branch and reconcile
57 conflicting files.

Most of this PR's original scope landed on the tip while it sat: #12506/#12945/
#13635 shipped a stricter public error boundary (allowlist-based
`isSafePublicErrorIdentifier`, `errorSanitization.ts`, `errorPathRedaction.ts`,
`upstreamErrorResponse.ts`), #12429 migrated the web-cookie TLS transport to
wreq-js, and #11754 retired the common ChatGPT Web executor. Those parts are
resolved to the tip, which is strictly more restrictive in every case, and the
now-dead tls-client provenance stream is dropped (the tip's
`tls-client-wreq-residue` guard forbids reintroducing `tls-client-node`).

What survives is the part the tip does not cover:

- chatCore reads rejection metadata through `getSafeErrorMetadata`, wraps
  `isLocalStreamLifecycleError`/`formatProviderError` so a hostile Proxy cannot
  escape the boundary, sanitizes the failure message before call logs and
  console, projects the failure-usage code through the bounded vocabulary, and
  sanitizes the upstream body before it reaches the persisted attempt logs.
- Perplexity's non-streaming quota/upstream error body sanitizes the upstream
  message and projects the provider-supplied code (`toPublicPerplexityErrorCode`).
- Arena (lmarena) maps every public failure onto a fixed vocabulary instead of
  echoing upstream text; `lmarena_stream_error` is registered in the public
  identifier allowlist.
- Notion keeps the tip's fail-closed transport (no plain-fetch proxy bypass) and
  sanitizes the transport error before the response body.
- `chatgptWebTools` returns a non-ok buffered response untouched.

Tests for superseded behaviour are dropped; the surviving contributions keep
their tests, split into `lmarena-public-error-boundary-11742` and
`perplexity-web-public-error-boundary-11742` to stay under the test size cap.

Prunes three now-stale eslint suppression entries: notion-web.ts no longer has
an unused var after this merge, and the two chipotle entries were left behind by
the tip's own provider removal (#13913).
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…gosouzapw#13635)

* docs: bring the provider count to the live 358 across the reference, diagrams and llm.txt mirrors

* chore(skills): regenerate the cli-tunnel SKILL.md for the tunnel create positional

* test: clear the ESLint errors in the volcengine upsert and resource-pressure tests

* test(autoCombo): complete the mode-pack ProviderCandidate fixtures for the open-sse typecheck

* fix(ci): allow the opencode-plugin-v2 workspace package in the pack artifact policy

* docs: list the WAL, vacuum, sql.js and pressure self-restart env vars in .env.example

* refactor(db): move the synced-model provider purge into its persistence module to break the models/providers cycle

* test(memory): use a plain label for the rerank loopback key fixture so gitleaks stays at zero

* chore(ci): register the eleven covering unit tests in stryker tap.testFiles

* test(grok-cli): run the reset-credit tests on a fixture clock inside the captured token window

* test(combo): seed real provider connections for the reset-aware strategy tests

* fix(db): keep operator custom models out of the listing-only synced catalog reader

* fix(i18n): translate the new settings and combo keys for vi and pt-BR and restore the zh-TW glossary term

* fix(sse): carry the upstream error code and type through the provider execution pipeline

* test(sse): re-point the chatCore and combo source guards at the split modules and refresh the translate-path golden

* fix(oauth): keep the server-only OAuth constants out of the provider detail client bundle

* test: align the sql.js, webpack, injection-scan and error-boundary guards with their merged contracts

* docs(changelog): record the v3.8.51 base-red sweep

* fix(sse): anchor the glued-prefix sk- credential pattern so error redaction scans in linear time

* docs(changelog): note the linear credential scan in the base-red sweep

---------

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…bo catalog event-loop pin, unweighted quota-share, resilience key set, pack-gate stamp, synced-catalog env doc (diegosouzapw#13678)

* fix(combo): rotate unweighted quota-share targets instead of pinning the first

The combo resolver turns an unset step weight into 0 (comboStructure.ts), and
diegosouzapw#10881 made normalizeWeight treat 0 as disabled plus return definition order when
the total weight is 0. A quota-share combo without explicit weights therefore had
no DRR quanta and dispatched every request to its first target — the
combo-matrix/quota-share integration suite saw openai six times out of six.

An all-zero set is now an unweighted combo and shares evenly; an explicit 0 still
disables a target when its siblings are weighted.

Refs diegosouzapw#12732

* fix(models): resolve auto-combo target metadata once per catalog build

diegosouzapw#12046 derives vision/modalities for the built-in auto/* combos by resolving
catalog metadata for every target of every combo. The ~40 auto combos share one
candidate pool and the loop neither memoized nor yielded, so the diegosouzapw#9147 fixture
(60 connections, 720 synced models) went from a ~4s build with a 167ms longest
event-loop gap to ~11s and a 860-1070ms gap on an idle box — past the 800ms
contract and past diegosouzapw#12628's 8s cold-build bound, which is why the test came back
500 catalog_build_timeout on every release-green run.

Metadata depends only on the target's provider/model/connection scope within a
build, so memoize it per build and yield between misses. Same fixture: 2.3-3.1s
build, 56-72ms longest gap. The 9147 test is unchanged.

Refs diegosouzapw#12732

* test(resilience): list credentialHealthCheck in the configuration-only key set

diegosouzapw#12043 added credentialHealthCheck.intervalMinutes to DEFAULT_RESILIENCE_SETTINGS
and to the /api/resilience GET projection. It is operator configuration (the
background sweep cadence), not runtime breaker state, but the exact key-set
assertion was never updated, so resilience-http-e2e failed on the release tip.
The providerBreakers/runtime absence checks stay as they were.

Refs diegosouzapw#12732

* fix(ci): stamp BUILD_SHA before the release-green pack gate validates

check:pack-artifact assembles dist/ through build:cli, which never writes
dist/BUILD_SHA (only build:release does). diegosouzapw#12959 pointed the provenance ref at
HEAD, but the diegosouzapw#10427 guard still stops at 'dist/BUILD_SHA is missing' before it
ever reaches the ancestry check — reproduced on tip + diegosouzapw#13635 + diegosouzapw#13436, the first
tree whose Turbopack build compiles.

ci.yml sequences build -> stamp -> validate; the validator now does the same in
both entry points, keeping PACK_GATE_ENV for the validate step. The guard is
unchanged: an unstamped dist/ or one built from another commit still fails.
On that tree the stamped gate passes: 'BUILD_SHA 5cb3ae5d9 is on the release line'.

Refs diegosouzapw#12732

* docs(env): document OMNIROUTE_SYNCED_CATALOG_STALE_AFTER_MS

diegosouzapw#13248 (diegosouzapw#12849) added the override for when a connection's synced model list
stops being authoritative, but neither .env.example nor ENVIRONMENT.md lists it,
so the env/docs contract gate reports it as code-only. The other five vars that
gate reports are already added by diegosouzapw#13635 and diegosouzapw#13361; this touches a different
region of .env.example so it does not collide with either.

Refs diegosouzapw#12732
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…(stryker, CLI i18n, paid-target fixture, call-log traceId, Jina prefix, callLogStats import, gitleaks) (diegosouzapw#13747)

* fix(ci): clear the release/v3.8.51 base-reds left by the 09-15 batch — stryker coverage, CLI ready_timeout key, paid-target fixture, call-log traceId, Jina custom prefix

Every PR into release/v3.8.51 pushed after diegosouzapw#13635/diegosouzapw#13678 still failed Fast
Quality Gates and all four Unit fast-path shards on the same 16 tests. Each one
reproduces on the pure tip; none is a product defect:

- mutation-test-coverage: noauth-model-lockout and
  local-token-budget-429-skips-cooldown (diegosouzapw#13606) were missing from
  stryker.conf.json tap.testFiles.
- cli-i18n-catalog: --ready-timeout calls t("serve.ready_timeout") with no
  catalog entry; added to en, zh-CN and zh-TW (the parity-checked locales).
- paid-model-target(-routes)-6540: diegosouzapw#13407 removed Together's one-time credit
  from the free catalog, so "together/..." classifies as unknown and the
  save-time guard correctly lets it through. Fixture is now
  gemini/gemini-3.1-pro-preview, plus a precondition test on the fixtures.
- attempt-logging-early-keepalive-merge / video-bridge-log-redaction: diegosouzapw#13546
  keys the call-log row on traceId; baseCtx now defaults traceId to
  pendingRequestId (same pattern as chatcore-attempt-logging). The keepalive
  test also moves to the 30s wall-clock poll deadline video-bridge uses.
- models-catalog-route: custom Jina rows keep the jina-ai/ prefix; diegosouzapw#13403
  changed the custom assertion to jina/ (only synced rows use the alias).

Refs diegosouzapw#12732

* fix(ci): clear the four reds the first r4 CI run surfaced — callLogStats duplicate import, Uzbek gitleaks false positive, redaction probe traceId, file-size

- src/lib/db/callLogStats.ts: the diegosouzapw#13641 merge left ERROR_TYPE_CONTRACT
  imported twice (TS2300), failing API Route Typecheck and
  check:dashboard-typecheck on every PR.
- .gitleaks.toml: the Uzbek catalog from diegosouzapw#13727 translates outputTokenDesc as
  "Yakunlash/javob tokenlari"; generic-api-key reads it as a token value.
- dashboard-request-failed-redaction-probe: reads the persisted row by
  traceId (diegosouzapw#13546); with pendingRequestId it asserts null.
- models-catalog-route: drop the explanatory comment, which pushed the frozen
  file over its size cap; the rationale lives in the changelog fragment.

Refs diegosouzapw#12732

* fix(ci): re-freeze the two test files diegosouzapw#13748/diegosouzapw#13749 grew past their file-size caps

PR-mode check:file-size relaxes source files against the base but not
testFrozen, so image-generation-handler.test.ts (2133->2235, diegosouzapw#13748) and
batch_api.test.ts (1345->1348, diegosouzapw#13749) failed Fast Quality Gates on every PR,
this one included. Caps set to the merged LOC, with the justification entry.

Refs diegosouzapw#12732

* fix(ci): register free-badge-provider-gate (diegosouzapw#13645) in stryker tap.testFiles

diegosouzapw#13645 landed a covering test for src/sse/services/auth.ts without the
stryker entry, so the strict mutation-test-coverage gate went red again.

Refs diegosouzapw#12732

* fix(ci): clear two more base-reds the diegosouzapw#13440/diegosouzapw#13439 merges added

- stryker.conf.json: register daily-reset-tz-threading (diegosouzapw#13440), which covers
  accountFallback.ts and rrState.ts.
- .gitleaks.toml: allowlist the PROTECTED_PRIORITY_INFRA_502_ENABLED flag id
  (diegosouzapw#13439); generic-api-key reads its key: as a token (secrets ratchet 0 -> 1).

Refs diegosouzapw#12732

* docs(changelog): tidy the stryker base-red fragment wording

Refs diegosouzapw#12732
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