Changelog

Every release, with the routing, tracing and policy changes that shipped in it.

RSS
v1.0.0-alpha
May 22, 2026 – Sep 23, 2026
31 releasesContains breakingfeatures ×28fixes ×22docs ×3performance ×1
Sep 23, 2026
Breaking

⛰️ Features

  • (code) Make slash launcher the primary control (#935)
  • (extensions) [breaking] Add native request-check host (#923)

⚙️ Miscellaneous Tasks

  • Sync registry catalog (#937)
Sep 22, 2026

⛰️ Features

  • (router) Add named routers and preset migration (#916)
  • (tui) Add supervised background agent control deck (#927)
  • Add router request checks and receipts (#919)

🐛 Bug Fixes

  • (tui) Cancel deck jobs before exit cleanup (#928)
  • Make saved and running config state explicit (#918)

⚙️ Miscellaneous Tasks

  • Sync registry catalog (#929)
  • Sync registry catalog (#920)
  • Sync registry catalog (#915)
Sep 16, 2026
Breaking

⛰️ Features

  • (acp) Add checkpoints and assessment revisions (#903)
  • (acp) Persist canonical session trajectories (#902)
  • (cli) [breaking] Rename the invocation to bro
  • (config) Add provider header policies (#910)
  • (control) Add remote router administration (#901)
  • (evolution) Add checkpoint TS routing (#907)
  • (mcp) Add native skills gateway support (#912)
  • (registry) Automate canonical model lifecycle (#876)
  • (tui) Adopt native scrollback (#904)
  • (tui) Replace dashboard with conversation
  • (tui) Improve scrollback and transcript rendering (#899)

🐛 Bug Fixes

  • (codex) Preserve ACP tools through Responses (#892)
  • (update) Delegate managed installs (#898)

🚜 Refactor

  • (mcp) Remove OSS origin server (#913)

📚 Documentation

  • Correct MCP spend report command (#911)

⚙️ Miscellaneous Tasks

  • Sync registry catalog (#914)

  • Breaking (MCP): remove the OSS first-party origin server. The bitrouter-mcp crate, bro mcp serve, bro mcp install, daemon /mcp-control endpoint, and automatic bitrouter_skills injection are removed. Local agents operate BitRouter through the shipped Agent Skill and structured bro CLI. The upstream MCP client/gateway, aggregate /mcp, Skills-over-MCP relay/cache, server-side tool loop, and bro mcp check remain.

  • Breaking (CLI): the invocation is now bro. bitrouter <cmd> becomes bro <cmd>. Only the invocation changed — the product, crate, npm package, Homebrew tap, bitrouter.yaml, ~/.bitrouter, BITROUTER_* environment variables, brk_ key prefix, and telemetry identifiers keep their names. Shell, PowerShell, npm, and Homebrew installers additionally create a deprecated bitrouter alias; invoking it prints one migration note on stderr while preserving structured stdout. The alias is installer-only, release archives contain bro, and the alias is removed in 1.0.0.

Sep 7, 2026

⛰️ Features

  • (cli) Unify ACP lifecycle surfaces (#885)

🐛 Bug Fixes

  • (sdk) Deduplicate server-tool stream usage (#895)
Sep 7, 2026

⛰️ Features

  • (cli) Complete searchable ACP onboarding (#888)

🐛 Bug Fixes

  • (sdk) Preserve routed cache usage (#893)
Sep 7, 2026
Breaking

⛰️ Features

  • (acp) Headless permission policy and output formats (#866)
  • (acp) Read harness authentication from the protocol (#860)
  • (acp) Harden v1 controller routing (#853)
  • (acp) Add controller identity and session routing (#852)
  • (acp) Add multi-session controller (#849)
  • (acp) Rebuild the ACP agent surface and add the chat TUI (#816)
  • (actions) [breaking] One table for status, list_models, route (#869)
  • (chat) Resolve slash commands against the actions table (#880)
  • (cli) Operate trajectory history
  • (eval) Publish trajectory operations
  • (eval) Add generic route evaluation workflow (#763)
  • (eval) Make policy locks the routing source (#762)
  • (launch) Route every catalog harness (#781)
  • (mcp) [breaking] Drop the complete tool from the origin server (#875)
  • (mcp) Upgrade to stable rmcp 3.1 for MCP 2026-07-28 (#760)
  • (observability) [breaking] Live router view and hosted launch (#803)
  • (optimize) Add agentic workflow loop (#777)
  • (policy) Route models by reasoning effort (#804)
  • (policy) Route agent workflows by predicted role (#790)
  • (policy) Add trajectory progress guard
  • (policy) Harden cost-aware workflow routing (#768)
  • (policy) Generalize agent trace routing (#757)
  • (registry) Add agents and runtimes as a primitive pair (#879)
  • (router) Add shadow classifier bakeoff (#865)
  • (router) Freeze routing measurement (#862)
  • (skills) [breaking] Unify discovery and conform to SEP-2640 (#870)
  • (skills) [breaking] Serve over MCP (SEP-2640), cut installer (#770)
  • (substrate) Detach/reattach session robustness (#743)
  • (trajectory) Reduce replayable health
  • (trajectory) Add durable event ledger
  • Optimize routes from observed history (#833)
  • Publish bitrouter/auto as the router slug (#788)
  • Guide @auto workflow optimization (#779)
  • Add MCP registry discovery (mcp search/list/add) (#759)
  • Add cache-aware routing, Terminus 2 identity, and Claude bridge (#717)

🐛 Bug Fixes

  • (auth) Preserve fallback semantics
  • (auth) Redact extension failures
  • (chat) Show the session log when a launch fails (#857)
  • (cli) Onboard into the default ACP TUI (#886)
  • (cli) Harden trajectory operations
  • (config) Make server.log_level set the log filter (#806)
  • (daemon) Authenticate restart kill target
  • (daemon) Await restart process exit
  • (db) Normalize anchored SQLite URLs on Windows
  • (eval) Preserve unguarded policy subjects
  • (eval) Scope trajectory decision credit
  • (launch) Say launch: not spawn: in console output (#798)
  • (pipeline) Settle routing failures
  • (policy) Bind progress guard evidence
  • (policy) Make runtime mode authoritative (#761)
  • (protocol) Preserve Anthropic tool extension fields (#774)
  • (responses) Budget shutdown drain per batch
  • (responses) Drain after slow reconciler shutdown
  • (responses) Close continuation safety gaps
  • (responses) Require graceful reconciliation
  • (responses) Fence continuation reconciliation
  • (responses) Bound continuation ownership state
  • (responses) Close continuation publication races
  • (responses) Harden continuation publication
  • (responses) Authorize continuation on delivery
  • (responses) Harden continuation delivery
  • (responses) Bind completed continuation
  • (responses) Persist gateway continuation
  • (responses) Preserve native continuation
  • (responses) Stabilize stream identity
  • (responses) Include response creation time
  • (router) Correct research measurement reports (#874)
  • (sdk) Normalize routed stream usage (#887)
  • (tests) Escape Windows database URLs in YAML
  • (tests) Drain settlements before restart assertions
  • (trajectory) Hold continuation starts at episode head (#829)
  • (trajectory) Align start and settlement clocks
  • (trajectory) Count recovery transitions
  • (trajectory) Preserve truncated ancestry honesty
  • (trajectory) Correct outbox delivery audit
  • (trajectory) Bind reused evaluation
  • (trajectory) Stabilize failed retries
  • (trajectory) Expose ancestry conflicts
  • (trajectory) Separate hold from tier selection
  • (trajectory) Validate initial episode start
  • (trajectory) Enforce replay lifecycle
  • (trajectory) Bind native evidence key
  • (trajectory) Close correlation edge cases
  • (trajectory) Harden correlation runtime
  • (trajectory) Harden ledger persistence
  • Point stale surfaces at commands that exist (#799)
  • Harden provider fallback errors (#755)

🚜 Refactor

  • (acp) [breaking] One ACP stack, from the engine to a flat chat loop (#848)
  • (acp) Move the ACP proxy engine into bitrouter-sdk (#793)
  • (docs) Consolidate internal specs under docs/ (#750)
  • (policy) Make selection trajectory-aware
  • (sdk) [breaking] Move the OTLP renderer out of the SDK (#851)
  • (substrate) Drop detach/reattach + fleet machinery (#751)
  • (tui) [breaking] Move all drawing into bitrouter-tui (#830)
  • Consolidate BitRouter Cloud SDK ownership (#846)
  • Unify task-aware routing on agent_route/v1 (#828)

📚 Documentation

  • Sync status and launch docs (#840)
  • Harden Harbor EC2 network preflight (#838)
  • Align docs with current CLI surfaces (#802)
  • Correct routing surface docs (#741)

⚡ Performance

  • (trajectory) Bound prefix lookup cardinality
  • (trajectory) Bound prefix correlation

🧪 Testing

  • (trajectory) Prove progress control

  • Headless permissions and formats for acp prompt / spawn -p. A headless run used to deny every session/request_permission; now the caller states the rule: --deny-all (still the default), --approve-reads (the ACP tool kind is read or search), --approve-all, and a per-tool --permission-policy '{"autoApprove":[…],"autoDeny":[…],"defaultAction":…}' (or @path). Each answer is a new NDJSON line, {"type":"permission","decision":"approved"|"denied","title":…,"kind":…}, and the process exits 5 when at least one request was denied and none approved. --format text prints the transcript exactly as bitrouter chat prints it to a pipe; --format quiet prints the assistant's text only; json (the default) is the unchanged NDJSON. The decision is made by bitrouter_tui::permission::Policy and reaches the agent through one shared interpreter (chat/effects.rs) that the interactive TUI, the piped chat, and acp prompt all run — the first session-verb parity between the terminal and the headless CLI.

  • Breaking (MCP): the origin MCP server's complete tool is removed. MCP is BitRouter's control and introspection surface; running a completion is what the daemon's HTTP inference API is for. Use it instead — it is the transport built for inference, and it always had the surface the tool did not: streaming, the full parameter set, and the metering path.

    // before — MCP tools/call
    { "name": "complete",
      "arguments": { "model": "openai/gpt-4o",
                     "messages": [{ "role": "user", "content": "hi" }] } }
    # after — the daemon's HTTP API (OpenAI-shaped; /v1/messages is the
    # Anthropic-shaped twin)
    curl http://127.0.0.1:4356/v1/chat/completions \
      -H 'content-type: application/json' \
      -d '{"model":"openai/gpt-4o","messages":[{"role":"user","content":"hi"}]}'

    What remains on bitrouter mcp serve is list_models, status, route_preview and the skills pair: what is routable, where it would go, and what it has cost. The stdio profile is now list_models + status + route_preview + skills_search + skills_get; the HTTP profile is list_models, plus status where the backend can answer it.

    The one-line spend footer went with it. It only ever rode successful complete results; status reports the same figure as typed structured content under spend, from the same metering database, with unpriced and the remaining cap a footer had no room for.

    Breaking (Rust API): bitrouter_mcp::backend::Backend::complete and the CompleteRequest / CompleteResponse / Usage types are gone; Backend is now a pure port-handover trait (status_port + models_port). Also removed: server::Builder::completion, server::CostFooter, BitrouterMcp::with_cost_footer, server::CompleteArgs, and ServeOptions::cost_footer. server::serve_stdio loses its cost_footer parameter and now takes the handler alone. serve_http_on, CloudBackend and CloudAuth are unchanged.

  • Breaking (MCP wire, SEP-2640): the skills extension's resources field now matches the specification the MCP Core Maintainers accepted on 2026-09-03. BitRouter previously implemented an earlier draft and emitted entries a conforming host must refuse. Three changes:

    // before — a skill entry BitRouter published
    {
      "uri": "skill://pdf-processing/SKILL.md",
      "frontmatter": { "name": "pdf-processing", "description": "…" },
      "resources": [
        { "uri": "skill://pdf-processing/SKILL.md", "digest": "sha256:…" }
      ]
    }
    
    // after
    {
      "uri": "skill://pdf-processing/SKILL.md",
      "frontmatter": { "name": "pdf-processing", "description": "…" },
      "resources": [
        { "uri": "skill://pdf-processing/SKILL.md", "digest": "sha256:…",
          "size": 5120 }                 // new, REQUIRED on every entry
      ]
    }
    1. size is required on every resources entry — the file's raw byte length. It lets a host budget a skill from the listing alone, and a read whose length differs from size is now a verification failure equivalent to a digest mismatch, whether or not the digest is computed.
    2. resources is required, and "dynamic" is a string marker. The draft let the key be omitted to mean "generated dynamically"; the accepted specification requires the key and takes either the complete array or the literal string "dynamic". An entry with neither "is invalid, and hosts MUST NOT load it". The gateway therefore no longer republishes an upstream entry that omits resources; it skips it, as it already skipped other malformed entries.
    3. Per-skill limits are fixed: 512 resources entries and 16 MiB (16,777,216 bytes) summed over size. BitRouter will not serve or re-publish a skill exceeding either.

    Breaking (Rust API): bitrouter_sdk::mcp::skills::SkillResource gains size: u64, and SkillEntry::resources changes from Option<Vec<SkillResource>> to the new SkillResources enum (Enumerated(Vec<SkillResource>) | Dynamic).

  • Breaking (CLI): bitrouter skills list --json changes shape, and the command sees more skills than it used to. bitrouter skills list and the MCP skills_search tool are now one action over one report type.

    // before
    { "skills": [{ "name": "alpha", "path": "/p/.claude/skills/alpha" }] }
    
    // after
    { "skills": [{
        "name": "alpha",
        "description": "What alpha does",          // new
        "dir": "/p/.claude/skills/alpha",          // was `path`
        "skill_md": "/p/.claude/skills/alpha/SKILL.md",  // new
        "valid": true,                             // new
        "problem": "…"                             // new, omitted when valid
    }] }

    path meant the skill directory to the CLI and the SKILL.md file to the MCP tool. Neither was wrong; sharing one key for both was, so both surfaces now carry dir and skill_md.

    Three behaviour fixes ride along, all from collapsing three discovery rules over two roots into one:

    • All three conventional layouts are listed. bitrouter skills list read only <root>/.claude/skills, so a ./skills/foo skill was invisible to it while the agent could see it.
    • A skill that cannot be loaded is listed and explained, with valid: false and a problem, instead of being listed unmarked by the CLI and dropped silently by the agent's surface. SEP-2640's skills/list still publishes only the loadable ones, which the specification requires.
    • The MCP surfaces read the user-global root, which only -g used to reach. An agent no longer misses a skill because of where it was installed.
  • Fixed (MCP): a bitrouter mcp install-ed client now sees the skills tools. mcp install writes ["mcp", "serve"], but the skills and SEP-2640 surfaces were wired only under mcp serve --backend skills, so an installed client never saw a skill. Every stdio profile now carries them — the identity argument that makes --backend skills stdio-only (the server is a subprocess of the caller whose machine it is) holds identically for stdio mcp serve. The multi-tenant HTTP profile is unchanged and still carries neither.

  • Breaking (CLI): bitrouter route --json changes shape. bitrouter route and the MCP route_preview tool are now one action over one report type, and the report keeps route_preview's richer vocabulary — it was the superset, and it is the one an agent reads. Duplicated keys for one fact are exactly the drift the unification exists to remove, so the old names are gone rather than deprecated.

    // before — `bitrouter route gpt-5 --json`
    {
      "model": "gpt-5",
      "resolved_via": "config",
      "chain": [{ "provider": "openai", "service_id": "gpt-5", "protocol": "openai" }]
    }
    
    // after
    {
      "requested_model": "gpt-5",          // was `model`
      "effective_model": "gpt-5-codex",    // new: what the policy table selects
      "effective_effort": "high",          // new, omitted when policy selects none
      "resolved_via": "config",            // now live | config | zero_config
                                           // (was live daemon | config | zero-config)
      "policy_decision": { … },            // new, omitted on the live-daemon path
      "provider_chain": [                  // was `chain`
        { "provider": "openai", "service_id": "gpt-5-codex", "api_protocol": "openai" }
                                           // `protocol` → `api_protocol`
      ],
      "estimated_cost": { … }              // new, omitted when the registry prices nothing
    }

    Migration is mechanical: .model → .requested_model (read .effective_model if you want what would actually run), .chain → .provider_chain, .chain[].protocol → .provider_chain[].api_protocol, and .resolved_via == "live daemon" → "live" / "zero-config" → "zero_config". The resolved_via values are now the same words bitrouter models --json uses for the same fact (live / config), instead of two spellings that almost matched.

    Two behaviour fixes ride along. bitrouter route now runs the policy table in its config fallback, as route_preview always did — it could previously name a model the daemon would never pick, which is why effective_model is a separate field from requested_model. (The live-daemon path is unchanged on both surfaces: the daemon's route verb resolves the model as given, so a live answer reports effective_model == requested_model and no policy_decision.) And route_preview now resolves config per call instead of snapshotting it at bitrouter mcp serve start, so an edited bitrouter.yaml is visible to a long-lived MCP server, as it always was to the CLI.

  • Breaking (Rust API): bitrouter_mcp::capabilities::routing is gone. The routing port moved to bitrouter_mcp::actions::route and is now typed: RoutingQuery::preview(RoutePreviewArgs) -> serde_json::Value becomes RouteQuery::route(RouteInput) -> RouteReport. ServeOptions::routing takes the new trait object.

  • Breaking (MCP tools): the origin server's status and list_models tools return the same report types as bitrouter status and bitrouter models, and advertise them as output_schema.

    • list_models was a bare [{ id, provider }] that kept only the first provider of each model. It is now { models: [{ id, providers: [...] }], resolved_via: "live" | "config" } — the whole fallback chain per model — with an optional provider argument (the same filter as bitrouter models --provider). On stdio + local it reads the daemon's live routing table over the control socket and falls back to a config parse, so it answers with no daemon running; resolved_via says which view it is.
    • status was a GET /v1/models in disguise ({ listen, models, providers } locally, the raw balance on cloud). It is now { running, pid?, listen?, models?, providers, socket?, spend? }: a stopped daemon is running: false, not a tool error, and spend carries two independent halves — spent (today's locally metered estimate, with unpriced saying how partial it is) and limit (a metered account's remaining credit). It is no longer served on HTTP + local — nothing on that transport can read the daemon's control socket — and no longer carries the free-text spend footer, which is now the typed spend block (the footer is gone from the server entirely — see the complete removal above).
  • bitrouter status --json gains providers[] (the distinct providers behind the routable models) and spend; bitrouter models --json gains resolved_via. Both are additive — every pre-existing key is unchanged. bitrouter models now prefers the running daemon's catalog, like bitrouter route, and falls back to the config parse it always used; standalone answers (models, route, spawn's Codex preflight) now resolve a config the way the daemon does, so a subscription-backed provider (claude-code, google-ai) is no longer missing from them.

  • Breaking (Rust API): bitrouter_mcp::backend::{ModelInfo, StatusInfo, ProviderStatus} and Backend::{list_models, status} are gone; Backend gains status_port / models_port (Option<Arc<dyn StatusQuery>> / Option<Arc<dyn ModelsQuery>>), Builder::completion_local is gone (its models(...) half is what survives — see the complete removal above), and ServeOptions gains status and models. bitrouter_sdk::language_model::routing::ModelInfo is the element type of the shared report and now derives JsonSchema, PartialEq and Eq.

  • Breaking (CLI): bitrouter skills add, remove, find, and update are removed, along with the bitrouter-skills crate that backed them. Installing skills is the ecosystem's job — npx skills add, or the Claude Code / Codex plugin marketplaces (this repo ships as one). BitRouter reads the installed-skills directory and serves it over MCP; it does not populate it. That is the same line as "server, not host" applied to content lifecycle: BitRouter handles transport, not distribution.

    bitrouter skills list and bitrouter skills init remain. SKILL.md format support moved into the binary (apps/bitrouter/src/skills/), where its only consumers live; the git-clone, source-resolution, install-to-disk, and registry-client code is gone. The --registry / --namespace flags and the api.bitrouter.ai skills-hub client went with them.

  • Skills over MCP (SEP-2640). BitRouter now serves Agent Skills as an MCP server and proxies them as a gateway, over stdio and Streamable HTTP alike. bitrouter mcp serve --backend skills answers skills/list, skills/get, resources/list, and resources/read over the installed-skills root, with complete sha256: digests per file; the existing skills_search / skills_get tools are unchanged and still served. The daemon's aggregate POST /mcp merges upstream skill catalogs, namespacing each under its configured server name (skill://<server>/<skill-path>/SKILL.md) so two upstreams publishing the same URI cannot shadow one another. BitRouter is a skills server and gateway, never a host: no daemon path installs skills, and gateway-sourced content never touches a filesystem skill-discovery path. Caveats are documented in skills/bitrouter/references/mcp-server.md — the gateway is not a security boundary, and remote catalogs are daemon-scoped rather than caller-scoped.

  • Breaking (behaviour): aggregate resources/read (POST /mcp) no longer tries each member and returns the first success. It resolves exactly one owning member — by skill-URI label, else by which member enumerates the URI — and errors when zero or several match, naming the candidates. First-success scanning let configuration order silently decide which upstream answered a URI two members both served, which is a cross-origin misroute (and the impersonation surface SEP-2640 names for skills). A URI that no member enumerates is now an error on the aggregate endpoint; read it from that server's direct route (POST /mcp/{server}) instead.

  • The gateway's initialize now advertises the resources capability and declares the io.modelcontextprotocol/skills extension. Skills are read through resources/read, so a compliant client that saw no resources capability would never issue one. The extension is declared optimistically — upstream capabilities are discovered lazily, so the gateway cannot know at handshake time whether any member serves skills.

  • Breaking (Rust API): BenchmarkOutcomeRecord has a new request_id field and strict reward feedback joins it to the persisted CapturedIngressTrace.id. Migrate Rust struct literals to BenchmarkOutcomeRecord::new(session_key, task_id, reward) followed by .with_request_id(trace_id) when producing reward-feedback artifacts. Older outcome JSONL remains serde-compatible (request_id defaults to absent), but it is analytical-only and strict feedback rejects it.

  • Breaking (policy routes): active policy_table routing now uses one predictive route contract: agent_route/v1|<task-family>|<role>|<risk>. Exact task-family routes fall back to the corresponding unknown-family role/risk baseline, then to the policy default. Observed agent_trace/v2 keys remain telemetry only. Static agent_trace routes, three-segment predictive v1 routes, and all v2 predictive routes are rejected during config and lock validation. Regenerate policy locks and certificates with the current predictor contract.

    key_strategy: agent_trace selects this deterministic predictor; the retired workflow_state and legacy_fingerprint spellings are rejected. adequacy.max_downgraded_requests_per_session is rejected: session identity is diagnostic-only and no longer affects routing. adequacy.explore_opening is honored for source-neutral opening projections.

  • Rust API: PolicyKeyStrategy now exposes only the canonical AgentTrace variant. PolicyDecision keeps workflow_state_kind and workflow_identity; PolicyDecisionRecord keeps workflow_state and workflow_identity; and PolicyDecisionSummary keeps by_workflow_state. Their JSON output uses canonical trace_state, trace_identity, and by_trace_state names while accepting the old JSON spellings on input. The matching trace_* accessors are available for new Rust callers.

Jul 18, 2026

⛰️ Features

  • (sdk) Clarify request timing metrics (#738)
  • (tui) Scrollable PTY panes (host scrollback + mouse forwarding) (#734)
  • (tui) Wire MCP and skills gateways into harnesses (#732)
  • (tui) Composite manager (#715)

🐛 Bug Fixes

  • (fleet) Non-blocking spawn/prompt so long turns don't time out (#737)
  • (sdk) Isolate protocol request extras (#733)

🚜 Refactor

  • (tui) Split state.rs into a state/ module (#730)
Jul 15, 2026

⛰️ Features

  • (acp) Route spawn sub-agents through daemon by default (#705)
  • (cli) Add cloud API command (#718)
  • (routing) Adaptive, self-optimizing policy-table routing (#710)

🐛 Bug Fixes

  • (sdk) Preserve upstream bad requests (#716)

🚜 Refactor

  • Remove attestation, fold plugins/ into crates/ (#701)
  • Relocate bitrouter-mcp crate under crates/ (#704)
Jul 12, 2026

⚙️ Miscellaneous Tasks

  • Refresh Rust dependencies and MSRV (#699)
Jul 11, 2026

🐛 Bug Fixes

  • (sdk) Preserve streaming preflight errors (#696)
  • (update) Detect npm installs in self-updater (#689)
  • Record canonical stream timing and OTEL latency (#697)
Jul 11, 2026

⛰️ Features

  • (agents) Add pi-acp to the ACP catalog (#685)
  • (providers) Add SuperGrok BYO subscription (#676)
  • Ship Claude Code and Codex agent plugins (#683)
  • Add AWS Bedrock, Azure, Vertex built-in providers (#647)

🐛 Bug Fixes

  • (sdk) Preserve token limits and upstream errors (#692)
Jul 9, 2026

⛰️ Features

  • Make registry dist runtime-only (#641)
  • Refactor registry provider variants (#639)

🐛 Bug Fixes

  • Preserve stream error settlement (#656)
Jul 7, 2026

⛰️ Features

  • Make registry dist runtime-only (#641)
  • Refactor registry provider variants (#639)

🐛 Bug Fixes

  • Preserve stream error settlement (#656)
Jul 6, 2026

⛰️ Features

  • (cli) Spawn codex agent (#631)
  • (cli) Route update through the JSON output layer (#620)
  • (cli) JSON output layer with a uniform error envelope (#610)
  • (server-tools) Built-in web_fetch tool (BYOK) (#612)
  • (server-tools) Add Tavily web_search backend, drop Perplexity (#608)
  • (server-tools) Built-in web_search with BYOK backends (#603)
  • (update) Add bitrouter update self-updater (#607)

🐛 Bug Fixes

  • (codex) Harden Codex spawn checks (#632)
  • (config) Don't expand ${VAR} inside YAML comments (#609)
  • (observe) Stop the settle span double-counting as a telemetry event (#605)

📚 Documentation

  • Align docs with current CLI (#637)

⚙️ Miscellaneous Tasks

  • Migrate registry into OSS dist (#636)
Jun 23, 2026

⛰️ Features

  • (cli) Wait for daemon readiness on start; auto-start it on spawn (#597)
  • (telemetry) Live account-bearer refresh + $lib/$screen_name attributes (#598)
Jun 23, 2026

⛰️ Features

  • (claude-code) Route Claude Code traffic to a dedicated subscription provider (#593)
  • (messages) Preserve thinking-block signature through the streaming round-trip (#592)
  • (observe) Opt-in first-party telemetry export (#588)
  • (providers) Source built-ins from the registry snapshot (#591)
  • (registry) Registry-backed model resolution (#589)
  • (spawn) Launch coding agents through BitRouter via bitrouter spawn (#584)
  • (telemetry) Account-authenticated exports + anonymous opt-out (#596)
  • Read the existing Claude Code session for Claude subscription auth (#590)

🐛 Bug Fixes

  • (claude-code) Detect subscription traffic by the agent-profile beta (#594)
Jun 18, 2026

⛰️ Features

  • (attestation) NEAR confidential-inference verification (L1 + L1.5) (#563)
  • (config) JSON Schema + config validate for IaC (#575)
  • (fusion) Multi-model deliberation server tool + alias (#574)
  • (mcp) Answer the MCP initialize/ping handshake at the gateway (#561)
  • (sdk) Expose server-tool usage for observability (#568)

🐛 Bug Fixes

  • (attestation) [breaking] Pin & assert TDX base MRs (#567) (#578)
  • (attestation) Enforce DCAP TCB status floor (#573)
  • (chat) Buffer streamed tool call until name arrives (#577)

🚜 Refactor

  • (server-tools) Move advisor/sub-agent into the SDK (#576)
Jun 13, 2026

⛰️ Features

  • (server-tools) Router-executed server-side tool loop (#555)
  • (server-tools) Replace owned provider-defined tools on inject (#559)
  • (server-tools) Pass ToolContext to RouterToolset (#558)
  • Protocol-native routing (#554)
Jun 11, 2026

🐛 Bug Fixes

  • (chat) Drop provider-defined tools (no chat wire form) (#553)
Jun 11, 2026

⛰️ Features

  • (language-model) LanguageModelV3 parity for the canonical IR (#548)
  • (metering) Context-tier ("staged") pricing (#551)

🐛 Bug Fixes

  • (protocol) Don't fragment streamed tool calls (#552)
Jun 11, 2026

⛰️ Features

  • (mcp) Origin MCP server for BitRouter (#526) (#530)

🐛 Bug Fixes

  • (protocol) Translate tool_choice across protocols (#549)
Jun 9, 2026

⛰️ Features

  • (capabilities) Extend Capability vocabulary (tools, reasoning, web_search, logprobs) (#536)

🐛 Bug Fixes

  • (pipeline) Run non-streaming requests to completion (#538)
  • (stream) Bill prompt tokens on client disconnect (#537)
Jun 8, 2026

⛰️ Features

  • (capabilities) Capability-aware routing primitives + typed structured-output fields (B4) (#528)
  • (observe) [breaking] Forward cloud span attrs + content capture (#535)
  • (sdk) Surface MCP upstream 401/403 auth challenges (UpstreamAuth) (#534)
  • (sdk) Implement VirtualModel priority/cascade strategy (#521)

🐛 Bug Fixes

  • [breaking] Pre-1.0 security audit fixes + dead-code cleanup (#523)

🚜 Refactor

  • (cli) [breaking] Subcommand cleanup (placeholders + auth) (#524)
Jun 6, 2026

⛰️ Features

  • (providers) Claude & Codex OAuth subscriptions (#519)
Jun 6, 2026
Breaking

⛰️ Features

  • (sdk) [breaking] Per-target Messages auth scheme (x-api-key | Bearer) (#516)
Jun 3, 2026
Breaking

⛰️ Features

  • (skills) [breaking] Converge marketplace.json on Claude Code native schema (#512)
Jun 2, 2026

⛰️ Features

  • (cloud-sdk) Namespace-scoped management client + CLI (#508)
  • (messages) Integrate Opus 4.8 Messages API parameters (#509)
  • (observe) [breaking] Split otel feature into transport sub-features (#506)
  • (skills) Skills gateway client — bitrouter-skills crate + CLI (#511)
May 30, 2026
Breaking

⛰️ Features

  • (guardrails) [breaking] Plugin + per-account rule resolution (#503)
  • (observe) [breaking] GenAI-semconv trace hierarchy + outbound traceparent (#495)
  • (sdk) [breaking] Streaming gen_ai.response.id via StreamPart::ResponseStarted (#500)

🚜 Refactor

  • (sdk) [breaking] Rename API protocols to spec names (#504)
May 26, 2026

⛰️ Features

  • (bitrouter) Windows support for the daemon control surface (#490)
  • (sdk/mcp) Expose headers, set_caller, evict for auth (#494)

🐛 Bug Fixes

  • (sdk/anthropic) Fold cache buckets into prompt_tokens (Usage subset contract) (#492)
May 25, 2026

⛰️ Features

  • (cli) Bitrouter cloud subcommand for /v1/* management (#489)
  • (cli) OAuth 2.0 device-flow auth subcommand (#480)
  • (mcp) Aggregation + caching + SSE + sampling-deny (#484)
  • (observe) Migrate to OpenTelemetry with multi-tenant attribution (#475)
  • Bitrouter-cloud SDK + LLM provider with OAuth or API-key onboarding (#486)
  • PKCE OAuth login for Anthropic and OpenAI Codex (#481)

🐛 Bug Fixes

  • (bitrouter) Drop duplicate reqwest dep entry (#485)
May 22, 2026

⛰️ Features

  • (routing) Multiple accounts per provider — failover + load-balance (#473)
  • (sdk) Structured outputs (response_format) for all 4 protocols (#472)
  • (sdk) Add RouterOptions to opt out of built-in routes (#478)
  • (sdk) Derive JsonSchema on wire types (#467) (#469)

🐛 Bug Fixes

  • (daemon) Re-apply built-in provider catalog on file reload (#476)

🚜 Refactor

  • (db) Sea-orm migrations + all backends, no concrete driver (#474)