Skip to content

feat(sse): wire the PROVIDER_PROFILES window gate into the global provider cooldown - #12247

Merged
diegosouzapw merged 1 commit into
release/v3.8.51from
feat/provider-failure-window-cooldown
Sep 1, 2026
Merged

diegosouzapw merged 1 commit into
release/v3.8.51from
feat/provider-failure-window-cooldown

Conversation

@diegosouzapw

Copy link
Copy Markdown
Owner

Follow-up nº 1 da auditoria código×docs (fases 1–2 na #12200) — decisão do dono: ligar a config morta, com TDD.

O que liga

providerFailureThreshold / providerFailureWindowMs / providerCooldownMs existiam em PROVIDER_PROFILES sem nenhum consumidor no runtime (achado P0.1 da auditoria). Agora alimentam o window gate do Provider Cooldown global (open-sse/services/providerCooldownTracker.ts):

  • Entradas provider-level (sem connectionId) só contam como cooling após providerFailureThreshold falhas dentro de providerFailureWindowMs — e então esfriam por providerCooldownMs (OAuth 10×/15min→5min; API key 15×/30min→10min). Sucesso limpa a janela.
  • Entradas connection-level mantêm o backoff exponencial pré-existente, intocado.
  • A camada continua opt-in (PROVIDER_COOLDOWN_ENABLED, default off) e todos os call sites do combo já são gated por enabled — comportamento default de produção inalterado.
  • O tracker resolve o perfil via getProviderCategory (config/providerRegistry) + PROVIDER_PROFILES (config/constants) — módulos-folha, sem ciclo de import e zero mudança de assinatura nos call sites.

TDD (Hard Rule #18)

  1. tests/unit/provider-cooldown-window-gate.test.ts escrito primeiro — 4 vermelhos provando a ausência do gate (abaixo do threshold cooldownava; janela não existia; cooldown não era providerCooldownMs; success não limpava janela).
  2. Wiring aplicado → 6/6 verdes (inclui expiração via mock.timers e preservação do contrato connection-level).
  3. Suíte legada do tracker alinhada ao contrato novo (1 teste pinava o comportamento antigo) → 23/23.

Validação

  • typecheck:core ✅ · ESLint focado ✅ · test:vitest 50/50 files, 463/463 tests ✅ (um timeout de 20s em provider-family-combos apareceu 2× sob carga de 3 CIs simultâneos e foi discriminado: a MESMA suíte passa 50/50 na árvore sem estas mudanças e na minha com a máquina calma — carga, não regressão)
  • Suítes vizinhas do tracker/combo: breaker-network-error-guard 10/10 · combo-provider-cooldown-sibling 9/9 · web-session-pool-health 14/14 ✅
  • Docs: seção do breaker no AGENTS.md atualizada (campos deixam de ser "no runtime consumer") + subseção nova no RESILIENCE_GUIDE.md; refresh do soft-drift de executors trazido pela base nova (104→106). check:docs-counts ✅

…vider cooldown

providerFailureThreshold / providerFailureWindowMs / providerCooldownMs shipped
in PROVIDER_PROFILES with no runtime consumer (2026-08-31 docs audit, P0.1).
Provider-level entries in providerCooldownTracker now honor them: the whole
provider only counts as cooling after providerFailureThreshold failures inside
providerFailureWindowMs, then cools for providerCooldownMs. Connection-level
entries keep the pre-existing exponential backoff, and the layer stays opt-in
(PROVIDER_COOLDOWN_ENABLED, default off) — default behavior is unchanged.

TDD: tests/unit/provider-cooldown-window-gate.test.ts written first (4 red on
the old behavior), then the wiring; legacy tracker suite aligned to the new
contract (23/23 green). Docs: AGENTS.md breaker section + RESILIENCE_GUIDE
opt-in layer subsection; executors soft-drift refresh (104 -> 106).
@diegosouzapw
diegosouzapw merged commit 2e17161 into release/v3.8.51 Sep 1, 2026
21 checks passed
diegosouzapw added a commit that referenced this pull request Sep 1, 2026
The two native-codex-turn-pin suites landed via the #10379 merge wave after
PR #12247 forked, so #12247's green CI never saw them: they set up 'provider
in global cooldown' with a single recordProviderCooldown call, the pre-#12247
contract. Since the window gate, a provider only counts as cooling after
providerFailureThreshold failures inside the window — the setup now loops to
the profile threshold (same alignment the tracker's own legacy suite got in
Sibling sweep: all 7 suites touching recordProviderCooldown pass (60/60).
diegosouzapw added a commit that referenced this pull request Sep 1, 2026
…tes aligned to the window gate (#12255)

* chore(quality): register native-codex-turn-pin tests in stryker tap.testFiles

The mutation-test-coverage gate (--strict) fails on the release tip: the two
native-codex-turn-pin suites (#10379 merge wave) cover open-sse turn-pin code
and src/shared/utils/circuitBreaker.ts but were not listed in
stryker.conf.json tap.testFiles, so their mutant kills would not count. Adds
both files; the gate now passes clean (4728 test files scanned, no drift).

* style: prettier pass on stryker.conf.json

* test(sse): align turn-pin suites to the provider-cooldown window gate

The two native-codex-turn-pin suites landed via the #10379 merge wave after
PR #12247 forked, so #12247's green CI never saw them: they set up 'provider
in global cooldown' with a single recordProviderCooldown call, the pre-#12247
contract. Since the window gate, a provider only counts as cooling after
providerFailureThreshold failures inside the window — the setup now loops to
the profile threshold (same alignment the tracker's own legacy suite got in
Sibling sweep: all 7 suites touching recordProviderCooldown pass (60/60).
diegosouzapw added a commit that referenced this pull request Sep 1, 2026
…estFiles (#12263)

Gate check:mutation-test-coverage --strict red→verde local (registro dos 2 testes turn-pin no tap.testFiles, drift da mesma classe do #12170). O único check vermelho desta PR (Unit shard 4/4) é o base-red dos próprios testes turn-pin desalinhados pelo #12247 — corrigido pela #12259, mergeada na sequência. Reds circulares: cada PR só está vermelha no item que a outra corrige.
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…vider cooldown (diegosouzapw#12247)

providerFailureThreshold / providerFailureWindowMs / providerCooldownMs shipped
in PROVIDER_PROFILES with no runtime consumer (2026-08-31 docs audit, P0.1).
Provider-level entries in providerCooldownTracker now honor them: the whole
provider only counts as cooling after providerFailureThreshold failures inside
providerFailureWindowMs, then cools for providerCooldownMs. Connection-level
entries keep the pre-existing exponential backoff, and the layer stays opt-in
(PROVIDER_COOLDOWN_ENABLED, default off) — default behavior is unchanged.

TDD: tests/unit/provider-cooldown-window-gate.test.ts written first (4 red on
the old behavior), then the wiring; legacy tracker suite aligned to the new
contract (23/23 green). Docs: AGENTS.md breaker section + RESILIENCE_GUIDE
opt-in layer subsection; executors soft-drift refresh (104 -> 106).
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…tes aligned to the window gate (diegosouzapw#12255)

* chore(quality): register native-codex-turn-pin tests in stryker tap.testFiles

The mutation-test-coverage gate (--strict) fails on the release tip: the two
native-codex-turn-pin suites (diegosouzapw#10379 merge wave) cover open-sse turn-pin code
and src/shared/utils/circuitBreaker.ts but were not listed in
stryker.conf.json tap.testFiles, so their mutant kills would not count. Adds
both files; the gate now passes clean (4728 test files scanned, no drift).

* style: prettier pass on stryker.conf.json

* test(sse): align turn-pin suites to the provider-cooldown window gate

The two native-codex-turn-pin suites landed via the diegosouzapw#10379 merge wave after
PR diegosouzapw#12247 forked, so diegosouzapw#12247's green CI never saw them: they set up 'provider
in global cooldown' with a single recordProviderCooldown call, the pre-diegosouzapw#12247
contract. Since the window gate, a provider only counts as cooling after
providerFailureThreshold failures inside the window — the setup now loops to
the profile threshold (same alignment the tracker's own legacy suite got in
Sibling sweep: all 7 suites touching recordProviderCooldown pass (60/60).
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…estFiles (diegosouzapw#12263)

Gate check:mutation-test-coverage --strict red→verde local (registro dos 2 testes turn-pin no tap.testFiles, drift da mesma classe do diegosouzapw#12170). O único check vermelho desta PR (Unit shard 4/4) é o base-red dos próprios testes turn-pin desalinhados pelo diegosouzapw#12247 — corrigido pela diegosouzapw#12259, mergeada na sequência. Reds circulares: cada PR só está vermelha no item que a outra corrige.
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.

1 participant