# Configure BYOK escalation levels: L0, L1, and L2

Reelier's escalation ladder is a spend ceiling you set per run. `--max-level 0` — the default — replays your skill's recorded tool calls deterministically and never constructs a model, so the deterministic core costs 0 tokens. `--max-level 1` and `--max-level 2` raise the ceiling: they let a model step in, but only on a step that actually diverges, and only with credentials you supply. That is what BYOK means here — bring your own key, spend on your own terms.

This guide configures all three levels: what each one does, the exact moment a model is (and is not) called, and how to point Reelier at your API key or any OpenAI-compatible endpoint. Every command is real and every receipt below is verbatim from a run on 2026-07-22 with reelier v0.14.0.

Markdown twin of https://www.reelier.com/guides/byok-escalation-levels — a step-by-step Reelier how-to. Every command below is a real Reelier command and every output block is verbatim, never a mockup.

## Before you start

- Reelier installed — `npm i -g reelier` (or use `npx -y reelier@latest` in place of `reelier` in every command below).
- A compiled skill to run. The examples use `registry-latest.skill.md`, a read-only npm-registry lookup shipped in the repo; to compile one from your own agent history, see the from-session guide.
- No API key needed to start. Level 0 is the default and never calls a model, so the first run costs nothing and asks for nothing.

## 01 · Know what each level does

Level 0 is deterministic replay: Reelier re-issues the recorded tool calls and checks each recorded assertion. No model is constructed, so it costs 0 tokens, and a diverged step simply fails — nothing is re-reasoned. This is the floor, and the default.

Level 1 adds a cheap re-read. When a step diverges, Reelier hands the model the SAME observation the tool call already produced — it re-runs nothing — and asks whether the step's asserts/binds are merely stale (a field that moved from `json.id` to `json.data.id` after an API change). If so, it patches them in the `SKILL.md` and moves on. Default model: `claude-haiku-4-5-20251001`.

Level 2 adds one re-execution. If Level 1 cannot heal from the old observation, Reelier may re-derive the step's `args` and run the tool call exactly once against a fresh result. It is only ever offered for `read` or idempotent-write steps — a destructive step is never auto-re-run (that is a human editing the skill by hand). Default model: `claude-sonnet-5`.

## 02 · Run at Level 0 — the default, zero tokens

With no flag, `run` replays at Level 0. The receipt has no `LLM tokens` line at all because the model was never constructed — the 0 is structural, not rounded down. This is the deterministic core every higher level sits on top of.

```bash
reelier run registry-latest.skill.md
```

```
✓ Step 1 — Latest dist-tag from the registry [passed] 150ms

PASSED: 1/1 steps ok, 0 failed, 150ms total
```

## 03 · Set your BYOK credentials

Levels 1 and 2 need a key — but only at the moment a step actually diverges, so a clean run never asks for one. Reelier resolves credentials in order: explicit flags first, then environment variables, then defaults.

`REELIER_LLM_API_KEY` holds the key (or `ANTHROPIC_API_KEY` on the default `api.anthropic.com` base URL) — or pass `--llm-api-key`. `REELIER_LLM_BASE_URL` (default `https://api.anthropic.com`) aims the client elsewhere: point it at any OpenAI-compatible endpoint — OpenRouter, Ollama, Gemini's compat endpoint, Groq, vLLM — and Reelier switches to the chat-completions wire format automatically. `REELIER_LLM_MODEL` sets the Level-1 model; `REELIER_LLM_L2_MODEL` sets the Level-2 model.

You can also pass any of these inline on a single run, which overrides the environment for that run only:

```bash
reelier run registry-latest.skill.md --max-level 1 --llm-api-key "$REELIER_LLM_API_KEY"
```

## 04 · Level 1 — heal stale checks without re-executing

Raise the ceiling to 1 and nothing changes on a clean run; the difference appears only when a step drifts. When one does, Reelier re-reads the observation that tool call already returned and asks the cheap model whether the assertion is just stale. If it can rewrite the asserts/binds to describe that same observation, it patches the `SKILL.md` and the step passes — no tool call is re-executed at this level, so there are zero new side effects.

If you raise the level without a key and a step then diverges, Reelier stops rather than guess: `Missing LLM API key. Set REELIER_LLM_API_KEY (or ANTHROPIC_API_KEY when using the default api.anthropic.com base URL), or pass --llm-api-key. This is only needed when a step actually diverges and --max-level >= 1 triggers an escalation — BYOK spend is opt-in.` The ceiling is a permission, not a schedule.

```bash
reelier run registry-latest.skill.md --max-level 1
```

## 05 · Level 2 — re-derive and re-execute once

Level 2 is the same ladder with one more rung: when re-reading the old observation is not enough, the model may propose re-derived `args` and Reelier re-runs the tool call a single time against the fresh result, then checks the patched assertions. Use `--llm-l2-model` to point the heavier re-derivation at a stronger model than the Level-1 default.

Two guardrails are structural, not configurable. Level 2 is offered only for `read` and idempotent-write steps; a destructive step never auto-re-runs — Reelier records that as a job for a human. And escalation is a separate axis from write gates: `--max-level` sets the model ceiling, while `--allow-writes` / `--yes` decide whether recorded write steps re-fire at all. The safest thing to escalate is a read-only replay, which is the default.

```bash
reelier run registry-latest.skill.md --max-level 2 --llm-l2-model claude-sonnet-5
```

