CLI Reference
pr-review reads a unified diff, runs one Vizzini mode against your LiteLLM
proxy, and prints the validated result.
git diff main...HEAD | pr-review --mode reviewpr-review --patch-file change.patch --mode describe --format jsongit diff main...HEAD | pr-review --mode risk # no model or proxy needed| Flag | Default | Meaning |
|---|---|---|
--patch-file |
- |
Unified diff to read. - reads stdin |
--mode |
review |
describe, review, improve, command, plan or risk (the deterministic score alone; needs no proxy or model) |
--issue |
Plan mode: JSON issue file {title, body, labels}. See Pre-Code Planning |
|
--tree |
Plan mode: repository paths, one per line (git ls-files > tree.txt) |
|
--okf-index |
Plan mode: the knowledge base’s root index.md |
|
--command |
Command mode: a slash command, e.g. "/explain a.go:44-45 why?" |
|
--thread |
Command mode: JSON file with the thread history, [{"author": "...", "body": "..."}] |
|
--litellm-url |
$VIZZINI_LITELLM_URL |
OpenAI-compatible API root, e.g. http://litellm:4000/v1 |
--model |
$VIZZINI_MODEL |
Model name as configured in LiteLLM |
--format |
markdown |
markdown (for humans and mrman) or json |
--max-chunk-tokens |
6000 |
Token budget per LLM request |
--concurrency |
4 |
Parallel LLM requests |
--timeout |
10m |
Overall deadline |
--skip-oversized |
false |
Review mode: skip hunks larger than the token budget |
--knowledge |
Review mode: OKF bundle directory (e.g. .okfw) whose relevant documents the model may cite. See Knowledge-Grounded Reviews |
|
--repo |
Review mode: the repository checkout at the change’s head (e.g. .). The definitions of symbols the change uses and the callers of symbols it changes are given to the model as read-only context. See Repository Context |
|
--run-id |
generated UUIDv7 | Attribution: this run’s ID. Every request carries it, as metadata and as the W3C trace ID (VIZZINI_RUN_ID). See Cost Attribution |
--pr |
— | Attribution: the pull request, e.g. ado:dev.azure.com/org/project/repo#42 (VIZZINI_PR) |
--iteration |
— | Attribution: the head commit reviewed (VIZZINI_ITERATION) |
--requester |
— | Attribution: the human the run is for, sent as the proxy’s end user (VIZZINI_REQUESTER) |
--agent |
pr-review |
Attribution: the tool asking (VIZZINI_AGENT) |
--risk-policy |
JSON risk policy (#RiskPolicy): path weights, threshold, sensitivity. See Risk & Auto-Approve |
|
--lint-json |
Review mode, repeatable: a linter report, either golangci-lint JSON or SARIF, whose diagnostics on changed lines the model should explain. See Lint-Aware Reviews | |
--fail-on |
Critical,Major |
Review mode: comma-separated severities that make pr-review exit 2, or none |
--all-findings |
off | Review mode: report every finding. By default the noise floor moves Trivial findings, and Minor Performance findings, to the JSON report’s filtered list. See The noise floor |
Environment
Section titled “Environment”| Variable | Used for |
|---|---|
VIZZINI_LITELLM_URL, VIZZINI_MODEL |
Defaults for the flags above |
VIZZINI_API_KEY |
Bearer token for the proxy (falls back to LITELLM_API_KEY). There is deliberately no flag, so the key never appears in ps |
TIKTOKEN_CACHE_DIR |
Pre-seeded tokenizer cache. See Running Offline |
| Mode | JSON output |
|---|---|
review |
{summary, risk_score, base_risk_score, model_risk_score, risk_files[], auto_approve, findings[], knowledge_docs[], excluded[], skipped[], chunks, diagnostics, merged_findings, context_snippets, run_id, pr_key, iteration, requester, agent, usage} with findings sorted most severe first; merged_findings counts same-span duplicates folded into one (knowledge guide); context_snippets counts the repository-context snippets given |
describe |
{title, type, summary, changes[]} |
improve |
{suggestions: [{file, start_line, end_line, category, summary, existing_code, improved_code}]} |
plan |
{summary, affected_files[], phases[], verification[], risks[], references[]} (no patch is read) |
command |
{command, answer} for /explain; {command, suggestions[]} for /refactor and /docstrings |
risk |
{score, band, files[]}: the deterministic risk score, with no model call |
Every model answer is validated against the schema and
anchored to the diff before it is printed. JSON output is a report: it starts
with "apiVersion": "vizzini.infrashift.io/v1" and a "kind" and is itself
schema-checked, ready for garmr.
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
Success |
1 |
Any error: bad flags, unreadable patch, proxy failure, or an answer the model could not repair |
2 |
Review mode: at least one finding has a severity listed in --fail-on |
Policy gate
Section titled “Policy gate”The gate’s default comes from #PolicyGate in schema/review.cue, which
blocks on Critical and Major. The review is always printed in full, and
the gate only decides the exit code, so a CI job can post the review and then
fail:
git diff origin/main...HEAD | pr-review --mode review > review.mdstatus=$? # 0 pass, 2 blocked by policy, 1 errorpr-review --fail-on Critical # block only on Criticalpr-review --fail-on Critical,Major,Minorpr-review --fail-on none # report, never blockAn unknown severity such as --fail-on High is rejected before any request
is made.
The noise floor
Section titled “The noise floor”Some kinds of finding are rarely worth a reviewer’s time. In Vizzini’s
benchmark, 6% of Trivial findings and about a
fifth of Minor Performance findings were real problems, against 81% of Major
ones. By default, pr-review leaves these out. Minor Maintainability findings
were as noisy, but models sometimes file a real bug under Maintainability, so
the default keeps them:
- Where they go: they are not shown in Markdown or text output. The JSON
report keeps them in a
filteredlist, so nothing is lost. - What still sees them: the floor decides what is shown, never what
blocks.
--fail-onstill applies to filtered findings, and so does auto-approval. When a filtered finding fails the gate,pr-reviewsays so. - The bot:
vizzini-botdoes not post filtered findings. A thread it posted earlier for such a finding is left open, not resolved as fixed.
The rules live in #NoiseFloor in schema/review.cue. --all-findings turns
the floor off for one run. Embedders set Config.NoiseFloor, where
{"rules": []} turns it off, or use ReviewOptions.AllFindings.
Interrupting with Ctrl-C or SIGTERM cancels in-flight requests.