Skip to content

fix(routing): require consent and caller authorization for model fallback - #16810

Merged
diegosouzapw merged 13 commits into
release/v3.8.52from
fix/16406-fallback-policy-five-1016
Oct 17, 2026
Merged

diegosouzapw merged 13 commits into
release/v3.8.52from
fix/16406-fallback-policy-five-1016

Conversation

@diegosouzapw

@diegosouzapw diegosouzapw commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

A model-unavailable response could silently move a request to another model version and still identify the original model in the response. Internal cross-version family recovery now requires x-omniroute-allow-cross-version-fallback: true; same-version effort recovery remains available. After a fallback, the response header and normal response body identify the dispatched model. The explicit requested-model echo setting may retain its alias in the body.

The request policy resolves the original key scope for internal self-loop calls, rejects unknown scope, and composes API-key model grants with the hidden-model and active-connection lockout checks from #16223. The pipeline updates its own wire state before retrying and never bypasses a custom selector after an ineligible result. Browser CORS permits the opt-in header; the real Anthropic fixture confirms it stays out of upstream headers. Explicit combo targets retain their configured failover; the extra quality-recovery family hop stays within the same version and must separately pass direct model authorization. VS Code path-token requests retain the identity materialized by their public adapter.

Depends on #16223, integrated with contributor commits preserved. Earlier #16425 and #16780 address the separate dotted-id and connection-lockout parts of the report.

Refs #16406.

Validation

Current prepared head: ae0557b41ea81d578450c2e344f2c5809d05ddce, reconciled with release 858d6022270b73489dfa8d89eee6fcc9a6a9e214. The original contribution and dependency commits are preserved.

  • Before-fix HTTP/SSE, wire-state, self-loop and combo authorization regressions were reproduced; the corresponding controls remain covered.
  • Final authorization/fallback run: 143 tests pass; dashboard run: five tests pass. No failures or skips.
  • Reproduced boundary regression: base 774 edges (PASS), initial candidate 779 (FAIL). Move pure model-access contracts and effort constants into the engine and encapsulate application authorization behind its adapter: final 773 (PASS), ceiling unchanged at 774. One explicit engine-to-application adapter dependency remains; this does not claim complete layer separation.
  • Core and open-sse TypeScript checks pass with zero errors. Complexity and cognitive ratchets, file size, changelog, formatting and normal commit hooks pass.

These are focused checks using the existing matching dependency installation. Required CI/Quality and the final combined candidate must pass before merge; release has advanced since this pinned validation. No authenticated upstream smoke or deployment is claimed.

