Skip to content

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 — switches compare to 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
# Strict preset but ignore quality issues
severity:
  preset: strict
  quality_issues: info
# 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:

abicheck compare old.json new.json --config .abicheck.yml

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:

  1. Severity Configuration table — shows the configured level, finding count, and exit impact for each category.
  2. 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:

# .abicheck.yml, committed alongside the workflow
severity:
  quality_issues: error
  potential_breaking: info
- uses: abicheck/abicheck@v0.6.0
  with:
    old-library: libfoo-v1.json
    new-library: libfoo-v2.json