Round-6 remediation: 7 blockers closed — priced explain alternatives, request-level data-protection enforcement, evidence-gated cache, honest savings

2026-08-09

routerapisecurityobservabilityintelligence

LOCKSTEP TRACEABILITY MATRIX --- api_endpoints: [ "GET /v1/explain/{request_id}", "POST /v1/chat/completions", "POST /v1/messages", "GET /deploy.json", ] sdk_methods_updated: [ "ts: ExplainAlternative.price_per_1k (client.explain.get)", "ts: DataProtectionRequest.no_training + .frameworks (exported)", "py: DataProtectionRequest TypedDict (exported)", "py: ExplainRequest.get / AsyncExplainRequest.get docstrings", ] mcp_tools_updated: ["none"] ---

What We Built

This entry consolidates two remediation waves (commits 23e303c09 Wave A and d162cb656 Wave B) that answer the defects surfaced by the round-6 stochastic review. Seven blockers were closed:

  1. Priced explain alternatives. GET /v1/explain/{request_id} now reports a

price_per_1k on every entry in alternatives_considered, threaded from the routing trace's consideredCandidates (each priced at decision time). The assembler also stopped short-circuiting on a single-arm banditCandidates array, which had been yielding zero alternatives even when the selector genuinely weighed a pool.

  1. Request-level data-protection enforcement. A data_protection block on

the completion body is now composed tighten-only into the router's endpoint filter (zero retention / no-training), so a per-request compliance override finally reaches routing instead of being inert. Malformed blocks fail closed with a field-named 400 rather than resolving as absent.

  1. **Observed-effect readiness + build-info unification + /deploy.json +

monitoring alarm.** All provenance surfaces (/health, /health/ready, /attestation, /deploy.json) now derive commit/version from one getBuildInfo(), so they can never disagree; a new unauthenticated GET /deploy.json manifest and a monitoring-stack alarm-metrics fix ship alongside.

  1. SDK auto-model + catalog counts. README/quickstart drift corrected — the

catalog truth is 44 models / 9 providers, derived from provider-catalog-capabilities.ts by scripts/catalog-counts.ts.

  1. Evidence-gated cache hits. Prompt-cache governance now withholds a cache

hit when an evidence receipt is required but uncommitted.

  1. Honest savings/usage. Savings baselines and usage queries were corrected

to attribute against the considered-declined candidate, not a fabricated headline model.

  1. Credentialed /auth CORS. /auth/* responses now emit credentialed CORS

correctly for the dashboard's Supabase-JWT origin.

Why It Matters

Two of these are contract-facing and drove the lockstep work here. Compliance buyers ask "can I demand zero-retention or no-training on a single request?" — the answer is now yes, enforced, and fail-closed. And integrators auditing routing decisions can now see the _price_ of each rejected alternative, not just its score, closing the loop on "why did you pick this model over the cheaper one."

How It Works

The explain alternative gains one nullable field:

export type ExplainAlternative = {
  model: string;
  score: number | null;
  price_per_1k: number | null; // USD/1k tok, priced at decision time; null when unpriced
  rejection_reason: string;
};

The request override is additive and tighten-only:

{
  "model": "auto",
  "messages": [
    /* ... */
  ],
  "data_protection": {
    "retention_max_days": 0, // forces dataPolicy: "zero"
    "no_training": true, // forces at least "no-training"
    "frameworks": ["hipaa"],
  },
}

Unknown keys inside data_protection return 400 invalid_data_protection with the offending param.

The Numbers

7 blockers closed across 2 waves; catalog truth reconciled to 44 models / 9 providers. Full auditor context: docs/reviews/2026-08-08/ledger.json.

Competitive Edge

Portkey and OpenRouter expose routing metadata after the fact; neither lets a single request _raise_ the data-protection floor and have eligible endpoints fail closed when they can't honor it. BR treats a per-request compliance demand as a routing constraint, not a logging annotation.

Lockstep Checklist

> _Contract surfaces propagated in the same push._

  • [x] API Routes: src/api/routes/explain-request.ts,

src/api/routes/completions/index.ts, src/api/middleware/data-protection.ts (committed in 23e303c09/d162cb656).

  • [x] TS SDK: ExplainAlternative.price_per_1k added;

DataProtectionRequest extended with no_training + frameworks and now exported from index.ts. Root pnpm tsgo clean.

  • [x] Python SDK: DataProtectionRequest TypedDict added and exported;

sync + async explain docstrings document price_per_1k.

  • [x] MCP Schemas: No change required — br_explain_request is a passthrough

returning unknown with no output field schema, and agents.json describes the tool in prose (no response-field enumeration).

  • [ ] Master Record: not touched (no new capability surface; refinements to

existing routes).

