- quality-baseline.json: coverage.{statements,lines,functions,branches} floors (80/80/82/73, real ~82.58/82.58/84.23/75.22 with margin; tighten via --update after a green main run)
- check-quality-ratchet.mjs: --allow-missing (local quality:gate skips coverage.* without a coverage run; CI runs strict)
- ci.yml quality-gate job: needs test-coverage + downloads merged coverage-report so the ratchet enforces 'coverage cannot drop'
- TDD +1 test (6 total)
- check-test-masking.mjs: for each MODIFIED test file in a PR, flags net assert removal + new assert.ok(true) tautologies (base...HEAD diff). Directly enforces CLAUDE.md 'never weaken asserts to go green'
- wired into pr-test-policy CI job (reuses base fetch); no-op outside PR; TDD 5 tests
- check-file-size.mjs: frozen files can only shrink; new files must be <= cap (kills the next 12k-line god-component)
- file-size-baseline.json: 91 files frozen at current LOC (largest 12883)
- wired into CI lint job; TDD 5 tests; --update ratchets the baseline down on shrink
- check-fetch-targets: every dashboard fetch(/api/...) resolves to a real route.ts; found 7 pre-existing dashboard->route mismatches frozen as KNOWN_MISSING for triage
- check-openapi-routes: every openapi.yaml path resolves to a real route; found 1 stale spec entry (agent-bridge agents/{id}/state) frozen as KNOWN_STALE_SPEC
- check-deps: anti-slopsquatting allowlist (105 deps); new deps need explicit human-reviewed entry
- all wired into CI lint/docs jobs; TDD +12 tests (21 total across 5 gates)
#3462 added a process.env.COMMAND_CODE_VERSION read but did not document it,
tripping the env-doc-sync gate on the release branch (PR-merges bypass the
pre-commit check-docs-sync hook). Add the var to .env.example + ENVIRONMENT.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The custom-models loop in getUnifiedModelsResponse gated every model through hasEligibleConnectionForModel(getConnectionsForProvider(...)). no-auth providers (theoldllm, etc.) never create DB connection rows, so that returned [] and the gate dropped every imported/custom model for them — the Playground dropdown showed nothing for imported models while built-in/custom models on auth providers worked. Built-in models survived because they go through providerSupportsModel(), which already has a no-auth bypass (#2798).
The custom-model gate now applies the same no-auth bypass, keeping the eligibility check (with parentProviderType) intact for auth providers.
Co-authored-by: tjengbudi <tjengbudi@users.noreply.github.com>
Co-authored-by: a2belugin <a2belugin@users.noreply.github.com>
Claude Code -> claude-opus-4-8 turns intermittently died with 'tool call could not be parsed (retry also failed)'. OmniRoute's claude identity cloak rebuilt the anthropic-beta header from scratch and unconditionally forced interleaved-thinking-2025-05-14 (+ advanced-tool-use / effort for heavy agents), even when the client never negotiated them. The forced interleaved-thinking conflicts with tool_choice-forced turns, producing malformed opus tool_use streams (and sibling 400 'Thinking may not be enabled when tool_choice forces tool use').
selectBetaFlags now takes the client's inbound anthropic-beta: when present, thinking/effort betas are only emitted if the client requested them. Opaque clients (no header — the OAuth cloak path) keep the full set unchanged, so existing behavior and the #2454 model-tier gating are preserved.
Co-authored-by: Forcerecon <Forcerecon@users.noreply.github.com>
Vertex AI's FunctionCall/FunctionResponse protos have no id field; emitting it made Vertex reject tool calls with 400 'Unknown name id'. The id is now stripped only when the routed provider is vertex/vertex-partner (threaded via credentials._provider), preserving it for the public Gemini API where Gemini 3+ uses it for signature matching.
Co-authored-by: nullbytef0x <nullbytef0x@users.noreply.github.com>
npx playwright falls back to a registry download when playwright is absent from
the slim runtime image's node_modules. On GitHub-hosted runners this download
fails with exit 127, breaking both amd64 and arm64 -web image builds.
Fix: COPY playwright and playwright-core from the builder stage and invoke
node node_modules/playwright/cli.js directly — no network access, same version,
and playwright remains available at runtime for web-session providers.