// cli · offline
Offline mode & fixtures
no network, no keys, no cost
--offline swaps the live model client for a ReplayClient that answers from canned fixtures — no network, no API keys, no cost, fully deterministic. The demo scaffold uses it for the free first run, and it is the cheapest way to iterate on config plumbing, evaluators, and slices before spending money on live calls.
bash
evalshift run --offline --fixtures fixtures.jsonl
## Fixture format
Fixtures are JSONL — each line pairs a model with a prompt-substring matcher:
json
{"model": "gemini/gemini-2.5-flash",
"match": "User account_42 had 5 failed login attempts",
"kind": "tools",
"result": {"calls": [{"tool_name": "notify_security_team",
"arguments": {"severity": "high", "summary": "..."},
"sequence_index": 0}],
"final_text": null,
"input_tokens": 240, "output_tokens": 48,
"cost_usd": 0.0011, "latency_ms": 760}}Matching rules:
- +The canonical model id must match, and
matchmust be a substring of the rendered prompt — for multi-turn examples, of the last user message only. - +Exactly one fixture may match; zero or several is an error (an ambiguous match names the offending fixture line numbers).
## Recording fixtures
Record fixtures from a live run:
bash
python scripts/capture_fixtures.py <run-id> --suite golden.jsonl --out fixtures.jsonl
−
disable the cache in offline projects
Set
defaults.cache: false in offline projects so fixture edits aren’t shadowed by cached entries.## Showcase scenarios
The CLI repo’s examples/showcase/ ships four offline report-showcase scenarios (pass-clean, fail-dropped-tool, fail-argument-drift, mix); scripts/run_showcase.sh --offline --only pass-clean --open runs one end to end.