## 06 · Confirm the ceiling only spends on drift

Set the ceiling as high as you like — the model still runs only when a step diverges. Here the same read-only skill replays at `--max-level 2` with no key configured at all, and passes at 0 tokens because nothing drifted. Raising the ceiling did not cost anything.

```bash
reelier run registry-latest.skill.md --max-level 2
```

```
✓ Step 1 — Latest dist-tag from the registry [passed] 211ms

PASSED: 1/1 steps ok, 0 failed, 211ms total
```

## The receipt

```
Bench: registry-latest
  runs:        2
  pass rate:   100.0% (2/2)
  first run:   150ms (2026-07-22T10:40:28.231Z)
  latest run:  211ms (2026-07-22T10:40:36.798Z)
  steps:       passed=2 unchecked=0 skipped=0 failed=0 (across all runs)
  step levels: L0=2 L1=0 L2=0 (across all runs)
  escalation:  L1 attempted=0 healed=0  L2 attempted=0 healed=0 (a step that burned tokens and still failed shows here)
  LLM tokens:  0 in / 0 out (no cost math — tokens only)
  per-step failure counts: none
```

`reelier bench registry-latest` over the two runs above — the default Level-0 replay and the `--max-level 2` replay with no key set. `step levels: L0=2 L1=0 L2=0` and `LLM tokens: 0 in / 0 out` prove the ceiling stayed a ceiling: no step diverged, so no escalation ran and no tokens were spent. Produced on 2026-07-22 with `reelier` v0.14.0 in a scratch directory, replaying the repo's read-only `registry-latest.skill.md`.

## FAQ

**Does raising --max-level cost tokens on every run?**

No. The bench above ran the same skill at `--max-level 2` with no key configured and spent 0 tokens, because no step diverged. The model is called only on a step that actually drifts, and never on a clean run — raising the ceiling grants permission, it does not schedule spend.

**What is the difference between Level 1 and Level 2?**

Level 1 re-reads the SAME observation the tool call already produced and patches stale asserts/binds — zero re-execution, zero new side effects. Level 2 may re-derive the step's `args` and re-run the tool call exactly once against a fresh result. Level 2 is offered only for `read` or idempotent-write steps; a destructive step is never auto-re-run.

**Can I use a non-Anthropic model?**

Yes. The Level-1 default is `claude-haiku-4-5-20251001` and the Level-2 default is `claude-sonnet-5`, but set `REELIER_LLM_BASE_URL` (or `--llm-base-url`) to any OpenAI-compatible endpoint — OpenRouter, Ollama, Gemini's compat endpoint, Groq, vLLM — and choose the models with `--llm-model` / `--llm-l2-model`. The Anthropic base URL uses the native Messages API; everything else uses chat-completions.

**Is --max-level the same as --allow-writes?**

No — they are separate axes. `--max-level` sets how high a model may escalate; `--allow-writes` / `--yes` decide whether recorded write steps re-fire during replay (idempotent-write needs `--allow-writes`, destructive needs `--yes`). A run can be at Level 2 and still be read-only.

## Related

- [Deterministic replay — the Level-0 core, defined](https://www.reelier.com/learn/deterministic-replay)
- [Assertion grammar — the assert/bind lines Level 1 and Level 2 patch](https://www.reelier.com/learn/assertion-grammar)
- [Guide: compile a skill from an agent session to run at any level](https://www.reelier.com/guides/from-session-compile)
- [Guide: replay an agent workflow at Level 0 for zero tokens](https://www.reelier.com/guides/replay-agent-workflow-zero-tokens)
- [Agent memory vs replay — why the deterministic core needs no model](https://www.reelier.com/learn/agent-memory-vs-replay)

## Sources

- [seldonframe/reelier — the open-source (AGPL-3.0) CLI every command here runs](https://github.com/seldonframe/reelier)
- [Anthropic Messages API — the native wire format used on the default base URL](https://docs.anthropic.com/en/api/messages)
- [OpenAI Chat Completions — the compatible format used for every other endpoint](https://platform.openai.com/docs/api-reference/chat)

Other guides: [How to snapshot-test a Claude Code workflow](https://www.reelier.com/guides/snapshot-test-claude-code-workflows) · [How to record MCP tool calls with a wrap proxy](https://www.reelier.com/guides/record-mcp-tool-calls) · [How to replay an agent workflow at 0 LLM tokens](https://www.reelier.com/guides/replay-agent-workflow-zero-tokens) · [How to gate CI on agent drift](https://www.reelier.com/guides/ci-gate-for-agent-drift) · [Replay an agent skill on every PR with the Reelier GitHub Action](https://www.reelier.com/guides/github-action-agent-replay) · [Test your MCP server for regressions by replaying a golden run](https://www.reelier.com/guides/test-mcp-servers) · [Run a deterministic cron agent by scheduling a recorded replay](https://www.reelier.com/guides/deterministic-cron-agents) · [Build an agent audit trail from Reelier run receipts](https://www.reelier.com/guides/agent-audit-trail-receipts) · [Compile a skill from an existing session with reelier from-session](https://www.reelier.com/guides/from-session-compile) · [Diff two agent runs with reelier diff (exit 1 on drift)](https://www.reelier.com/guides/diff-two-agent-runs) · [Convert an LLM agent skill into a deterministic, assertion-checked skill](https://www.reelier.com/guides/convert-agent-skill-deterministic)
