Verdicts and exit codes
The page to read when you're writing a script that has to branch on an Izri result.
Run statuses
| Status | Terminal | Meaning |
|---|---|---|
PENDING |
Queued, not yet picked up. | |
RUNNING |
Executing. | |
PASSED |
✓ | Everything passed. |
FAILED |
✓ | Tests failed. |
ERROR |
✓ | The run itself broke. |
CANCELLED |
✓ | Stopped before completion. |
Umbrella states
izri/quality resolves to exactly three values:
| State | Meaning |
|---|---|
passing |
No hard rule fired, composite ≥ 70. |
failing |
A hard rule fired, or composite < 70. |
unknown |
Not enough signal — delta in flight, or all children skipped. |
Child states
| State | Meaning |
|---|---|
passing |
Ran, nothing blocking. |
failing |
Ran, found something. |
pending |
Queued or running. |
error |
The analyzer crashed. Hard rule — fails the umbrella. |
skipped |
Not applicable, or not on your plan. |
CLI exit codes
The contract is one sentence: izri run --watch exits non-zero on any terminal status except PASSED.
| Terminal status | Exit code |
|---|---|
PASSED |
0 |
FAILED |
non-zero |
ERROR |
non-zero |
CANCELLED |
non-zero |
--watch polls every 3 seconds with a 30-minute cap. Hitting the cap is also non-zero — treat a timeout as a failure, because a run you never saw finish is not a run that passed.
Without --watch, izri run returns as soon as the run is enqueued and exits 0 on successful submission. That exit code says the run started, not that it passed. Scripts that gate on quality must use --watch.
Action exit behavior
fail-on-finding (default true) makes the step exit non-zero when the scope check reports hard findings or the test run doesn't pass.
Set it to false to surface results without failing the build. The check run and sticky comment still publish — only the workflow step's exit code changes.
GitHub check conclusions
| Umbrella | Check conclusion |
|---|---|
passing |
success |
failing |
failure |
unknown |
neutral / in progress |
Branch protection treats a required check as unsatisfied until it concludes successfully, so unknown blocks a merge without marking it failed — the correct behavior for "still deciding."
Require izri/quality, not the children. The umbrella handles skipped signals; requiring izri/visual directly blocks every backend-only PR.
Branching in a shell script
#!/usr/bin/env bash
set -euo pipefail
if izri run --watch; then
echo "Safe to merge."
else
status=$?
echo "Izri verdict is not passing (exit $status)"
izri status --json > izri-report.json
exit "$status"
fiNote set -e and the explicit if — under set -e a bare izri run --watch aborts the script before you can capture anything useful.
Distinguishing the two failure modes
A failing umbrella is always one of two things:
- A hard rule fired —
pr_type_forbidden_category,change_uncovered, or an analyzer error. - The composite came in under 70.
izri status --json reports hardFindingsCount. Non-zero means case 1; zero means case 2. They call for different responses — a hard rule needs the specific problem fixed, a low composite usually needs better test coverage of the diff.
Related
- Signals overview — weights and hard rules.
- CLI
- Troubleshooting
Reading this with an agent? /docs/reference/verdicts-and-exit-codes.md serves the raw markdown.
Edit this page on GitHub →All docs