TS-2 #248 — align audit, replays, streaming telemetry, feedback schema, cost center attribution

2026-05-09

apicompletionstelemetry

LOCKSTEP TRACEABILITY MATRIX --- api_endpoints: [ "POST /v1/usage/{requestId}/feedback (schema: rating → score)", "POST /v1/chat/completions stream=true (new telemetry headers)", ] sdk_methods_updated: ["none — no new endpoints"] mcp_tools_updated: ["none"] ---

What We Built

Three targeted fixes for the telemetry and attribution gaps Computer Protocol identified.

Fix 1 — Feedback schema alignment: OpenAPI declared rating (1-5 or boolean). The live validator required score (0-1 float). Fixed OpenAPI to match code: score: number (0.0–1.0). Autonomous agents following the spec can now submit quality feedback without a schema mismatch.

Fix 2 — Cost center attribution DB fallback: agentJwtAuth middleware fetches the agent profile from the in-memory cache. On a new ECS task (fresh boot, no prior requests from that agent), the cache is empty → profile = null_agentCostCenter never set → usage attributed to "unassigned". Added getFromDb fallback when cache misses, so the first request on a new task still attributes correctly.

Fix 3 — Streaming telemetry header parity: Non-streaming completions emit ~30 X-BR-* headers; streaming emitted ~8. Added core pre-stream headers to the streaming path: X-BR-Routed-Model, X-BR-Router-Original-Model (when failover), X-BR-Route-Reason (auto vs explicit), X-BR-Selection-Method, X-BR-Agent-Owner, X-BR-Agent-Cost-Center, X-BR-Agent-Lifecycle, X-BR-Budget-Remaining, X-BR-Agent-Budget-Remaining, X-BR-Memory-Facts-Injected. Post-stream headers (Provider-Latency-Ms, Quality-Score, Audit-Hash, Routing-Savings) remain streaming-only because they depend on values computed after the last byte.

What This Doesn't Fix

  • Replay decisions empty — the /v1/replays/decisions query is correct (reads from usage_events with status='ok'). If empty, it means either (a) DB not configured, or (b) no completions have run yet in the reporting window. No code change needed; the empty state already returns {decisions:[], count:0}.
  • Provider-Latency-Ms in streaming — only available after the stream completes; cannot be set as a pre-stream header. Best effort via setStreamHeader after the stream.

Lockstep Checklist

  • [x] TypeScript SDK: no change (behavior, not contract)
  • [x] Python SDK: no change
  • [x] MCP tools: no change
  • [x] OpenAPI: updated feedback schema (rating → score)
  • [x] Ship log: this entry