Firstpass v0.3.0
DocsGuaranteeBenchmarksCLIGitHub
◆ verified cascade routing · proof over prediction

Cheap until proven otherwise.

The cheapest model takes the first pass. It clears your gate — proven on the real output, not guessed from the prompt — or it escalates. Wrong answers capped at ≤10% at 95% confidence, and the router tunes itself as your traffic drifts.

No API keys, nothing installed — uvx firstpass demo prints a signed receipt.

cheapest-first · gated ≤10% served-fail @ 95% every provider · BYOK, zero markup v0.3.0 · open source
firstpass · enforce · POST /v1/messages one decision
RUNG 2 anthropic/opus never reached RUNG 1 anthropic/sonnet SERVED RUNG 0 anthropic/haiku GATE FAILED missing "total" escalate ×1

WHAT IT COST

spent $0.0092
always frontier $0.0345

73% cheaperat proven quality — not predicted

sha256:5c02…a91f chain ok every decision seals a receipt an auditor can re-derive

the mechanism

Four moves. No black box.

Predictive routers guess a model from the prompt and hope. Firstpass runs the cheap model, checks what actually came back, and only spends more when the check fails — then learns from the outcome.

The four moves: Route opens on the cheapest model, Prove gates the real output, Escalate goes one rung up only on failure, and Learn feeds outcomes back so the serve threshold self-tunes. 1 Route open the cheapest rung in the ladder 2 Prove gate the real output, not the prompt 3 Escalate one rung on fail, budget-capped 4 Learn outcomes tune the serve threshold
01 — ROUTE

Open the cheapest rung

Every request starts on the least expensive model in your ladder. No per-prompt prediction — the cheap model simply takes the first pass.

02 — PROVE

Gate the real output

A gate checks the actual response: JSON validity, a schema, your test suite, an LLM judge, or self-consistency. Proof, not a guess.

03 — ESCALATE

One rung, only on fail

Fail the gate and it climbs exactly one rung — budget-capped, with cross-provider failover on transport or 5xx errors.

04 — LEARN

Tune the threshold

Deferred outcomes feed back through /v1/feedback. Adaptive conformal moves the serve threshold as your traffic drifts.

why it's different

Prediction guesses. Firstpass proves.

predictive routers

Guess the model from the prompt

  • A classifier picks a model before any output exists — right or wrong, you can't tell until it's too late.
  • No artifact of why a request went where it did. "Trust the model."
  • Drift silently degrades the classifier; nothing recalibrates.
  • No bound on how often a wrong answer reaches your user.
firstpass

Verify the output, then serve it

  • The gate reads the real response. It passes on proof or it escalates.
  • Every decision is a tamper-evident, hash-chained receipt an auditor can re-verify.
  • Outcomes recalibrate the serve threshold live under drift.
  • A distribution-free served-failure bound — earned on real tasks, not asserted.

the guarantee

A number you can put in a contract.

On 974 real MBPP coding tasks with real test gates, Firstpass held served-failure under a 10% distribution-free target at 95% confidence — while serving 82% of requests from the cheap tier. The bound is earned from the run, not assumed.

≤10%
served-failure target, distribution-free at 95% confidence
7.7%
realized served-failure at the calibrated threshold
5.5%
calibrated risk (conformal, continuous score)
82%
of requests served from the cheapest tier
On 974 MBPP tasks: the realized served-failure rate is 7.7%, below the 10% distribution-free target line at 95% confidence, with calibrated risk 5.5%. Separately, 82% of requests are served from the cheap tier. Served-failure vs the ≤10% target 0%2%4%6%8%10% 10% target (95% conf.) 5.5% calibrated risk 7.7% realized served-fail Where requests are served 82% cheap tier 18% 82% of requests clear the gate on the cheapest rung — no escalation, no expensive call. The remaining 18% escalate on proof of need. tasks 974 real test gates live
MBPP · 974 tasks · base (test) gate · α=0.10, δ=0.05. Source artifact: docs/benchmarks/mbpp-live-base.txt.
The self-tuning loop: the router serves the first pass, the true outcome is reported to /v1/feedback, adaptive conformal nudges the serve threshold up or down to hold the target, and the next request serves against the updated threshold — a closed loop that tracks drift with no recalibration run. THE SELF-TUNING LOOP Serve first pass above threshold Outcome known POST /v1/feedback Adaptive conformal Gibbs–Candès nudge Serve threshold ↑ / ↓ tracks drift held live at ≤10%
No recalibration run, no downtime — each reported outcome moves the threshold to keep realized served-failure under target as your traffic drifts.

How the bound is computed →

the gate is the point

Bring your own definition of "good."

A gate is any check on the real output. Firstpass ships several and lets you plug in your own — your tests, your linter, your judge.

Five gate kinds — inline checks, JSON-Schema, your subprocess, an LLM judge, and k-sample self-consistency — each read the actual output and converge on one verdict. The verdict serves on proof or escalates one rung on failure. GATE KINDS ONE VERDICT · ON THE REAL OUTPUT OUTCOME inlinenon-empty · json-valid schemaJSON-Schema subset subprocessyour tests · stdin LLM judgemaker ≠ checker self-consistencyk-sample agree Gate verdict proof, not a guess serve passes → first-pass answer escalate fails → up one rung
Any of the five kinds — or your own subprocess — produces the same thing: a verdict on the actual output. Pass serves it; fail escalates one rung. Prediction never overrides that verdict.

Built-in inline

non-empty, json-valid, and a JSON-Schema subset — zero config, running the moment you route.

Subprocess — bring your own

Any executable. The candidate arrives as JSON on stdin (never argv, injection-resistant); print a verdict. Your tests, your linter, your policy.

LLM judge

A native judge with anti-gaming built in: a model never grades its own output, and the candidate is fenced as untrusted data under a pinned prompt.

Self-consistency

Resample k times and score by agreement — semantic-entropy style, for tasks without a crisp oracle.

Fail-open or fail-closed

Per-gate on_abstain decides what an inconclusive check does. Flaky gates auto-disable on a rolling error budget.

Priced on the receipt

Every gate's cost is written onto the receipt, so verification overhead is visible, not hidden.

All five gate kinds →

system architecture

One hop between your agent and every provider.

A drop-in proxy that speaks both wire dialects inbound — Anthropic /v1/messages and OpenAI /v1/chat/completions, both live-verified. Your key passes straight through: BYOK, zero markup, redacted from every log.

Firstpass sits as one hop between your agent and your providers. An agent speaking either the Anthropic or OpenAI wire dialect connects to the proxy, which routes to the cheapest rung, gates the real output, and escalates or fails over on need. Every decision is written off the hot path to a hash-chained trace store, and a feedback API folds downstream outcomes back in. The proxy calls out to Anthropic, any OpenAI-compatible host, or Gemini, with AWS Bedrock and Google Vertex as additional auth paths. AGENTS FIRSTPASS PROXY PROVIDERS Your agent Anthropic OR OpenAI wire base_url Router cheapest first Gate engine test the output Escalate + failover Trace store SQLite · hash-chain Feedback API /v1/feedback Anthropic OpenAI-compatible Gemini + Groq · Together · DeepSeek · Ollama · vLLM + AWS Bedrock (SigV4) · Google Vertex (OAuth) call · BYOK output → re-gate
One hop, both inbound dialects. Whatever a provider returns is re-checked by the gate before it is served; every decision lands in the hash-chained trace store off the request path.

tamper-evident by construction

Every decision leaves a receipt.

Each decision is a SHA-256 hash-chained, append-only record. Export the sealed log and an external auditor re-derives the chain from genesis — no proxy, no database. Tamper or reorder and it breaks at that index and exits non-zero.

Hash chain: each receipt stores the SHA-256 of the previous record in prev_hash, so records link genesis to head. Tampering with one block changes its hash, so the next block's prev_hash no longer matches and verification fails at that index. receipt #0 · genesis prev_hash 000000… hash a91f… receipt #1 prev_hash a91f… hash 5c02… receipt #2 · TAMPERED prev_hash 5c02… hash e7d4… receipt #3 prev_hash e7d4… hash 1b88… Edit receipt #2 → its hash changes → receipt #3's prev_hash (e7d4…) no longer matches. firstpass verify re-derives the chain from genesis and exits non-zero at index 3. Records #0–#1 still verify. The break is localized and provable.
receipt · trace.json
{
  "trace_id": "0192f3a1-7c4e-7abc", "prev_hash": "9f2c…a1b7",   // chains to the prior decision — tamper-evident
  "attempts": [
    { "rung": 0, "model": "…/haiku-4-5", "gate": "fail", "cost": 0.0007 },  // cheap first — the gate caught it
    { "rung": 1, "model": "…/sonnet-5", "gate": "pass", "cost": 0.0121 }   // escalated, proven, served
  ],
  "final": { "served_rung": 1, "savings_usd": 0.0502 }   // vs always-top-tier
}

