Severity and CI gating
The five-level severity scale, --fail-on semantics, exit codes, and recipes for wiring CommitBrief into pre-commit hooks and CI pipelines.
Findings are tagged with a severity. CommitBrief uses a five-level
scale and exposes the highest matched level via --fail-on for CI
gating.
The five levels
Highest impact → lowest:
critical > high > medium > low > info
| Level | What it flags |
|---|---|
critical |
Exploitable defects, data-loss bugs, regulatory violations, hard security holes (auth bypass, injection, key leak). Treat as release-blocking. |
high |
Likely defects with significant impact: race conditions, missing authorization checks, broken business invariants, severe performance regressions. Should be fixed before merge. |
medium |
Real bugs with moderate impact or significant maintainability issues: incorrect-but-recoverable error handling, missing input validation that downstream catches, expensive but non-critical inefficiencies. |
low |
Minor defects or notable improvements that do not block the PR: inconsistent style breaking project conventions, small efficiency wins, missed cleanup. |
info |
Pure informational notes: educational pointers, alternative approaches, “consider this for v2”. Not a defect. |
The level names are part of the public JSON schema and cannot
be renamed. The level definitions come from the embedded
COMMITBRIEF.md default —
your project-local COMMITBRIEF.md can tighten or relax them for
your codebase.
Severity drives four things
--fail-on=<severity>— “fail at this level or worse” (exit code).--min-severity=<severity>— hide findings below a level in the rendered output (display only).- Cards panel color — severity-coded left border (red → orange → yellow → blue → grey).
--compactordering — sorted critical-first.
The --fail-on flag
Maps the highest finding severity to an exit code. Case-insensitive.
--fail-on=<critical|high|medium|low|info|any|none>
| Value | Meaning |
|---|---|
"" (default) |
Off. Pipeline failures still exit 1; findings do not. |
none |
Explicit off. |
any |
Any finding at any severity fails. |
critical |
Fail when one or more findings have severity critical. |
high |
Fail at high OR critical. |
medium |
Fail at medium, high, OR critical. |
low |
Fail at low, medium, high, OR critical. |
info |
Fail on any finding (since info is the lowest level). Equivalent to any. |
Anything else is a parse error before the review fires:
invalid --fail-on value "X" (expected: critical, high, medium, low, info, any, none)
Exit codes
| Code | Meaning |
|---|---|
| 0 | Review completed; no --fail-on threshold reached. |
| 1 | An error occurred (git failure, provider error, parse failure, guard abort, etc.) OR --fail-on threshold was reached. |
There is no distinction between “pipeline failed” and “--fail-on
matched” at the exit-code level — both exit 1. Stderr disambiguates:
pipeline failures print the underlying error; --fail-on matches
print <N> finding(s) at or above '<severity>' severity.
Graceful degrade behavior
When the LLM produces unparseable JSON (and the one-shot retry
also fails), CommitBrief degrades to markdown rendering and the
findings list is nil. In that case --fail-on is intentionally
skipped and stderr prints:
ℹ --fail-on skipped: LLM produced unparseable output, no findings to evaluate.
Failing CI on a flaky model invocation is worse than letting the run succeed and surfacing the markdown text — you still see the review content.
Display filter — --min-severity
--min-severity=<level> hides findings below the given severity in
the rendered output — cards, markdown, and --copy. It is a
display convenience for noisy reviews, not a gate.
commitbrief --staged --min-severity=high
Crucially, it never weakens CI:
--jsonstays complete. The machine contract always carries every finding, regardless of--min-severity.--fail-onevaluates the full, unfiltered set. Alowfinding hidden from the display still trips--fail-on=low.
Accepts critical | high | medium | low | info | none; an invalid
value errors before the provider call. Use --fail-on to govern the
exit code and --min-severity to govern what you see.
CI recipes
GitHub Actions — fail on critical
- name: CommitBrief review
run: commitbrief --staged --fail-on=critical --no-cost-check
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
The official GitHub Action
CommitBrief/commitbrief-action
is a composite action that runs CommitBrief on pull requests in two
modes:
comment(default) — posts each finding as an inline review comment and submits a verdict viacommitbrief remote pr. Needspull-requests: write.gate— runscommitbrief diff <base>...<head> --fail-on=<sev>and fails the job on a finding at or above the threshold. No comments; only needscontents: read.
name: CommitBrief
on: pull_request
permissions:
contents: read
pull-requests: write # comment mode posts the review
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: CommitBrief/commitbrief-action@v1
with:
provider: anthropic
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
# mode: comment # default
# request-changes-on: high # default: critical
Gate mode (pass/fail only, no comments):
- uses: CommitBrief/commitbrief-action@v1
with:
provider: openai
api-key: ${{ secrets.OPENAI_API_KEY }}
mode: gate
fail-on: high
Pin version: to a released tag (e.g. v1.4.0) for reproducible
CI. CLI-tool providers (claude-cli / gemini-cli / codex-cli) are
not usable in CI — they need a locally-authenticated host CLI.
GitLab CI — save review JSON
review:
script:
- commitbrief --staged --fail-on=high --quiet --json --output review.json
artifacts:
paths: [review.json]
Pre-commit hook
The generated pre-commit hook embeds
--fail-on=critical --quiet --no-cost-check already — install it
with one command:
commitbrief install-hook
See Git hooks.
Interaction with other guards
Each guard exits 1 independently of --fail-on — guards run
before the review completes; --fail-on only evaluates after a
successful provider call.
| Guard | Exit on abort |
|---|---|
.commitbrief/ pre-send guard |
1 with aborted by pre-send guard. |
| Secret scanner | 1 with aborted: pre-send secret scanner. |
| Cost preflight | 1 with aborted: cost preflight. |
--fail-on |
1 with the count + severity label. |
See Safety and cost for what each guard does and how to opt out.