Skip to content

Command-line interface

The recension CLI is a thin wrapper over the library: run an optimization from a config file, show a run record, and diff two artifact versions. Install the package and the recension command is on your path.

recension run

recension run --config run.yaml

Executes the optimization described by the config and writes the audit record to disk. A fully commented config and a tiny dataset live in examples/cli/, runnable as-is from the repo root:

recension run --config examples/cli/run.yaml
recension show run_record.json

Note

The offline mock backend is deterministic but not task-aware, so a config-driven mock run demonstrates the pipeline and the record format rather than a real improvement. The worked examples use scripted mocks to show runs that genuinely accept edits. For real optimization through the CLI, use backend: anthropic (needs the [anthropic] extra and ANTHROPIC_API_KEY in the environment).

Config schema

The config is a YAML mapping. Bad values fail loudly with a config error and a non-zero exit.

Key Required Notes
artifact.text / artifact.path one of Inline text, or a file to load. artifact.name is optional.
evalset.path yes JSONL file; each record needs id, input, split (train/validation/optional test), plus expected (for exact_match/f1) or rubric (for llm_judge).
objective.name yes exact_match (opt. case_sensitive), f1, or llm_judge (opt. rubric).
model.backend yes mock (opt. seed), anthropic (opt. model), openai (opt. model, base_url), gemini (opt. model), or ollama (opt. model, host). API keys come from the environment only, never this file.
budget no candidates_per_round (4), rounds (3), diagnosis_depth (1), max_model_calls (unlimited).
seed no Makes the whole run reproducible against the mock.
min_improvement no Margin a candidate must beat the incumbent by (default 1e-6).
accept_significant no Require the validation gain to be statistically significant (a bootstrap CI excluding 0), not just above the margin (default false).
alpha no Significance level for the bootstrap CI (default 0.05 = 95%).
bootstrap_resamples no Resamples for the significance bootstrap (default 2000).
overfit_gap no Flag validation_overfit when the final validation score beats the locked test split by more than this (default 0.1).
slice_by no An Example metadata key; reports per-subgroup baseline-vs-final scores so a run that improves overall but regresses a segment is visible.
slice_tolerance no A slice is announced as regressed when it drops by more than this (default 0.0).
guards no A list of non-regression guard objectives, e.g. - {name: max_length, max_chars: 200}. A candidate that improves the primary metric but regresses a guard is rejected.
guard_tolerance no Allowed drop on a guard before it counts as a regression (default 0.0).
strict_leakage no Raise on a leakage-flagged winner instead of accepting it (default false).
output no Where to write the run record (default run_record.json).
write_artifact no Also write the final artifact text to this path.

A test split (records with split: "test") is scored exactly once at the end, giving an unbiased estimate that the repeated selection on validation cannot give. See Concepts.

If the run hits budget.max_model_calls or a leakage flag in strict mode, the CLI still writes the partial record and exits with status 2, so the audit trail survives the failure.

Running against a real provider

The example config uses the offline mock backend. To run against a real model, change the model section to one of the hosted providers (install its extra and set the key in your environment) or a local Ollama server. Everything else in the config stays the same.

# OpenAI (pip install "recension[openai]"; OPENAI_API_KEY in the environment)
model:
  backend: openai
  model: gpt-4o-mini
  # base_url: https://my-openai-compatible-server/v1   # optional: vLLM, LM Studio, OpenRouter, ...

# Google Gemini (pip install "recension[gemini]"; GEMINI_API_KEY in the environment)
model:
  backend: gemini
  model: gemini-2.0-flash

# Ollama local models (no extra; start the server and `ollama pull llama3.2` first)
model:
  backend: ollama
  model: llama3.2
  # host: http://localhost:11434

Keys are read from the environment only, never from the config file. Note that deterministic, reproducible runs are a guarantee of the mock backend alone; hosted APIs treat the seed as a best-effort hint or ignore it.

recension show

recension show run_record.json

Prints a human-readable summary of a run record: the baseline, each round's diagnosis, every candidate with its score and any leakage flags, the accepted version with its diff, and the final score progression.

recension diff

recension diff run_record.json <version-a> <version-b>

Prints the unified diff between two artifact versions stored in the record (the version ids appear in recension show). Useful for reviewing exactly what an accepted edit changed.

recension check

A prompt regression test for CI. It scores the current artifact (from the config) and exits non-zero if it dropped below a baseline, so a prompt change that regresses your eval set fails the build the same way a failing unit test would.

recension check --config run.yaml --baseline run_record.json   # baseline = a prior record's score
recension check --config run.yaml --baseline 0.82 --split test # or a literal score, on the test split
Flag Notes
--config The same config run uses (artifact, evalset, objective, model).
--baseline A prior record JSON (uses its final_score, or final_test_score with --split test) or a literal number.
--split validation (default) or test.
--tolerance Allowed drop below the baseline before failing (default 0.0).

Exit codes: 0 no regression, 1 regressed (or a config error). Wire it into a workflow to gate merges on "the prompt did not get worse":

# .github/workflows/prompt-check.yml
name: Prompt check
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
        with:
          python-version: "3.12"
      - run: pip install recension
      - run: recension check --config run.yaml --baseline baseline_record.json --split test

recension verify

Checks a run record's integrity and exits non-zero if it was tampered with.

recension verify run_record.json

Because artifact version ids are content-addressed, editing a version's text or id after the fact is detected with no external reference. recension show prints the same integrity line. For full-record tamper-evidence (any field), records can be HMAC-signed: with RECENSION_SIGNING_KEY set in the environment, pass --signature <hex> to also check the signature. Exit codes: 0 verified, 2 integrity failure.

recension report

Renders a run record into a single standalone HTML page (inline CSS, no assets, no network) that you can open, share, or attach to a change request.

recension report run_record.json -o report.html

The page shows the baseline and final scores, the locked test estimate and any overfit flag, every round's diagnosis and candidates (with significance, guard, and leakage detail), the accepted diff, the per-slice breakdown, the token ledger, and the record's integrity status.