RUNBOOKS

Routing policy as executable code.

This is the whole differentiator, and it fits on one screen. A runbook is a file. It is reviewed like a file, versioned like a file, deployed like a file, and executed — on every request, in the router process, in about 180 microseconds.

Hover any highlighted key to see what that clause is responsible for.

runbooks/default.ymlrunbook/v3
classifyScores the request across four dimensions before any model is contacted. Heuristic, deterministic, and cheap enough to run on every request.
tierMaps a score band to a set of interchangeable targets. Targets inside a tier are load-balanced by health and latency, not by preference.
escalate_afterHow many verified failures a tier gets before the request climbs. Lower it for customer-facing work; raise it for bulk transforms.
fallbackWhere traffic goes when a provider is unreachable or a tier is exhausted. These paths are kept warm, so failover is a routing decision, not a recovery project.
budgetA spending guard evaluated against the period to date. A soft guard warns; a brake pins every eligible request to the cheapest tier until the period rolls.
PHILOSOPHY

A dropdown is a decision you can't diff.

Every routing product eventually offers a settings page: a model picker, a slider, a checkbox called "use cheaper model when possible". It is a reasonable thing to build and a terrible thing to operate. Someone changes a value on a Tuesday. Spend moves fourteen percent. Three weeks later nobody can say who changed it, what it was before, or what the change was supposed to achieve.

A runbook removes the ambiguity by removing the dropdown. The policy is a file in your repository with your review rules on it. Changing how traffic routes means opening a pull request, which means someone approves it, which means there is a record with a name and a date and a reason attached to it — the same standard you already hold for a database migration or a firewall rule.

This is not a workflow preference. It is the difference between a system you can operate and a system you can only apologise for. Every decision leaves a trace is the second principle of the house, and it starts with the policy that made the decision.

COOKBOOK

Six patterns that cover most of what people ask for.

Copy one, rename it, change the numbers. Every pattern below is a complete, valid clause — not pseudocode.

Pattern 01

cost-floor

Never let a route resolve above a named tier, whatever the classifier thinks. The bluntest instrument in the box, and the one people reach for first.

bulk.tagging:
  match: "kind == classification"
  tier: small
  max_tier: small     # hard ceiling
  escalate_after: 3
  on_exhausted: return_partial

Pattern 02

latency-ceiling

Some routes are attached to a human waiting for a screen to paint. Give them a deadline and let the router pick whatever meets it.

search.suggest:
  match: "route == search.suggest"
  deadline_ms: 300
  tier: auto
  on_deadline: return_best_effort
  fallback: [small-b, small-c]

Pattern 03

provider-pin

Data-residency, a signed agreement, or a model that is simply better at one narrow thing. Pin the target and keep a same-jurisdiction fallback.

hr.records:
  match: "tags contains pii"
  pin: mid-b
  residency: eu-only
  fallback: [mid-c]  # same jurisdiction
  on_exhausted: fail_closed

Pattern 04

canary-tier

Send a slice of live traffic one tier down and compare verification pass rates. This is how a policy earns the right to get cheaper.

summarize.thread:
  tier: mid
  canary:
    tier: small
    share: 0.05
    promote_if: "pass_rate >= 0.98 over 7d"

Pattern 05

budget-brake

A spending guard the router enforces itself. Not an alert that fires after the money is gone — a clause that changes routing while the period is still open.

budget:
  period: month
  guard: soft
  warn_at: 0.80
  brake_at: 1.00
  on_brake: pin_tier(small)

Pattern 06

human-gate

The top rung of the ladder is a person. Make that explicit, give it a queue, and stop pretending a model will eventually get it right on attempt nine.

review.contract:
  tier: frontier
  escalate_after: 1
  on_exhausted: human-review
  queue: legal-desk
  sla_minutes: 240
VERSIONING & AUDIT

A routing change looks like every other change you make.

Runbooks are validated on push, dry-run against a replay of yesterday's traffic, and deployed to every router in the fleet as one atomic version bump. Rolling back is checking out the previous version.

runbooks/reporting-pipeline.ymlv6 → v7
@@ -12,9 +12,14 @@ tier mapping
   classify:
     evaluator: heuristic-v2
-  tier: { small: { when: "score < 0.24" } }
+  tier: { small: { when: "score < 0.31" } }
+  guards:
+    - when: "risk > 0.60"
+      floor_tier: mid
   escalate_after: 2
-  fallback: [small-c]
+  fallback: [small-c, mid-a]
   budget:
     guard: soft
✓ approved reviewer: ops-oncall dry-run: 1.2M replayed requests · tier drift +4.1% to SMALL deployed to 6 routers in 84s
validate
Schema and expression check on push. A malformed guard expression fails the build, not the request.
dry-run
The candidate policy is replayed against a window of real decisions. The output is a tier-drift report: what would have routed differently, and by how much.
version bump
Runbooks are immutable once deployed. reporting-pipeline@7 means exactly one file forever, and it is stamped on every decision made under it.
audit
Every decision records the runbook version, the matched route, the guards that fired and the escalations that followed. GET /v1/decisions/{id} returns the whole thing.
rollback
Deploy the previous version. There is no separate rollback mechanism because there is no separate deploy mechanism.
ESCALATION SEMANTICS

The state machine, in full.

Hover or focus a state to light the transitions that leave it. There are no hidden states: a request is in exactly one of these five at any moment, and every arrow is a clause you can change.

ATTEMPT VERIFY RETRY ESCALATE RETURN EXHAUST dispatch pass fail & attempts < escalate_after re-dispatch, same tier attempts == escalate_after climb one rung no rung left

ATTEMPT → VERIFY

A target is chosen and dispatched. The attempt is metered whether or not it succeeds — that is what makes the escalation ladder honest.

VERIFY → RETRY

Verification failure returns to the same tier, not the same target. A tier with three healthy targets gets three genuinely different attempts.

ESCALATE → EXHAUST

When the ladder runs out, the request does not loop and it does not silently return the last bad answer. It goes to on_exhausted, which is usually a human queue.

Start from a cookbook pattern.

The schema reference documents every key, every type and every default. Most first runbooks are under thirty lines.