Severity Configuration¶
abicheck classifies every detected change into one of four issue categories, each with a configurable severity level that controls exit codes and report presentation. Severity is layered on top of the overall verdict — it doesn't replace it.
Severity is the last step of the CI gating pipeline (classify → suppress → severity → exit code), and any active severity setting — a
--severity-*flag or a severity value in.abicheck.yml— switchescompareto the severity-based exit-code scheme. See CI Gating for how it combines with policies, suppressions, and baselines.
Issue categories¶
Every ChangeKind is assigned to exactly one of these categories:
| Category | What it covers | Default severity |
|---|---|---|
| abi_breaking | Clear ABI/API incompatibilities (e.g. func_removed, type_size_changed) |
error |
| potential_breaking | Source-level breaks and deployment risk (e.g. enum_member_renamed, symbol_version_required_added) |
warning |
| quality_issues | Problematic behaviors that don't break compatibility (e.g. visibility_leak, soname_missing, func_noexcept_added) |
warning |
| addition | New public API surface (e.g. func_added, type_added, enum_member_added) |
info |
The category assignment is based on canonical kind sets defined in
checker_policy.py and respects the active --policy (e.g. sdk_vendor
downgrades enum_member_renamed from potential_breaking to quality_issues).
Severity levels¶
Each category can be set to one of three levels:
| Level | Report presentation | Exit code impact |
|---|---|---|
error |
Flagged prominently with badge | Contributes to non-zero exit code |
warning |
Shown as a warning with badge | Does not affect exit code |
info |
Informational, neutral | Does not affect exit code |
CLI options¶
Presets¶
# Use the default preset (explicit)
abicheck compare old.json new.json --severity-preset default
# Strict: everything is an error (exits non-zero on any finding)
abicheck compare old.json new.json --severity-preset strict
# Info-only: purely informational (always exits 0)
abicheck compare old.json new.json --severity-preset info-only
Per-category overrides¶
--severity-preset is the whole per-run CLI surface. Individual categories
are set in .abicheck.yml's severity: block — one spelling, not a flag and
a config key saying the same thing — and a per-category value overrides
whatever the preset assigns that category:
# .abicheck.yml — default preset but fail on API additions too
severity:
preset: default
addition: error
# Only fail on binary ABI breaks, everything else informational
severity:
preset: info-only
abi_breaking: error
compare discovers .abicheck.yml from the working directory, or takes one
explicitly:
Available keys, each error/warning/info:
- severity.abi_breaking
- severity.potential_breaking
- severity.quality_issues
- severity.addition
Presets reference¶
See Severity presets for the
exact abi_breaking/potential_breaking/quality_issues/addition level
each preset assigns — that table is the authority compare's exit-code
computation follows; this page only documents how to select and override it.
Exit codes¶
When any severity setting is active — --severity-preset, or a severity
value in .abicheck.yml — the exit code is computed from the severity
configuration instead of the legacy verdict system. See
Severity-aware exit codes
for the exact code-to-condition table; the highest applicable code wins.
Without any active severity setting (no --severity-* flag and no config
severity value), the legacy verdict-based exit codes apply (see
exit codes reference).
Report output¶
Markdown¶
When severity is configured, the markdown report includes:
- Severity Configuration table — shows the configured level, finding count, and exit impact for each category.
- Section badges — each change section header includes the severity level
badge (e.g.
## ❌ Breaking Changes ❌ \ERROR``).
JSON¶
The JSON output includes a severity object when severity is configured:
{
"severity": {
"config": {
"abi_breaking": "error",
"potential_breaking": "warning",
"quality_issues": "warning",
"addition": "info"
},
"categories": {
"abi_breaking": {"severity": "error", "count": 2},
"potential_breaking": {"severity": "warning", "count": 1},
"quality_issues": {"severity": "warning", "count": 0},
"addition": {"severity": "info", "count": 3}
},
"exit_code": 4
}
}
Policy interaction¶
The severity system respects the active policy (--policy). For example,
under sdk_vendor, kinds that are downgraded from API_BREAK to COMPATIBLE
are reclassified from potential_breaking to quality_issues or addition
accordingly.
This means --policy sdk_vendor --severity-preset default will not exit
non-zero for changes that the sdk_vendor policy downgrades — for example,
kinds moved from potential_breaking to quality_issues or addition are
demoted to warning or info under the default preset. However, the
strict preset maps all categories (including quality_issues and
addition) to error, so --policy sdk_vendor --severity-preset strict will
still exit non-zero for any detected changes, even those the policy downgrades.
GitHub Action¶
The GitHub Action supports severity configuration via inputs:
- uses: abicheck/abicheck@v0.6.0
with:
old-library: libfoo-v1.json
new-library: libfoo-v2.json
severity-preset: strict # fail on new API additions too
Per-category overrides are not Action inputs and are not extra-args
either — they live in the repository's own .abicheck.yml, which the Action
picks up from the checkout: