Is BayesRoute production-ready at 1.0.0?
Yes. 511 tests across 22 suites pass under Vitest 4 with coverage of 98% statements, 96% branches, 99%
functions, and 98% lines; TypeScript 6 maximum strict mode is clean; Biome lint is clean;
publint and @arethetypeswrong/cli are clean across every subpath. The suite and the
distribution smoke test are run on the Node 20, 22, and 24 matrix. Every published release carries
provenance produced by GitHub Actions.
Why Thompson sampling instead of fixed weights?
Fixed weights never learn and go stale the moment a price or a model changes. BayesRoute keeps a Beta
posterior over acceptable output and Gamma-Exponential posteriors over latency and cost per model and
domain, samples each, and routes to the highest expected utility. That balances exploration and
exploitation with bounded regret, so good models earn traffic and weak ones lose it on evidence.
Why not a Python bandit library or a notebook?
Those are superb for offline experimentation in Python. BayesRoute is embeddable TypeScript for
production: closed-form conjugate updates with zero inference latency, a node-free core, and an API a
developer can use in five lines without a statistics background.
Does this work in Cloudflare Workers, Vercel Edge, Bun, or Deno?
Yes. The core is node-free; the audit seal uses the Web Crypto API, not node:crypto. Import
@takk/bayesroute or @takk/bayesroute/edge on any runtime with fetch
and Web Crypto. Only @takk/bayesroute/node requires the Node standard library.
How does BayesRoute handle my data?
BayesRoute records the model and domain identifiers you choose, the posterior parameters, the observed
quality, latency and cost, and timestamps. It never sees your prompts or completions and makes no outbound
network calls of its own. With the file store, only that operational state reaches disk; no secrets are
involved at any point.
What happens with a brand-new model (cold start)?
A new model and domain arm starts at its prior, the uniform Beta(1, 1) by default, so its belief is wide
and honest. To do better than a flat prior, set a per-domain prior with domainPrior; the
safe-exploration guard then gives the new arm a fair, bounded share of traffic until it has data of its
own.
Where does the state live?
In-process memory by default, with portable JSON snapshots via snapshot() and
load(). For durability across restarts, use createFileStore from
@takk/bayesroute/node. For multi-process coordination, implement the PosteriorStore
interface over SQLite, Postgres, or Redis.
Is the audit trail a digital signature?
No, and the docs are explicit about it. The seal is a SHA-256 hash-chain root that proves a log was not
altered after sealing. It is an integrity seal, not a signature: it does not prove who produced the log.
Signed and timestamped seals for stronger third-party evidence are on the roadmap.
Is the regret bound a guarantee on real traffic?
Under the model, roughly stationary rewards per arm, yes, regret is bounded as evidence accumulates. Real
traffic is bursty and non-stationary, so use the safe-exploration guard and time-decay, and confirm the
routing on your own data via the audit trail and router.rank(domain).
How do I verify a published version's provenance?
Every release is published with npm publish --provenance. Check the attestations with
npm view @takk/bayesroute@<version> --json | jq .dist.attestations. The attestation links
the tarball you installed to the GitHub Actions workflow that built it from a specific source commit.
Can I plug in my own store backend?
Yes. Implement the PosteriorStore interface with get, set,
keys, and snapshot, and pass it as store in the config. Back it with
SQLite, Postgres, Redis, or anything else; the file store is the zero-dependency reference.
What is the policy on breaking changes?
Strict SemVer 2.0.0, starting from 1.0.0. The binding stability surface is documented in SPEC.md section
5. Major bumps require a deprecation cycle; security fixes follow the disclosure flow in SECURITY.md.