The .abicheck.yml config file¶
.abicheck.yml is the per-project configuration file (ADR-037 D4). It holds
the stable, reviewed-in-a-PR properties of a project's ABI contract — build
system, header compile context, severity policy, public-surface scoping, and
suppression hygiene — as opposed to per-run invocation flags. See the
Config Keys Reference for the exhaustive,
generated list of every key/sub-key BuildConfig itself validates, and its
exact required type (other recognized top-level keys, parsed by a sibling
module, are also listed there but without a type); this page covers
effective defaults, precedence, and a worked example.
Every field is optional; an absent, empty, or non-mapping file yields the
all-defaults configuration. CLI flags always override the config, which in
turn overrides the built-in defaults (CLI > config > default).
- Loader (build/source blocks):
load_build_config()inabicheck/buildsource/inline.py; parsed into theBuildConfigdataclass. - Precedence resolver (
compareproject-contract blocks):resolve_compare_config()inabicheck/cli_helpers_compare.py.
File discovery¶
| Command | Discovery | Code |
|---|---|---|
compare |
Walks up from the current directory to the filesystem root and uses the first .abicheck.yml found. |
discover_project_config() in cli_helpers_compare.py |
dump --sources / --build-info |
Uses .abicheck.yml at the source-tree root only. |
discover_build_config() in buildsource/inline.py |
| any | An explicit --config <path> overrides discovery. |
cli_options.py (--config) |
Note: an auto-discovered (untrusted)
.abicheck.ymlnever causes a build command inbuild.queryto run — it is skipped with a diagnostic. Abuild.queryruns only when the config is supplied explicitly with--config(which marks it trusted for subprocess execution).--allow-build-queryis a deprecated no-op and is not required.
Strict loading (ADR-043)¶
Config loading is strict: an unknown top-level key, an unknown sub-key
inside a recognized block, a value of the wrong type, or a bad enum value are
all hard errors — not warnings. This is a behavior change from earlier
abicheck versions, which warned on unknown keys and kept going. A malformed
YAML file is also a hard error. On the CLI, any of these surfaces as a usage
error (exit 64; see Exit Codes) — the run never proceeds
on a config abicheck could not fully validate.
There is no longer an init/config scaffolding or diagnostic command
(abicheck init, config validate, config show-effective are all gone —
ADR-043) — write .abicheck.yml by hand, using this page as the schema/key
reference. Since unknown keys are now a hard error rather than a silent
warning, a typo or a key from a newer abicheck release will fail loudly
instead of being ignored — set the top-level version: if you need to
signal a schema generation to tooling, though it does not by itself suppress
an unknown-key error.
Top-level keys¶
build:, sources:, severity:, scope:, suppression:, source:,
compile:, debug:, exit_code_scheme:, version:, risk_rules:,
crosschecks:, targets:, bundles:, profiles:, and baseline: are the
recognized top-level keys. See the
Config Keys Reference for the exhaustive,
generated key/type list (BuildConfig's own schema); the sections below
cover what each block does, its effective defaults, and behavior that isn't
visible from the type alone.
build:¶
Drives inline build/source collection: an advisory build-system hint
(system:, default auto), a build-query command (query:) to produce a
compile DB, and/or an explicit compile_db: path or glob. query runs
only when the config is passed explicitly with --config (trusted) —
never from an auto-discovered config; --allow-build-query is a deprecated
no-op. See Producing source facts and
Build & source data.
sources:¶
Public-header roots/globs (public_headers:, default []) defining the
public surface, paths/globs excluded from source collection (exclude:,
default []), and the L5 source-graph detail cap (graph:, summary
(default, a cheap changed-scope CI graph) or full, a full replay scope).
severity:¶
Per-category severity map consumed by compare: a baseline preset
(default/strict/info-only) plus per-category overrides
(abi_breaking/potential_breaking/quality_issues/addition, each
error/warning/info) — per-category levels override the preset. When any
severity value is in effect, compare uses the severity-aware exit-code path.
See Severity and Exit codes.
scope:¶
Public-surface scoping — the main false-positive control. public: (default
effectively true) restricts analysis to the public exported surface;
collapse_versioned_symbols: (default false) collapses symbol-versioned
duplicates before diffing; show_redundant: (default false) disables
redundancy filtering. public_symbols: is an explicit public-symbol overlay,
additive with any CLI --public-symbol values — entries match exactly
(the raw symbol, or a qualified name's trailing :: segment, so foo also
matches ns::foo); globs/wildcards are not supported (mylib_* matches
nothing), list each symbol. See
API-surface intelligence.
suppression:¶
Suppression hygiene policy (a project rule, distinct from the suppression
rules file — see Related files):
strict: (default false) treats suppression-file problems strictly;
require_justification: (default false) requires a justification on every
suppression entry. See Suppressions.
source:¶
method: pins the precise S-axis (evidence method, s0..s6) for power
users.
Use a concrete
s0..s6, notauto. Whencomparereadssource.methodfrom the config (i.e. no--depthon the command line), the value must resolve to a concrete method —comparerejectsautowith a usage error. Pin a specific level here, or leave the key unset and let--depth(binary/headers/build/source—--maxand the oldfulldepth no longer exist) drive the collection depth per run.
See Scan levels and the
--depth dial.
(graph is not a valid source: sub-key — a config with source: {graph:
...} now fails with an unknown-key error. The L5 graph-detail knob is
sources.graph, in the plural sources: block above.)
compile:¶
The stable half of the L2 header compile context (ADR-037 D4): AST
frontend: (auto/castxml/clang/hybrid, case-insensitive — hybrid
runs castxml and clang together and merges them), std: (C/C++ standard,
e.g. c++17), include_dirs:/defines: (lists), sysroot:, and
nostdinc: (boolean). Per-invocation cross-compile flags stay CLI overrides
(CLI > config).
Values in
compile.std/compile.definesmust be a single whitespace-free compiler-option atom (a config scalar cannot expand into multiple compiler arguments).
debug:¶
Separate-debug-file resolution for ELF (ADR-021a), demoted off the CLI in
ADR-040 Lever 2 — stable per-project debug-artifact knobs, each corresponding
to a now-hidden CLI flag that still overrides the config value
(CLI > config); the coarse per-run --debug-root stays a visible CLI flag.
format: (auto/dwarf/btf/ctf, case-insensitive, default auto-pick)
forces the ELF debug format for both sides (was --debug-format);
dwarf_only: (default false) uses DWARF as the primary source even when
headers are available (was --dwarf-only); debuginfod: (default false)
enables debuginfod network resolution (was --debuginfod); debuginfod_url:
overrides DEBUGINFOD_URLS (was --debuginfod-url).
exit_code_scheme:¶
Top-level string, one of auto, legacy, severity. Default auto.
auto→severitywhen a severity map is in effect, otherwiselegacy.legacy/severityforce that scheme.
See Exit codes.
version:¶
Top-level integer. Default 0 (unset). Declares the config schema version for
forward compatibility.
risk_rules: and crosschecks:¶
Both are recognized top-level keys (so they do not trigger the unknown-key
error), but they are handled outside the compare config merge:
risk_rules:— a mapping of rule-name →{ paths: [...], weight: <int> }path-glob risk profile. It is loaded byscan's--risk-rules <file>option (which reads arisk_rules:block from the given YAML file); it is not auto-loaded from a discovered.abicheck.yml. Parsed byRiskRules.from_dictinbuildsource/risk.py. See Scan levels.crosschecks:— reserved. The active mechanism for tuning cross-checks isscan's repeatable--crosscheck KEY=LEVELflag; the current code does not read acrosschecks:block from the file.
targets:, bundles:, profiles:, and baseline:¶
Recognized top-level keys (so they do not trigger the unknown-key error),
but — like risk_rules:/crosschecks: above — not parsed by BuildConfig
itself. dump/compare/scan never read this block; it exists solely for
G30's GitHub Actions CI-integration primitives (a run-plan generator that
consumes it is planned but not built yet). Parsed and validated by
buildsource/project_targets.py; see the
Project Targets Schema reference for the
full field-by-field schema, the checks: list, and the
abicheck project validate command.
Related files (not .abicheck.yml keys)¶
Some settings often discussed alongside the config live in separate YAML
files, not in .abicheck.yml:
| Concept | File / flag | Top-level schema | Docs |
|---|---|---|---|
| Policy profile | --policy-file <file> (PolicyFile.load, policy_file.py) — note --policy only takes the built-in names strict_abi/sdk_vendor/plugin_abi |
base_policy, overrides, frozen_namespaces, evidence_policy |
Policies |
| Suppression rules | --suppress <file> (suppression.py) |
Suppression rule entries (YAML or ABICC format) | Suppressions |
The evidence_policy block is part of the policy file, not .abicheck.yml.
Complete example¶
A .abicheck.yml using only verified keys:
# Config schema version (forward-compat marker)
version: 1
# Build-system hint + where the compile DB lands
build:
system: cmake
compile_db: build/compile_commands.json
# Public surface definition for source collection
sources:
public_headers:
- include/**
exclude:
- include/**/detail/**
graph: summary
# Stable L2 header compile context
compile:
frontend: castxml
std: c++17
include_dirs:
- include
defines:
- MYLIB_STATIC=0
nostdinc: false
# Separate-debug-file resolution (coarse --debug-root stays a CLI flag)
debug:
format: auto
dwarf_only: false
debuginfod: false
# Severity policy consumed by `compare`
severity:
preset: default
abi_breaking: error
potential_breaking: warning
addition: info
# Public-surface scoping (false-positive control)
scope:
public: true
collapse_versioned_symbols: false
show_redundant: false
public_symbols:
- mylib_foo
- mylib_bar
# Suppression hygiene
suppression:
strict: true
require_justification: true
# Precise evidence method (optional; a concrete s0..s6, never `auto`)
source:
method: s6
# Exit-code scheme for CI
exit_code_scheme: auto