How it fits
One content source (this file) renders in the console /setup page and on modelrig.dev — edit here, surfaces follow.
ModelRig sits between your code and the model providers. Your repo declares routes — small YAML files naming a prompt, an output schema, and the models allowed to serve the task. Your app calls rig.run("task.name"); ModelRig renders the prompt, picks a model from the route's candidates using verified registry facts, enforces the schema, retries typed failures within per-class budgets, and hard-stops spending at your envelope caps. How the candidate ladder actually runs — ordering, validate → repair → fall-through, and what is not built — is on Routing & reliability.
Every call writes one telemetry row to a local SQLite file first — the run never blocks on the cloud. An async exporter mirrors rows to the console you are reading. Provider keys are the one thing that deliberately never leaves your machine; the exporter has no code path to them.
Routing is half of it. ModelRig also records the execution graph of your workstream — the run, its steps, and the artifacts each step produced — versioned, hashed, and lineaged, into an inspectable store you can open: when someone asks why the pipeline did that, you pull up the run and show them. This is the standard path, not an add-on: every pipeline execution is a run — wrap it in run.start / run.scope, name a step per model-call family (name it with stepKey), save the work products, and inside that context the SDK auto-stamps run_id for you, so the run appears on /runs and /projects with no hand-written id (the SDK auto-stamps the step key inside a run context too; the stepKey you pass names the step, and always wins). The namespace is on by default once a control plane is configured (a ModelRig API key, or the self-host Supabase pair); a pure local-only rig stays off; to opt out of capture, set posture off in account settings (the console or the set_org_settings MCP tool) — the account posture is the control, not a deployment env var. Artifact metadata and lineage ride the same exporter; artifact content is a separate axis — the recommended, encouraged path, since content custody is what turns your captured prompts, outputs and evidence into analysis, but it stays consent-gated: the signup default is managed — every new org is created with content custody on, having accepted the published terms at signup — and opting out is one account setting (in the console or the set_org_settings MCP tool, set posture off or metadata, or use a zero_retention route). A failing artifact can be promoted to a regression case and replayed as a bake-off — see → prove → save is the loop, and the store is where seeing happens.
What is retained beyond that is your choice, per route, and there are two lanes.
Pure router (capture off). Nothing retained. Real, supported, selectable, and the honest answer for a ZDR-strict or data-residency-bound workload.
Optimization on (recommended). Your traffic is what makes the routing smarter and the bill smaller. What is kept: per-inference telemetry rows, and bounded review samples for the bake-offs you create. Where: your organization, row-scoped by the database, not by our application code. How you leave: see it all in the console, delete it, export it, take your routes and go — they were always YAML in your git. What you get back: community priors on your very first bake-off and RigIndex-grade evidence on your own routes — at the same flat 2% either way; the corpus earns its place by being useful, not by being a discount.
Captures power bake-offs: replay your own recent traffic through route variants — a cheaper model, a different prompt — and get the effective cost of conformance for each, with confidence intervals. A winning variant is a proposal for you to apply in your YAML; nothing swaps models automatically.
The registry feeds routing from the side: declared claims, probed measurements, and observed traffic per model, with disagreements shown. A probed fact beats a declared claim — a model that declares schema support but failed our probes is not eligible to serve a schema route natively.
The loop, end to end: routes in your repo → rig.run in your app → local telemetry (+ captures on the routes where you turn Optimization on) → synced console → bake-offs prove cheaper variants → you edit the YAML. The console shows the truth; actions live in your code.
More capabilities
The five-step get-started is the front door; these are the shipped surfaces it does not stop to teach. One line each, with the reference doc:
- Runs & projects — the run → step → artifact graph on
/runs, grouped by tag on/projects. The standard path above; full API in instrumentation. - Tenants & statements — a
subjecttag or a project-scoped key becomes a per-customer tenant with a derived statement (attempted, verified, billable, true cost), on/tenants. See Tenants & statements. - Published receipts — publish a signed, login-free receipt of a bake-off or route at
/r/<id>— counts, scores and hashes only, verifiable at/v1/verify/<id>; names aliased, content never leaves. See Published receipts. - Analytics query API — a self-describing, read-only query surface over your own telemetry (
GET /v1/analytics/meta,POST /v1/analytics/query): an allowlisted SELECT grammar that returns metadata only, never content. See Optimization loop. - Provenance & trust — provenance-first prompt assembly keeps third-party content out of the most-trusted slot; annotate a variable
x-trust: untrustedto spotlight it. See Provenance & trust. - Bake-offs — pairwise, disagreement & regret — replay your own traffic, judge candidates pairwise with disagreement shown, and propose the lowest-regret arm under a quality gate (near-optimal, not merely cheapest). See Bake-offs & replay and the Grade protocol.
- Live routing (call-config) — change which model serves a route live, no redeploy: pin a model, or run a weighted A/B (the chosen arm records on
meta.arm). The SDK reads the route's config just-before-call (fail-open; no override ⇒ byte-identical) and overlays it onto a bundle you serve throughrig.runBundle. Set it in the console's call-config card, or have your coding agent set it over MCP (set_call_config, theroute-configscope — explicit and reversible). See Change your route's model live and The MCP oracle.
New claims are held to the same bar as the five steps: content custody stays early access (metadata and hashes), and pricing stays the launch-terms sentence.