Add a direct low-level mode for users who require explicit control over provider selection. score selects the highest configured weighted score directly while reusing the existing exploration rate.
Exact ties preserve configured candidate order. rules and all other strategies remain unchanged.
OmniRoute's SSE teardown aborts in-flight legs with
`Error [AbortError]: request_signal_aborted` on client disconnects
(open-sse/utils/streamHandler.ts getClientAbortReason), and fetch/DOM
cancellation surfaces as AbortError with an abort-flavoured message.
isClientAbortError() only matched message 'aborted'/'Aborted' plus errno
codes, so these shapes fell through shouldSwallowUncaught() and were
re-thrown from the process-level uncaughtException/unhandledRejection
handlers — killing the whole server on a routine client disconnect
(observed as repeated exit-code-7 crashes with
'uncaughtException: Error [AbortError]: request_signal_aborted').
Match AbortError by name when the message is abort-flavoured; genuine
errors that merely mention 'abort' (e.g. TypeError) still crash loudly.
Tests: new unit cases for the SSE/DOM AbortError shapes, a child-process
regression proving the process survives both benign emissions with the
production no-logger install shape, and a child-process test proving
genuine errors keep crash semantics.
Fase 2 da auditoria código×docs 2026-08-31: ~90 divergências corrigidas em README/llm.txt(+42 espelhos)/SVGs/AGENTS.md/25+ docs; correções semânticas (breaker 8/12/2 + DEGRADED, webhooks sem eventos fantasma, ROUTE_GUARD_TIERS completo, API_REFERENCE sem fantasmas, reasoning 200); gate check:docs-counts endurecido (versão em prosa, patterns anti-evasão, superfície +llm.txt/mcp-server/omni-mcp/tier-flow) +5 testes; fonte do gerador de agent-skills corrigida (107/32 → 110/33) e mesma família varrida do Copilot prompt, 39 locales, skills/README, CONTRIBUTING e 2 guias.
* chore(lint): batch 5 of #12146 — resolve the react-hooks compiler violations in combos, endpoint, provider-stats, api-manager and costs
40 violations across 14 files, all real refactors (no eslint-disable, no new
suppressions; the areas' react-hooks entries are deleted from the freeze):
- set-state-in-effect (30): fetch-on-mount effects moved behind an async
continuation (usePools, usePoolUsage, useApiKeyUsageLimits, Notion/Obsidian
source cards, A2A/MCP dashboards, ComboControlCenterClient, provider-stats,
combos modal loaders, ApiManager initial load); prop/state sync converted to
state adjustment during render with prev tracking (ApiKeyUsageLimitCard,
PoolWizard dimensions/reset/group snap, combos sortMethod, builder reset,
builder stage guard, single-provider default, stale intelligent selection);
localStorage reads became lazy useState initializers (combos usage guide).
- immutability / TDZ (8): effects that scheduled fetchers declared below them
moved after the declarations (EndpointPageClient, ApiManagerPageClient,
combos mount load); fetchData relocated below the per-key fetchers it calls.
- static-components (7): provider-stats SortIcon hoisted to module level.
- preserve-manual-memoization (2): ApiManager blockedModels dep destructured to
a local; provider-scope derivation memoized so downstream memos see a stable
dependency.
Validation: eslint (CI command with suppressions, --max-warnings 0) clean on the
14 files; dashboard typecheck within baseline; mutation gate no drift; area
tests 208/208 (node) + 29/29 (vitest).
Refs #12146
* chore(lint): batch 5 follow-up — hoist the render-adjustment predicates so the new-code complexity gates stay flat
The render adjustments added one cyclomatic branch to combos/page.tsx and one
cognitive point to PoolWizard (caught by the new-code gate on the committed
work); the compound conditions now live in pure module-level predicates.
* chore(lint): batch 5 follow-up 2 — PoolWizard render adjustments live in two small hooks
One consolidated hook tripped max-lines-per-function (>80) and the cognitive
budget; the dimensions and open/close adjustments now live in two focused hooks
with a shared WizardSetters type, and the group snap stays inline (one branch).
complexityNewCode=0, cognitiveComplexityNewCode=0.
* test(quota): repoint the two PoolWizard structural pins at the render-adjustment hook
quota-edit-opens-wizard anchored the pre-fill block on the old '} else if (editPool)'
effect literal and quota-pool-wizard-edit expected a bare 'if (editPool)' that only
existed there; both now anchor on the batch-5 structure (submit still branches via
if (!editPool)).
Resolves all 28 react-hooks/* compiler violations (24 set-state-in-effect,
4 refs) across the 18 dashboard/providers files of batch 2 and removes their
suppression entries — no eslint-disable, no new suppressions.
Techniques per file:
- Fetch-on-mount loaders (CustomModelsSection, ProviderCcAliasSection,
ProviderInterceptionSection, ProviderParamFilterSection, page.tsx,
useProviderConnections, useProviderSettings, CliproxyAccountHealthCard,
DarioAccountPanel, NinerouterModelList): network/parse/error concerns
extracted to module-level helpers returning error-as-value; the async glue is
defined INSIDE each effect with every setState after the await. Loaders that
handlers still need (refresh/retry buttons, exposed hook API) remain as
callbacks; spinner flags moved into the button handlers.
- Loading flags for provider-keyed sections derived from a loadedProviderId
marker instead of synchronous setLoading(true) resets.
- Modal init/reset effects (EditConnectionModal, EditCompatibleNodeModal,
AddCompatibleProviderModal, VolcengineConnectModal state reset,
useProviderUrlFilters hydration, page.tsx display-mode fallback,
useProviderSettings per-provider flag reset): converted to render-phase
adjustments guarded by the previously-seen prop/marker (react.dev "adjusting
state when a prop changes").
- VolcengineConnectModal: phone prefill via localStorage lazy initializer;
server-side session cancel + poll stop moved to the cleanup of an
open-scoped effect reading a session ref mirror.
- ModelCompatPopover refs: render-time ref mirrors removed — headerRowsRef is
maintained by an applyHeaderRows writer used by all handlers, paramTargetRef
is mirrored in an effect, and blockText/allowText mirrors were already kept
in sync by their single writer (applyParamFields).
- ModelCompatPopover state: header-row loading and value-visibility resets
moved from [open, protocol] effects into the open/protocol/outside-click
gesture handlers; the closed-popover rect reset was dropped (render is gated
on open and the rect is recomputed pre-paint on reopen).
- useRiskAcknowledged: localStorage mirrored via useSyncExternalStore with a
module-level listener set notified by acknowledgeProviderRisk.
- useProviderModels: loading for the empty-providerId case derived at the
return site instead of a synchronous setLoading in the effect.
Validation: scoped eslint with the suppressions file passes with 0 problems;
check-dashboard-typecheck.mjs OK; node --test batch (14 files) and vitest
batch (9 files, 47 tests) green.
Refs #12146
* chore(lint): batch 3 of #12146 — resolve the react-hooks compiler violations in dashboard/settings
Resolves the 25 react-hooks/* React Compiler violations frozen in
config/quality/eslint-suppressions.json for the dashboard/settings area
(24 set-state-in-effect, 1 immutability), plus the adjacent
react-hooks/exhaustive-deps in ProviderAccountRoutingCard, and removes
their suppression entries. No eslint-disable added anywhere; one
pre-existing eslint-disable-line (AccessTokensTab) removed.
Techniques used:
- ResilienceTab (8×): the "sync draft state from prop via useEffect"
cards now use the documented adjust-state-during-render pattern
(prevValue state + conditional setState in render) instead of an
effect.
- PricingTab visibleCount reset: same render-adjustment pattern keyed
on the filters tuple, replacing the reset effect.
- Fetch-on-mount loaders only used by the effect (IPFilterSection,
ModelCapabilityOverridesTab, PayloadRulesTab*, RoutingStrategyCard):
loader inlined into the effect as an async IIFE with a cancelled
flag; every setState now happens after the first await.
- Loaders reused by handlers/intervals (AccessTokensTab, AuthzSection,
FallbackChainsEditor, MitmProxyTab, ModelsDevSyncTab, OneproxyTab,
PayloadRulesTab, PoliciesPanel, PricingTab,
ProviderAccountRoutingCard, SystemStorageTab, GlobalConfigTab,
SubscriptionTab): split into a module-level pure fetcher + a
useCallback applier; the effect awaits the fetcher and applies after
the await (cancellation-guarded), while handlers keep the original
named loader (sync setState is fine there) built from the same
fetcher/applier — no logic duplication, identical error-message and
loading semantics.
- OneproxyTab keeps the spinner-on-filter-change behavior via the same
render-adjustment pattern (filtersKey → setLoading(true)).
- AccessTokensTab: the L() fallback helper is now memoized with
useCallback([t]), which also let the old
eslint-disable-line react-hooks/exhaustive-deps be removed.
- ProviderAccountRoutingCard: save's dependency array now includes
load (the frozen exhaustive-deps violation).
Suppressions: all react-hooks/* entries for the 17 batch files removed
(19 rule entries, 26 violation counts). Entries for other rules/files
untouched.
Refs #12146
* chore(lint): batch 3 follow-up — extract useOneproxyData so the cyclomatic gate stays flat
The first pass grew OneproxyTab past the complexity threshold (caught by the
new-code gate on the PR); the data-loading state now lives in a dedicated
useOneproxyData hook. Also registers search-432-plan-limit-cooldown in
stryker tap.testFiles (base drift the gate flagged on every batch).
* chore(lint): batch 1 of #12146 — resolve the react-hooks compiler violations in dashboard/cli-code
Real refactors, no suppressions — the 42 frozen react-hooks/* entries for the
12 dashboard/cli-code files (plus Antigravity's exhaustive-deps one) are
removed from config/quality/eslint-suppressions.json and the files now lint
clean under the React Compiler rules.
Techniques, per pattern:
- set-state-in-effect ("default API key" effects — Antigravity, Claude, Cline,
Codex, Droid, GrokBuild, Kilo, OpenClaw): the setState-in-effect that copied
apiKeys[0].id into the selection state is deleted; an `effective*` value is
derived during render (`selected || apiKeys[0]?.id`) and used by the select
and the submit handlers. Behavior identical, one less render pass.
- immutability ("accessed before declared") + set-state-in-effect on the
expand-time loaders (all tool cards): the fetchers (checkXStatus,
fetchModelAliases, fetchBackups, fetchProfiles, loadSavedMappings) are
hoisted above the effect as useCallback with correct deps, listed in the
effect deps, and invoked through an async continuation
(`void (async () => { await Promise.all([...]) })()`) so no setState runs
synchronously in the effect body.
- set-state-in-effect ("init form from fetched status" effects — Claude,
Cline, Codex, Droid, OpenClaw): the status-parsing effects are deleted and
their logic now runs inside checkXStatus right after the fetch resolves
(setState after await), keeping the same one-time ref guards. Codex's config
parser became syncFormFromStatus(), called on both success and error paths.
- HermesAgentToolCard: Date.now() in render (purity) is snapshotted once via a
lazy useState initializer; the batchStatus seeding effect is replaced by a
derived `displayRoles` (useMemo over batchStatus with currentRoles taking
precedence); the collapse-reset effect moved into the header toggle handler.
- ClaudeClassifierCompatToggle / CliProfileAutoSyncToggles / Cliproxyapi /
GrokBuild: mount/expand loads wrapped in the same async continuation.
- DroidToolCard's isOmniRouteEntry helper hoisted to module scope (pure).
Validation: eslint with suppressions --max-warnings 0 on the 12 files (clean),
scripts/check/check-dashboard-typecheck.mjs (OK, within frozen baseline),
vitest UI suites for the touched cards (15 files / 57 tests green, plus the 3
quarantined #8618 files run explicitly: 27 tests green), and the node-native
cli-code tests (61 tests green).
Refs #12146
* chore(lint): batch 1 follow-up — hoist the settings-init helpers so the cognitive gate stays flat
The first pass folded the one-time form init into the status fetchers, which pushed
sonarjs/cognitive-complexity to 1 in Claude/Cline/OpenClaw tool cards (caught by the
new-code gate on the PR). The init logic now lives in module-level helpers
(initXFormFromSettings + defaultKeyId); complexityNewCode=-1, cognitiveComplexityNewCode=0.
* chore(lint): batch 4 of #12146 — resolve the react-hooks compiler violations in shared/components
Real refactors (no suppressions, no eslint-disable) for the 21 react-hooks/*
violations across the 11 src/shared/components files of this batch:
- set-state-in-effect (prop/state mirror or modal open/close reset):
replaced with guarded render-time adjustments (react.dev "You Might Not
Need an Effect" prev-tracking pattern) — KiroAuthModal,
ModelSelectModal, ProxyConfigModal, OAuthModal (provider-change, close
and open resets; ref invalidation split into ref-only effects),
RequestLoggerDetail.sections (liveDetail mirror),
ComboCompressionModeSelect (initialCompressionMode mirror).
- set-state-in-effect (fetch+set effects calling component-scope
functions): moved the async loader inside the effect (ModelSelectModal
fetchCombos/fetchProviderNodes/fetchCustomModels, PricingModal
loadPricing, useProviderDailyUsage fetchRows — now with a cancelled
guard) or wrapped the call in an effect-local async runner
(ReasoningRoutingRules load, UsageStats fetchStats, OAuthModal
startOAuthFlow) with every setState on the async path.
- OAuthModal device-code countdown: deviceCodeSecondsRemaining state
deleted and derived from deviceCodeExpiresAt plus a `now` tick state
updated by the interval (re-anchored when polling starts).
- Sidebar localStorage hydration: reads moved into useSyncExternalStore
snapshots (server snapshot null) applied via render-time adjustment;
skipInitialActiveExpansion ref converted to state; the active-section
expansion effect became a render-time adjustment keyed on the old
effect deps; persistence consolidated into one saveToStorage effect
(removes the saves that ran inside setState updaters and drops a
pre-existing eslint-disable for exhaustive-deps).
- immutability (use-before-declare): PricingModal loadPricing inlined
into its effect; ProxyConfigModal resetFields hoisted above the load
effect as a dependency-free useCallback.
- exhaustive-deps (ProxyConfigModal): effect now depends on the stable
resetFields and on hoisted translated strings (socks5HiddenError,
levelGlobalLabel) instead of the `t` identity.
- preserve-manual-memoization (UsageStats sortedAccounts): optional
chains destructured into locals so the memo deps match the usage.
config/quality/eslint-suppressions.json: removed every react-hooks/*
entry for the 11 files (other-rule entries preserved).
Validation: eslint gate (--suppressions-location, --max-warnings 0) green
on all 11 files; typecheck:core clean; node unit sweep 373/373; vitest
sweep 547/550 with the 3 fails being 5s-timeout flakes under parallel
load (all pass isolated 8/8, one in an untouched file).
Refs #12146
* test(mutation): register search-432-plan-limit-cooldown in tap.testFiles
The test (merged with the DuckDuckGo cooldown fix) covers accountFallback.ts and
auth.ts but was not listed, so check:mutation-test-coverage --strict reds any PR
whose merge ref includes it. Base also merged in.
* fix(ci): clear the base-reds the 2026-08-30 afternoon merge batch left on release/v3.8.51 (round 5)
- docs-counts / check-docs-counts-sync test: #12103 (Perplexity Agent) made it 352
providers; README, AGENTS.md, llm.txt (+42 i18n mirrors), package.json description
and the 4 README diagrams still said 351.
- api-route-typecheck: #11971 passes a third `{ featureEnabled }` argument to
appendNoThinkingVariants() that the helper never accepted (TS2554 — and the flag
silently did nothing); the helper now honours it. src/lib/skills/interception.ts
narrowed a mapped object with a `Record<string, string>` predicate (TS2677) —
predicate typed with the actual element shape.
Gates: check:docs-counts OK (test 28/28), check:docs-sync PASS, check:api-typecheck
OK (289 frozen). Refs #12103, #11971
* docs(env): document RATE_LIMIT_EXECUTION_MAX_WAIT_MS (#12027 added it to .env.example only)
* fix(ci): round 5b — freeze the react-hooks compiler-rule violations, align 7 tests to merged contracts
No new ESLint warnings: the exact CI command (lint:json --max-warnings 0) reports 278
problems on the tip — 226 from eslint-plugin-react-hooks 7 compiler rules
(set-state-in-effect 167, immutability 36, refs/static-components/purity/
preserve-manual-memoization) that were masked until the lockfile change of
dfc84ba030 invalidated the ESLint cache, plus 46 no-explicit-any in
tests/unit/call-log-cap.test.ts (#12026). Velocity phase: frozen with
`eslint --suppress-all` (+668 suppressions); the 5 now-unused
`eslint-disable react-hooks/immutability` directives and one unused import removed.
Verified: lint:json --max-warnings 0 → 0 problems.
Tests aligned to contracts merged this afternoon (all reproduced red on the pure tip):
- providers-constants-split: 235 → 236 (Perplexity Agent, #12103)
- sse-auth: a forced pin outside allowedConnections now yields no credential
instead of silently falling back (#12080)
- with-chat-admission-10786: withInjectionGuard(postHandler, { logger: null }) (#12117)
- hard-session-lease-bypass-inventory: classify src/app/api/oauth/codex/import/route.ts (#12116)
- usage-service-hardening: OpenCode Go official usage API shape (#12124)
- i18n placeholder parity: apiManager.restrictedToConnections rewritten as a plain
ICU plural (`{count, plural, one {# connection} other {# connections}}`) in en,
vi, pt-BR and the 40 __MISSING__ mirrors — the parity extractor counts every
`{word}` including the old literal `{s}`
Refs #12103, #12080, #12117, #12116, #12124, #12026
* fix(ci): run the ESLint warnings job on the box with an 8 GB heap; reserved-prefix set 398 → 400
The cold full lint with the react-hooks 7 compiler rules is killed on the 7 GB hosted
runner with no message (status null → exit 1, JSON never written) — it only looked
green while the ESLint cache was warm. tests/unit/provider-node-reserved-prefix.test.ts
aligned to the two prefixes the afternoon batch registered (#12103).
* test(ci): document the lint-guard runner exception; #9147 event-loop gap 400 → 800 ms
quality-rail-gate-membership pinned lint-guard to ubuntu-latest; the cold full lint is
OOM-killed there, so the job now runs on omni-light with an 8 GB heap — the test keeps
fast-gates pinned and asserts the documented exception. With the catalog at 352
providers the hosted shards measure 410–633 ms gaps on 9147-catalog-eventloop-yield
(3 runs); 800 ms still fails a true pin. Re-tighten with the v4.0 catalog split.
* chore(quality): summarize the ESLint report on failure — a red lint:json printed nothing
--format json --output-file swallows every problem; a red 'No new ESLint warnings' job
gave zero output (three blind debugging rounds in #12144), and a killed process (OOM,
status null) was equally silent. On any non-zero exit the runner now prints the problem
count and the first 60 'file:line rule — message' lines from the report.
* chore(lint): freeze react-hooks/immutability for the 5 UI test harnesses in the suppressions file
The rule fires for these files in CI but not locally (compiler analysis divergence),
so the inline eslint-disable directives read as 'unused directive' warnings locally.
A suppressions entry is symmetric: suppressed where the rule fires, tolerated as
unpruned (--pass-on-unpruned-suppressions) where it does not. Found via the new
lint:json failure summary.
Aumenta o teto do sticky round-robin limit para 1000, com teste próprio (3/3 verdes). Fiz cherry-pick só dos 2 commits reais direto na tip atual: a branch original carregava 4 commits antigos de drift do ciclo (release/electron/CI, já resolvidos de outras formas) que geravam conflito redundante contra `.github/workflows/electron-release.yml`. Nenhum conteúdo seu foi perdido — força-pushed a branch limpa (autoria preservada). Obrigado!
Honra um `context_length` definido pelo operador em tempo de requisição no roteamento do combo (supersede #12014, que estava incluída nos mesmos commits). Boa cobertura de testes, incluindo o refactor de `resolveComboContextLimit` para módulo próprio. Validado no worktree combinado (13/13). Obrigado!
Intervalo de checagem de saúde de credencial configurável pelo operador, com boa cobertura de testes. Validado no worktree combinado (20/20).
Corrigi o import de `getCachedSettings` em `src/app/api/resilience/route.ts` e `src/lib/credentialHealth/scheduler.ts`, que apontava para `@/lib/db/settings` (path antigo antes do split para `@/lib/db/readCache`, já na tip). Resolvido também um conflito de tradução vi.json entre chaves duplicadas de outra feature (exclusive lease), sem relação com esta PR — mantida a versão já mergeada. Obrigado!
Adiciona suporte ao GLM-5.3-Flash Coding Plan (endpoint OpenAI-compatible, tiers de esforço low/high/max via reasoning_effort). Boa cobertura de testes. Validado no worktree combinado.
Dois problemas resolvidos antes de mergear:
1. **Duplicata silenciosa de "glm-5.3-flash"** em `src/shared/constants/modelSpecs.ts` e `open-sse/config/glmProvider.ts` (#11830, já mergeado nesta sessão, e sua PR inserem a mesma entrada em pontos diferentes do arquivo — git não detecta como conflito textual). Removida a duplicata, preservando a ordem que o teste pré-existente `open-sse/mcp-server/__tests__/glmCodingProviderConfig.test.ts` espera (glm-5.3-flash primeiro no array `GLM_SHARED_MODELS`).
2. Conflito real em `zai/index.ts`, `default.ts`, `pricing/shared-tiers.ts` e no teste de catálogo — todos aditivos, resolvidos mantendo ambos os lados.
27/27 + 10/10 (vitest) testes focados verdes. Obrigado!
Mantém o erro do call-log quando o limite de tamanho corta os bodies, com `preserveErrorForSizeLimit` (UTF-8-safe, preserva o valor original quando cabe, trata erro circular/não-serializável) — implementação mais robusta que a alternativa que já estava na tip (via #12027, que resolvi combinando: mantive a camada extra "errorOnly" do #12027 usando o helper mais seguro deste). Testes próprios + os de #12027 todos verdes (30/30) no worktree combinado. Obrigado!
Emite `web_search_call` nativo para o fallback de web_search da Responses API, com boa cobertura (integração + unitário). Validado no worktree combinado.
Corrigi 3 problemas no próprio `tests/integration/skills-pipeline.test.ts` desta PR antes de mergear: faltava `encodeSkillToolName` no import (usado em 3 lugares, causava `ReferenceError` que se propagava como 502 no teste "matching tool calls execute the registered skill") e 2 asserções comparavam nomes decodificados (`decodeSkillToolName`) contra valores re-codificados (`encodeSkillToolName`) — copy-paste do helper usado para montar o mock. 30/30 testes focados verdes após a correção.
Adiciona compatibilidade de renomeação de migração para 056/073/077/101. Teste próprio atualizado (7/7 verde no worktree combinado + isolado).
Fiz cherry-pick só dos 2 commits reais da PR (o fix + o ajuste do teste) direto na tip atual: a branch original carregava 3 commits antigos de drift do ciclo (release-workflow/electron, já mergeados de outras formas) mais um commit de auto-resolução de merge seu, que juntos geravam conflito redundante contra `.github/workflows/electron-release.yml`. Nenhum conteúdo seu foi perdido — força-pushed a branch limpa (autoria preservada). Obrigado!
Desacopla a expiração de execução do rate-limit do orçamento de espera na fila, e preserva erros em artefatos de call-log oversized. Testes próprios (`call-log-cap.test.ts` + atualizações em `rate-limit-execution-timeout-message-4165.test.ts`/`ratelimit-admission-control-6593.test.ts`). Validado no worktree combinado. Obrigado!
Migra o quota fetcher do OpenCode Go para a API oficial de uso, com refactor substancial que remove ~1850 linhas de código legado e atualiza a suíte de testes existente inteira para o novo contrato. Validado no worktree combinado (typecheck limpo, testes focados verdes). Obrigado!
Corrige o bulk-import do Codex apagando `providerSpecificData`/`tokenExpiresAt`/duplicando `priority` de conexões existentes ao fazer upsert num match — mescla o payload importado sobre o estado existente em vez de substituir tudo, igual ao caminho de import single-file já fazia. Findings 4, 6 e 7 do #12113. Teste próprio (224 linhas). Validado no worktree combinado. Obrigado!
Refresca o manifest do plugin a partir do disco ao ativar, para que instalações pré-existentes ganhem hooks novos adicionados por schema updates (ex.: `onStreamComplete` do #11825/#11934 nunca chegava a plugins já instalados antes do upgrade, pois o manifest persistido no DB era stripado pelo schema antigo). Finding 3 do #12113. Teste próprio (259 linhas). Validado no worktree combinado. Obrigado!
Restaura o log do injection-guard nas 13 rotas não-chat (embeddings, images, audio, moderations, etc.) — a correção de log duplicado anterior (#11936) silenciou completamente o único emissor de log dessas rotas, deixando tentativas de injeção sem rastro nenhum em modo warn, e sem log mesmo quando bloqueadas em modo block. Achado de segurança real (Finding 2 do #12113). Teste próprio (141 linhas). Validado no worktree combinado. Obrigado!
Corrige o kill do processo inteiro do plugin quando um handler fire-and-forget de `onStreamComplete` demora >10s — hook documentado como fire-and-forget não deveria derrubar o processo a cada stream completo. Finding 5 do #12113. Teste próprio (214 linhas). Validado no worktree combinado. Obrigado!
Corrige vazamento de colunas de conexão (email/nome/etc.) através do cast em `getExclusiveConnectionLeaseStatus` — a projeção agora fica restrita às colunas de lease, evitando que um futuro consumidor sirva PII sem querer via o tipo `ExclusiveConnectionLease`. Documentado como Finding 8 do seu próprio bug-audit (#12113). Teste próprio (103 linhas). Validado no worktree combinado. Obrigado!
Vincula o refresh OAuth do Google ao client que emitiu o token, com teste próprio (`google-oauth-client-binding.test.ts`). Validado no worktree combinado. Obrigado!
Adiciona o provider Perplexity Agent API, com dois arquivos de teste próprios (provider + sanitização de chatCore). Validado no worktree combinado. Obrigado!
Mantém conexões forçadas indisponíveis com escopo correto, com teste próprio ampliado (`forced-connection-fallback.test.ts`). Validado no worktree combinado. Obrigado!
Alinha o body do combo e o acesso legado por chave, com testes atualizados (CLI api-generator + row parsers). Validado no worktree combinado. Obrigado!
Deriva as modalidades do auto-combo a partir do pool de targets efetivo, com teste próprio robusto (174 linhas). Validado no worktree combinado. Obrigado!
Injeta a tag de usuário obrigatória nas requisições de inferência do provider Nous, com teste próprio ampliado. Validado no worktree combinado. Obrigado!
Usa a lista de publishers v1beta1 do Model Garden para descoberta de modelos Vertex Anthropic, com teste próprio. Validado no worktree combinado. Obrigado!
Mantém tokens de cache-write no formato de usage do OpenAI, com teste próprio (`cache-write-openai-shape.test.ts`) e atualização do teste existente de tokens detalhados. Validado no worktree combinado (typecheck limpo, 351/351 testes focados). Obrigado!
Owner decision (2026-08-30): shipping speed matters more than holding the debt line
until the v4.0 LTS modularization; the base was going red on every merge batch and
each red baseline cost a sweep.
Relaxation (one auditable pass, scripts/quality/relax-baselines.mjs):
- quality-baseline.json metrics: lower-is-better ×1.2, higher-is-better ÷1.2
(coverage floor 60 kept; eslintErrors stays 0; eslintWarnings 0 → 1050 = 20% of
the 5,247 frozen suppressions). Adds `_policy {phase: velocity, until: 4.0.0,
relaxPct: 20, requireTighten: false}` + a `_relax_velocity_2026_08_30` note
listing every before → after.
- complexity count 2681 → 3218; duplication 5.72 → 6.86; file-size cap/testCap
1000 → 1200 and all 127 frozen caps ×1.2; api/dashboard/open-sse typecheck
per-file counts ×1.2; openapi-coverage THRESHOLD 36 → 30.
- check-quality-ratchet: --require-tighten is advisory while _policy.requireTighten
is false (2 new tests); nightly bank-ratchet-shrinks pauses during the phase (it
would bank the measured shrink and undo the headroom every night).
Monitoring (scripts/quality/baseline-headroom.mjs, npm run quality:headroom):
measures each numeric gate the way CI does, prints live / baseline / headroom per
gate (ok ≥10%, warn <10%, critical <0); the new nightly `baseline-headroom` job
posts the table to the living issue "📈 Baseline headroom (velocity phase)" and
toggles the `headroom-alert` label. 6 unit tests on the pure helpers.
Also aligns the remaining red tests on the tip to contracts already merged:
#11775 (FREE lease-capable connections are ordinary capacity: gate inventory 48/97/99,
sse-auth selection, warmup scheduler), #11794 (dual-loopback readiness probe), and the
8 vi strings #11775 left as __MISSING__.
Docs: QUALITY_GATES.md → "Velocity phase" (what changed, tooling, how to close the
phase at 4.0), AGENTS.md quick reference.
- api-route-typecheck: 56dddfce34 (antigravity loadCodeAssist metadata) made
getAntigravityLoadCodeAssistMetadata() return Record<string, number> while
onboardAntigravityUser() still typed the parameter Record<string, string> —
TS2345 in src/lib/oauth/providers/antigravity.ts, gate red on every PR. The
parameter now derives from the getter's return type.
- env-doc contract: 0b19c5a09b (#11852, 5dive configure target) reads
CLI_5DIVE_BIN and CLI_5DIVE_STATE_DIR without documenting them —
Docs Gates red on every PR. Added to .env.example and ENVIRONMENT.md.
Gates: check:api-typecheck OK (289 frozen), check:env-doc-sync OK,
antigravity oauth tests 14/14.
Refs #11852
* fix(dashboard): make RequestLoggerDetail loadable outside Next — CSS via globals.css, CJS/ESM interop for react18-json-view
Origin: #11703 (5684589ce7) imported `react18-json-view/src/{style,dark}.css` at
module level in RequestLoggerDetail(.sections).tsx and relied on the bundler's
default-import interop. Next is fine with both, but every test that renders the
component died on the release tip:
- node:test / tsx: ERR_UNKNOWN_FILE_EXTENSION ".css" — request-log-detail-layout,
request-log-detail-stream, request-logger-detail-copy-all,
request-timeline-lane-allocation (4 unit shards red on every PR).
- esbuild bundle-safety check (media-page-client-browser-bundle): cannot resolve the
.css specifiers.
- node ESM resolves the package's CJS `main` (no `exports` map), so the default
import is the module namespace: "Element type is invalid … got: object".
Fix at the source: the two stylesheets are @imported from src/app/globals.css
(same as material-symbols / fumadocs), and the component unwraps `mod.default ??
mod` like redisQuotaStore/keytar already do. Also adds the 5 vi strings #11703
introduced (requestLogger.detail.{collapseAllLevels,collapseOneLevel,
currentExpandLevel,expandOneLevel,expandAllLevels}) — vi has strict parity.
Refs #11703
* refactor(dashboard): move the react18-json-view interop into shared/components/jsonView.ts
RequestLoggerDetail.tsx is frozen by check:file-size (1111 lines, cannot grow); the
inline interop pushed it to 1118. One tiny module serves both components and keeps
the CSS-import warning in a single place.
Remove a reserva estática global e passa a gatear o roteamento pela ocupação real do lease exclusivo ativo, com boa cobertura de testes (5 arquivos, 54 casos, todos verdes no worktree combinado). Typecheck limpo.
Dois ajustes feitos por cima antes do merge:
1. **26 arquivos `.pyc` órfãos removidos** (`scripts/ops/__pycache__/…`, `tests/unit/ops/__pycache__/…`) — cache compilado do Python sem relação com o fix de lease, provavelmente commitado sem querer do ambiente local.
2. **Conflito em `src/app/api/keys/[id]/route.ts`**: mantida a checagem mais ampla desta PR (`instanceof ApiKeyPolicyInvariantError || código LEASE_KEY_POLICY_INVALID`), que é um superset da versão anterior — cobre o caso original e o novo caminho de erro do lease.
Obrigado pela contribuição!
Feature grande e bem construída: exportação contínua de call logs para destinos plugáveis (BigQuery primeiro). Revisei especificamente o tratamento de segredos (`src/lib/logExport/secrets.ts`) e a migração — encryption gate real (`requiresEncryptionKey` recusa gravação em texto plano quando `STORAGE_ENCRYPTION_KEY` não está setada), redação antes de qualquer resposta de API, e a migração cria a tabela com `enabled=0`/`include_bodies=0` por padrão (opt-in, sem exportar nada até o operador configurar). 62/62 testes focados verdes, typecheck limpo.
Resolvido o conflito com o barrel `src/lib/localDb.ts` (removido nesta mesma sessão, #11795 fase 5 — todo consumidor já migrado para `src/lib/db/*`); a PR só adicionava um re-export nele, que não é mais necessário. Obrigado pela contribuição!
Mostra a % de cache nos logs de requisição, com teste próprio (`request-logger-cache-percentage.test.ts`). Validado no worktree combinado do lote.
Pequeno ajuste feito por cima: `formatCachePercentage` movida de `RequestLoggerV2.tsx` para `src/shared/utils/formatting.ts`. `RequestLoggerV2.tsx` importa `RequestLoggerDetail`, que desde o #11703 (mergeado nesta mesma sessão) importa CSS bruto de `react18-json-view` — algo que o Node native test runner não consegue carregar. O teste original importava a função direto do componente e quebrava por causa dessa cadeia de import, não por bug na PR. Movida a função (pura, sem dependências) para o utils compartilhado; ajustado o import do componente e do teste. Typecheck limpo, teste passando (6/6).
Adiciona 5dive como configure target, com teste de regressão próprio (`tests/unit/cli/setup-5dive.test.ts`) e strings i18n em 12 locales. Validado no worktree combinado (typecheck limpo, 26 testes focados).
Nota: um dos subtestes desse arquivo ("falls back to the local server when no context") depende de não haver contexto CLI ativo em `~/.omniroute/` — nesta máquina de desenvolvimento compartilhada existe um contexto real configurado, então o teste lê a config real em vez do fallback via `PORT`. Confirmado que é vazamento de ambiente do devbox (não do CI): reproduzido isoladamente, rastreado até `resolveActiveContext()` lendo `~/.omniroute/*.json` antes de cair no fallback de `PORT`. Não bloqueia o merge, mas fica registrado — o teste merece ficar hermético (mockar/isolar o data dir) numa limpeza futura.
Corrige divergência de scoring no relatório de saúde do auto-combo, com testes atualizados em `combo-resolve-auto-strategy-split.test.ts` e `combo-scoring-inspector.test.ts`. Validado no worktree combinado. Obrigado!
Fix de contraste no tooltip do gráfico de custos (fundo opaco + cor de texto legível). Mudança isolada de CSS/classe, validada no worktree combinado. Obrigado!
Resolução de links relativos entre Fumadocs e a wiki do GitHub, com dois arquivos de teste novos e bem focados (`docs-link-resolver.test.ts`, `sync-wiki.test.ts`). Validado no worktree combinado. Obrigado!
Correção pequena e correta — `passthroughModels: true` para o Vercel AI Gateway. Validado no worktree combinado do lote (typecheck limpo, gates estáticos verdes). Obrigado!
Resynced onto release/v3.8.51 (originally targeted main; retargeted since the default branch is release/v3.8.51). One real conflict in open-sse/handlers/chatCore.ts, but it was entirely unrelated to this PR's actual purpose: the antigravity-aware lockExactModel branching and deferAntigravityQuotaStateToCaller state exist on main but haven't been synced to release/v3.8.51 yet (confirmed by diffing your branch against its own main merge-base — the only change there was a Prettier reformat, not new logic). Discarded that unrelated drift and kept the release tip's current quota-lock shape; the onStreamComplete plugin wiring itself is untouched and intact. typecheck:core clean, 13/13 plugin delivery tests pass. Thanks for the thorough three-layer root-cause writeup.