firstpass export + verify

Export the sealed log as JSONL; anyone re-derives the hash chain from genesis on their own machine. A single altered or reordered receipt breaks the chain at its index and exits non-zero — the EU-AI-Act-style logging story, built in.

Durable, never-drop

FIRSTPASS_RECEIPTS=durable spills receipts to disk under backpressure and drains them on boot with the chain verified valid — no served decision is ever silently lost.

Receipts & audit →

the cost / quality dial

One dial: how hard should this one try?

Cost, balanced, quality, latency, or max — a mode is a posture the router honors, chosen per task, per turn, even per request with one x-firstpass-mode header. Same guarantee underneath; the mode only moves where on the cost/quality frontier you sit.

cost

Open on the cheapest rung and stay there while the gate clears. Escalate only on hard proof of need — most requests never leave the cheap tier.

balanced · default

Let the learned start-rung open a step higher when your own receipts say the cheap model usually fails this kind of task.

quality

Raise the serve threshold and prefer stronger rungs. Fewer marginal passes served; the guarantee target tightens.

latency

Fire speculative escalation in the marginal zone, so the next rung is already in flight if the gate fails — parallel tokens buy tail latency.

max

Open at the top of the ladder, for the rare request where the answer has to be right the first time and cost is no object.

The five modes are points on a single cost-versus-quality frontier. cost sits at the cheap floor, balanced (the default) a step up, quality higher, and max at the top. The dial only moves where you sit on the curve — it does not change the engine. latency is orthogonal: the same frontier point, with speculative escalation buying tail latency. ONE DIAL · WHERE ON THE FRONTIER YOU SIT quality · tighter bound → cost per served request → latency speculative escalate — same point, lower tail cost quality max balanced · default
One dial, one curve. Every mode is a point on the same cost/quality frontier — moving it changes where you sit, not how the engine works. latency is the exception: same frontier point, speculation trades parallel tokens for tail latency.
How modes are builtModes ship first as presets over the existing escalation knobs — a resolver that only overrides the knobs it has an opinion on. The richer constraint form, where you hand the router an (α, latency, $) budget and it solves for the knobs, lands behind a validation gate: worth exposing only once it measurably moves the frontier on real traffic. How modes compose →

the research

Verify proportional to doubt.

Today Firstpass proves before it serves. The next question is how much proof each answer needs — an easy request three signals already agree on shouldn't pay for a full test run; a genuinely uncertain one should. That's elastic verification: spend verification budget as a function of measured doubt, with a conformal guarantee over the verify-or-skip decision itself, so cutting a check is never a silent risk.

Value-of-information gating

Estimate what a verification step is worth before running it — skip the checks that can't change the decision, spend on the ones that can.

Per-query difficulty

Predict how hard a request will be for the cheap rung, from the prompt and cheap probe signals — to choose where to start and how much to check.

Session-level routing

Route over a whole trajectory, not one turn — carrying difficulty and outcome context across an agent's session.

A cheap k-sample probe sorts all traffic into three regimes. On the MBPP probe study: 12% fail every sample and escalate immediately (0% would have been oracle-correct — a doomed cheap attempt skipped); 23% are mixed and pay for the full gate, where verification's information is worth its cost; 65% pass every sample and are served without the expensive gate at 99% oracle-safety. The skip carries the same distribution-free served-failure bound as a verified serve — held-out 7.5%, under the 10% target. Cheap k-sample probe 100% of traffic · near-free visible gate 12%0 of k pass visible → escalate now, skip the doomed cheap attempt 0% oracle-correct 23%mixed — some pass → run the full gate, where its info pays verify here only 65%all k pass visible → serve, skip the expensive gate 99% oracle-safe Conformal guarantee over the verify / skip decision un-verified serves keep the ≤10% distribution-free bound — held-out served-failure 7.5% ✓
The validated three-regime rule (probe study, MBPP, k=5). Verification cost concentrates on the ambiguous 23%; the confident 77% is decided by the cheap probe alone. Source: docs/benchmarks/probe-study-mbpp.txt · elastic-validation.txt.
How we'll know it's realEach ships only if a pre-registered go/no-go study beats verify-everything on cost at an equal-or-better served-failure bound — the same rule that promoted the start-rung bandit from idea to code. The first probe study already validated the signal (a corrected pass-count regime, not entropy). Read the study →