GitHub Actions and others added 11 commits October 10, 2026 16:05
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Preserve request allowlists and recognize tried provider aliases when selecting context fallbacks.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@diegosouzapw
diegosouzapw marked this pull request as ready for review October 17, 2026 05:17
diegosouzapw added a commit that referenced this pull request Oct 17, 2026
…ription (#16964)

Merged via /merge-batch (2026-10-17 wave, maintainer PRs). Validated on the 2026-10-17 combined board of 26 maintainer PRs over release/v3.8.52@3c3edb9ef: typecheck:core, open-sse typecheck, eslint on changed files, file-size, changelog-integrity, complexity, cognitive-complexity, env-doc-sync and agent-skills-sync all green; focused tests 618/618 (node:test) + 17/17 (vitest UI); boundary 774/774 on the combined tree (#16810 removes one engine->app edge, #16933 adds one, merged in that order); api-typecheck, dead-code, provider-consistency, docs-sync and i18n new-key coverage checked. Remaining CI reds are the inherited base-red #15306.
diegosouzapw added a commit that referenced this pull request Oct 17, 2026
…olden (#16962)

Merged via /merge-batch (2026-10-17 wave, maintainer PRs). Validated on the 2026-10-17 combined board of 26 maintainer PRs over release/v3.8.52@3c3edb9ef: typecheck:core, open-sse typecheck, eslint on changed files, file-size, changelog-integrity, complexity, cognitive-complexity, env-doc-sync and agent-skills-sync all green; focused tests 618/618 (node:test) + 17/17 (vitest UI); boundary 774/774 on the combined tree (#16810 removes one engine->app edge, #16933 adds one, merged in that order); api-typecheck, dead-code, provider-consistency, docs-sync and i18n new-key coverage checked. Remaining CI reds are the inherited base-red #15306.
diegosouzapw added a commit that referenced this pull request Oct 17, 2026
Merged via /merge-batch (2026-10-17 wave, maintainer PRs). Validated on the 2026-10-17 combined board of 26 maintainer PRs over release/v3.8.52@3c3edb9ef: typecheck:core, open-sse typecheck, eslint on changed files, file-size, changelog-integrity, complexity, cognitive-complexity, env-doc-sync and agent-skills-sync all green; focused tests 618/618 (node:test) + 17/17 (vitest UI); boundary 774/774 on the combined tree (#16810 removes one engine->app edge, #16933 adds one, merged in that order); api-typecheck, dead-code, provider-consistency, docs-sync and i18n new-key coverage checked. Remaining CI reds are the inherited base-red #15306.
diegosouzapw added a commit that referenced this pull request Oct 17, 2026
Merged via /merge-batch (2026-10-17 wave, maintainer PRs). Validated on the 2026-10-17 combined board of 26 maintainer PRs over release/v3.8.52@3c3edb9ef: typecheck:core, open-sse typecheck, eslint on changed files, file-size, changelog-integrity, complexity, cognitive-complexity, env-doc-sync and agent-skills-sync all green; focused tests 618/618 (node:test) + 17/17 (vitest UI); boundary 774/774 on the combined tree (#16810 removes one engine->app edge, #16933 adds one, merged in that order); api-typecheck, dead-code, provider-consistency, docs-sync and i18n new-key coverage checked. Remaining CI reds are the inherited base-red #15306.
diegosouzapw added a commit that referenced this pull request Oct 17, 2026
…c → OpenAI pivot (#16946)

Merged via /merge-batch (2026-10-17 wave, maintainer PRs). Validated on the 2026-10-17 combined board of 26 maintainer PRs over release/v3.8.52@3c3edb9ef: typecheck:core, open-sse typecheck, eslint on changed files, file-size, changelog-integrity, complexity, cognitive-complexity, env-doc-sync and agent-skills-sync all green; focused tests 618/618 (node:test) + 17/17 (vitest UI); boundary 774/774 on the combined tree (#16810 removes one engine->app edge, #16933 adds one, merged in that order); api-typecheck, dead-code, provider-consistency, docs-sync and i18n new-key coverage checked. Remaining CI reds are the inherited base-red #15306.
diegosouzapw added a commit that referenced this pull request Oct 17, 2026
…rip tests (#16949)

Merged via /merge-batch (2026-10-17 wave, maintainer PRs). Validated on the 2026-10-17 combined board of 26 maintainer PRs over release/v3.8.52@3c3edb9ef: typecheck:core, open-sse typecheck, eslint on changed files, file-size, changelog-integrity, complexity, cognitive-complexity, env-doc-sync and agent-skills-sync all green; focused tests 618/618 (node:test) + 17/17 (vitest UI); boundary 774/774 on the combined tree (#16810 removes one engine->app edge, #16933 adds one, merged in that order); api-typecheck, dead-code, provider-consistency, docs-sync and i18n new-key coverage checked. Remaining CI reds are the inherited base-red #15306.
diegosouzapw added a commit that referenced this pull request Oct 17, 2026
…elds (#16950)

Merged via /merge-batch (2026-10-17 wave, maintainer PRs). Validated on the 2026-10-17 combined board of 26 maintainer PRs over release/v3.8.52@3c3edb9ef: typecheck:core, open-sse typecheck, eslint on changed files, file-size, changelog-integrity, complexity, cognitive-complexity, env-doc-sync and agent-skills-sync all green; focused tests 618/618 (node:test) + 17/17 (vitest UI); boundary 774/774 on the combined tree (#16810 removes one engine->app edge, #16933 adds one, merged in that order); api-typecheck, dead-code, provider-consistency, docs-sync and i18n new-key coverage checked. Remaining CI reds are the inherited base-red #15306.
diegosouzapw added a commit that referenced this pull request Oct 17, 2026
… account pinning (#16963)

Merged via /merge-batch (2026-10-17 wave, maintainer PRs). Validated on the 2026-10-17 combined board of 26 maintainer PRs over release/v3.8.52@3c3edb9ef: typecheck:core, open-sse typecheck, eslint on changed files, file-size, changelog-integrity, complexity, cognitive-complexity, env-doc-sync and agent-skills-sync all green; focused tests 618/618 (node:test) + 17/17 (vitest UI); boundary 774/774 on the combined tree (#16810 removes one engine->app edge, #16933 adds one, merged in that order); api-typecheck, dead-code, provider-consistency, docs-sync and i18n new-key coverage checked. Remaining CI reds are the inherited base-red #15306.
@diegosouzapw
diegosouzapw merged commit 8708178 into release/v3.8.52 Oct 17, 2026
31 of 81 checks passed
diegosouzapw added a commit that referenced this pull request Oct 17, 2026
…e auto/* request path (#16814) (#16933)

Merged via /merge-batch (2026-10-17 wave, maintainer PRs). Validated on the 2026-10-17 combined board of 26 maintainer PRs over release/v3.8.52@3c3edb9ef: typecheck:core, open-sse typecheck, eslint on changed files, file-size, changelog-integrity, complexity, cognitive-complexity, env-doc-sync and agent-skills-sync all green; focused tests 618/618 (node:test) + 17/17 (vitest UI); boundary 774/774 on the combined tree (#16810 removes one engine->app edge, #16933 adds one, merged in that order); api-typecheck, dead-code, provider-consistency, docs-sync and i18n new-key coverage checked. Remaining CI reds are the inherited base-red #15306.
diegosouzapw added a commit that referenced this pull request Oct 17, 2026
Merged via /merge-batch (2026-10-17 wave, maintainer PRs). Validated on the 2026-10-17 combined board of 26 maintainer PRs over release/v3.8.52@3c3edb9ef: typecheck:core, open-sse typecheck, eslint on changed files, file-size, changelog-integrity, complexity, cognitive-complexity, env-doc-sync and agent-skills-sync all green; focused tests 618/618 (node:test) + 17/17 (vitest UI); boundary 774/774 on the combined tree (#16810 removes one engine->app edge, #16933 adds one, merged in that order); api-typecheck, dead-code, provider-consistency, docs-sync and i18n new-key coverage checked. Remaining CI reds are the inherited base-red #15306.
diegosouzapw added a commit that referenced this pull request Oct 17, 2026
#16930)

Merged via /merge-batch (2026-10-17 wave, maintainer PRs). Validated on the 2026-10-17 combined board of 26 maintainer PRs over release/v3.8.52@3c3edb9ef: typecheck:core, open-sse typecheck, eslint on changed files, file-size, changelog-integrity, complexity, cognitive-complexity, env-doc-sync and agent-skills-sync all green; focused tests 618/618 (node:test) + 17/17 (vitest UI); boundary 774/774 on the combined tree (#16810 removes one engine->app edge, #16933 adds one, merged in that order); api-typecheck, dead-code, provider-consistency, docs-sync and i18n new-key coverage checked. Remaining CI reds are the inherited base-red #15306.
@github-actions

Copy link
Copy Markdown
Contributor

CI Coverage Report

  • Coverage job: skipped
  • PR test policy: success

Coverage artifact was not available for this run.

diegosouzapw added a commit that referenced this pull request Oct 18, 2026
…s-version consent

#16810 gated the internal cross-version family hop behind
`x-omniroute-allow-cross-version-fallback: true`; without it an empty-content
answer from claude-sonnet-4.6 is returned as 502 instead of being recovered on
claude-sonnet-4.5. The three "empty family fallback preserves only explicit
effort" cases (from #13720) exercise exactly that hop and never sent the header,
so they failed with `502 !== 200` after 24s. Send the opt-in; the effort
propagation they assert is unchanged.

Refs #15306
diegosouzapw added a commit that referenced this pull request Oct 18, 2026
…port, route-guard locale proof, parseModel alias, family-fallback consent (#17007)

* test(sse): align the parseModel cache-key expectation with the #16811 Opus 4.5 contract

#16811 made the provider-qualified `anthropic/claude-opus-4.5` alias keep its
`anthropic` prefix and resolve to the dashed wire ID (`claude-opus-4-5`), leaving
only the bare alias on the dated snapshot. It updated its own regression test but
not this sibling from #16341, which still expected `provider: null`,
`claude-opus-4-5-20251101`, `isAlias: true`. The compat on/off results still
differ, which is what the cache-key test is about.

Refs #15306

* test(docs): bound the route-guard locale proof by the current paragraph order

#16691 moved the deny-list test reference ahead of the regex companion constant in
docs/security/ROUTE_GUARD_TIERS.md; the mirrors followed, but this test (from
#16504) still searched for that reference AFTER `SPAWN_CAPABLE_PATTERN_ANCESTORS`
and reported "missing localized policy proof" for all 66 locales. The window now
runs from the Kiro auto-import deny-list entry to the regex companion and asserts
the deny-list proof inside it; all 66 mirrors pass and the English-fallback and
hash checks are unchanged.

Refs #15306

* fix(mcp): keep apiKeyPolicy and next/headers out of the MCP server bundle's import time

`git bisect` on tests/unit/build/mcp-bundle-startup.test.ts lands on #16810, which
made src/shared/utils/modelFallbackAuthorization.ts import `resolveEnforcedPolicyKey`
from apiKeyPolicy. That module is reached from open-sse (modelFamilyFallbackPolicy),
so the MCP server bundle started carrying apiKeyPolicy → apiAuth → `next/headers`
(esbuild hoists the external import; plain Node cannot resolve it) and, once that is
out of the way, an async init cycle around sse/services/auth that leaves the import
with an unsettled top-level await (exit 13). #16499 then opened a second path into
apiKeyPolicy through keyConnectionScope → comboTargetKeyPolicy on the embeddings
service.

Load the three edges lazily, at the call sites that are already async:
modelFallbackAuthorization and keyConnectionScope import apiKeyPolicy /
comboTargetKeyPolicy inside the functions that use them, and apiAuth imports
`next/headers` only when it actually falls back to the request cookie store. The
bundle imports again on Node 24 and the request paths are unchanged.

Refs #15306

* test(chat): opt the family-fallback effort cases into the #16810 cross-version consent

#16810 gated the internal cross-version family hop behind
`x-omniroute-allow-cross-version-fallback: true`; without it an empty-content
answer from claude-sonnet-4.6 is returned as 502 instead of being recovered on
claude-sonnet-4.5. The three "empty family fallback preserves only explicit
effort" cases (from #13720) exercise exactly that hop and never sent the header,
so they failed with `502 !== 200` after 24s. Send the opt-in; the effort
propagation they assert is unchanged.

Refs #15306
@diegosouzapw
diegosouzapw deleted the fix/16406-fallback-policy-five-1016 branch October 18, 2026 23:49
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