A-3 — trust envelope load-bearing for routing: tier/scope/xdr_risk/anomaly gates
2026-05-09
LOCKSTEP TRACEABILITY MATRIX --- api_endpoints: ["none — internal routing change, no new routes"] sdk_methods_updated: ["none"] mcp_tools_updated: ["none"] ---
What We Built
applyTrustGates — the single function that translates trust-envelope claims into routing constraints. It runs BEFORE bandit selection in model-router-select.ts so every downstream strategy (quality, price, latency, Thompson sampling) operates on a trust-bounded candidate pool.
Signal precedence (first match wins, per Justin 2026-05-09):
br_trust.xdr_risk >= 0.7→ force-downgrade to "restricted" (price strategy + cost cap). External XDR signal is sourced outside BR, highest reliability.br_trust.anomaly_score >= 0.8→ downgrade nominal tier by one level. In-process detector, evaluated last.- Nominal tier (restricted/bronze) → price strategy + cost cap for restricted; price strategy only for bronze.
Scope filtering: br_scope.providers (non-empty) restricts to those providers; br_scope.models (not "*") restricts to listed model IDs.
Three modes:
"off"(default): pass-through, no filtering — A-2 behavior preserved."warn": compute gates, log when a constraint would have fired, return full candidate set."enforce": apply filtering + strategy overrides before bandit selection.
Wiring:
gateway.envelope.routing.modeconfig key →ModelRouterDeps.envelopeRoutingMode→ passed toapplyTrustGatesinresolveEndpoint.RouteCompletionParams.trustEnvelope→ set fromc.get("_trustEnvelopeDecoded")in the non-streaming completions handler.boot-router.tsreads the config key and passes it toinitModelRouter.
Lockstep Checklist
- [x] TypeScript SDK: no change (routing behavior, not API surface)
- [x] Python SDK: no change
- [x] MCP tools: no change
- [x] Config schema:
gateway.envelope.routing.modeadded tozod-schema.ts+types.gateway.ts - [x] OpenAPI: no change
- [x] Ship log: this entry
How to activate in production
- First activate A-2 synthesis:
gateway.envelope.synth.mode = "audit-only" - Then enable routing gates:
gateway.envelope.routing.mode = "warn"(observe for 1 week) - Once warn logs look correct:
gateway.envelope.routing.mode = "enforce"
The streaming path (routeCompletionStream) does not yet pass trustEnvelope — add in A-3.1 if streaming enforcement is needed before A-4.