Deliberate non-changes

  • Completion request body is OpenAI-passthrough in both SDKs (TS

Record / PY Dict[str, Any]), so data_protection has no generated request model. It is documented via the hand-written DataProtectionRequest doc-type in each SDK — matching the existing ProviderFilter convention.

  • GET /deploy.json is an unauthenticated discovery/meta file (not a

/v1/* contract). Neither SDK enumerates meta files like build.json, so it has no natural SDK home and was intentionally not added — consistent with the pre-push hook's SDK-relevance allowlist, which excludes it.

---

Grants management unadvertised (claim-auditor blocker)

Decision (owner: Justin): the capability-grant management API is not enabled in production — the /v1/grants/ REST routes and the br_grant_ MCP tools are gated per-tenant behind the fail-closed-off grants_api rollout flag, so every real caller receives 403 feature_disabled. Advertising the five management tools as agent capabilities was therefore a claim the platform could not honor. We unadvertise the management surface while keeping all enforcement/verification code and the management implementation intact.

Gap confirmed (read-only)

  • /v1/grants issue/attenuate/revoke, /v1/grants/{id} get/chain/check, list —

all mounted as capability defs but every one carries admission: grantsAdmission

  • an in-handler grantsApiEnabled check (src/api/capabilities/grants/_shared.ts,

GRANTS_API_FLAG = "grants_api", fail-closed off; src/infra/feature-flags.ts has no default that enables it). Not reachable in prod.

  • The five MCP tools (br_grant_issue/attenuate/revoke/inspect/check) were

registered unconditionally in src/mcp/server.ts and enumerated in MCP_TOOL_MANIFEST → agents.json + all manifest-derived discovery surfaces. They forward to src/api/mcp-adapters/grants.ts, which itself gates on evaluateGrantsAccessfeature_disabled.

What changed (advertising only)

  • src/mcp/grant-management-tools.ts (new): houses the 5 tool manifest

entries (GRANT_MANAGEMENT_TOOLS) + the deploy-level predicate grantsManagementAdvertised() (BR_GRANTS_API_ADVERTISED === "1", fail-safe off — mirrors the BR_BEHAVIOR_CERT_DELEGATION_CHAIN convention). Kept in a separate module so tool-manifest.ts's textual entry count (the doc-drift gate's source of truth) reflects what is actually advertised.

  • src/mcp/tool-manifest.ts: grant entries spread in only when advertised

(...(grantsManagementAdvertised() ? GRANT_MANAGEMENT_TOOLS : [])). Textual count 121 → 116.

  • src/mcp/server.ts: registerGrantTools gated by the SAME predicate — so

a tool is never registered without its TOOL_PERMISSIONS entry (which would fail OPEN in checkToolPermission).

  • site/public/.well-known/agents.json: regenerated via

scripts/generate-agents-json.ts (default env) → 5 tools removed, 121 → 116; prose "exposing 116 control-plane tools".

  • Count prose 119 → 116 (also fixes a pre-existing 2-stale drift) in

site/public/llms.txt (×3), src/api/server.ts embedded /llms.txt (×2), docs/concepts/mcp.mdx (×2). Drift gate MCP-count now clean at 116.

  • Regenerated: site/public/llms-full.txt, src/api/static-assets.generated.ts

(re-embeds agents.json + llms-full), site/public/routes.json (route set unchanged — grant routes stay mounted, so 663 routes as before).

  • src/api/capabilities/discovery/root-manifest.ts: contract_summary.delegation_chain

reworded — dropped the "POST /v1/grants/{id}/attenuate mints…" management instruction; kept the enforcement/verification narrative (X-BR-Grant-Id, derived act chain, revocation cascade, JWKS) and noted management is not GA.

  • Tests: src/mcp/grant-tools.test.ts opts in via BR_GRANTS_API_ADVERTISED=1

before importing the server (restored in afterAll); src/mcp/tool-manifest.test.ts gains a suite asserting the default-off unadvertising + RBAC-safe re-enable.

Deliberately LEFT LIVE (enforcement/verification — do not touch)

  • Inline PDP / resolveGrantForRequest / enforceGrantStructure /

require-grant gate / short-circuit-grant-consume / guardian grant path.

  • JWKS at /.well-known/brainstorm/grant-keys and grant-chain verification.
  • The /v1/grants/* routes stay mounted (flag-gated) — so

llms-full.txt/routes.json still document them as routes. Flipping BR_GRANTS_API_ADVERTISED=1 alongside the grants_api flag restores the full advertised surface (the implementation was retained, not deleted).

Verification

  • pnpm tsgo → exit 0.
  • src/mcp/grant-tools.test.ts (66 incl. adapter/server), src/mcp/tool-manifest.test.ts

(7), src/api/static-assets.test.ts, src/api/mcp-adapters/index.test.ts — all pass.

  • Doc-drift gate: MCP-tool-count clean at 116. (Remaining failures are the

unrelated 45→48 model-count drift from the concurrent catalog-refresh workstream — out of scope here.)