agent-first

Onboards in one step. Built for agents to run themselves.

One env var in, one env var out. No SDK, no rewrite — the proxy speaks the wire format your agent already uses, and exposes itself for machines to discover.

One command onboards you

firstpass onboard --apply detects your shell and agents, starts the proxy in observe mode (zero config, zero risk), routes your agent, and verifies itself. Idempotent, dry-run by default; firstpass offboard undoes all of it.

Discoverable at runtime

GET /v1/capabilities is a machine-readable descriptor; llms.txt and AGENTS.md ship machine-readable setup — an agent can wire and unwire itself with no human in the loop.

MCP server built in

firstpass mcp exposes traces, savings, evals, policy rehearsal, route explanation, and receipt verification as tools — so the agent reads its own decisions and rehearses changes before enforcing them.

get started

See the whole loop in ~10 seconds.

No API keys — the demo stands up a mock upstream and drives one real decision, escalation and all. It builds from source, so it needs a Rust toolchain; installing the proxy below doesn't.

bash · run the demo
uvx firstpass demo   # no keys, no clone, no toolchain — watch the receipt print

Or install the proxy

prompt · paste into Claude Code, Codex, Cursor…
Read https://dshakes.github.io/firstpass/llms.txt, then install Firstpass and
route this project through it. Run `firstpass onboard` first and show me the
plan before you apply anything. Keep it in observe mode; don't touch my keys.
bash
uvx firstpass            # run without installing
pip install firstpass    # or install it
bash
brew install dshakes/tap/firstpass-proxy
bash
curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/dshakes/firstpass/releases/latest/download/firstpass-proxy-installer.sh | sh
bash
docker run -p 8080:8080 -e FIRSTPASS_BIND=0.0.0.0:8080 \
  ghcr.io/dshakes/firstpass:latest
bash
cargo install --git https://github.com/dshakes/firstpass firstpass-proxy

The first tab is the one you hand to your agent — every other tab is a live install channel that republishes on each release: pip · uvx · Homebrew · Docker · curl | sh · prebuilt binaries. (Cargo builds from source and needs a Rust toolchain.) Then point your agent at it: run firstpass-proxy, set ANTHROPIC_BASE_URL=http://127.0.0.1:8080, and unset it to offboard — one env var, same wire format your agent already speaks.

status

Shipped in the open — honestly labeled.

GA is a checklist we publish, not an adjective. Here's what runs today and what's still ahead.

✓ Shipped & verified
  • Both wire dialects. Anthropic /v1/messages + OpenAI /v1/chat/completions, both live-verified end-to-end.
  • Enforce through tools & streaming. Structured (tool/image) enforce is default-on with verbatim per-rung carry; SSE opens instantly and streams the gated result.
  • The earned guarantee. ≤10%@95% distribution-free bound on 974 real MBPP tasks (committed artifact), Learn-then-Test calibration, live adaptive threshold.
  • Learned start-rung. UCB1 or discounted Thompson with logged propensities and a speculative-deferral band — default-off, honest policy stamp on every receipt.
  • Selectable modes. cost / balanced / quality / latency / max presets, per route or per request via x-firstpass-mode.
  • Five gate kinds. inline · schema · subprocess · LLM-judge (maker ≠ checker) · k-sample self-consistency, each with an error budget and gate cost priced onto the receipt.
  • Receipts. hash-chained; export + verify re-derive with no proxy or DB; durable never-drop mode.
  • Policy rehearsal. firstpass ope replays your logs with IPS / SNIPS / DR and bootstrap CIs before you enforce.
  • Packaged everywhere. pip · uvx · Homebrew · Docker · curl | sh · binaries, auto-published each release.

Full detail: the phased roadmap and the GA handoff — every gate stated, every remaining item enumerated.

Stop guessing which model. Start proving it.

Open source, pre-GA, and honest about what's shipped. Read the deep docs or read the code.