ABI/API taxonomy coverage¶
Phases 2 and 3 of ABI/API knowledge and corpus: every leaf mechanism in the ABI/API failure taxonomy resolved against the three things this repository already has -- the docs/learn/ page(s) that explain it, the catalog/cases/ case(s) that demonstrate it, and the ChangeKind(s) that would produce a finding for it -- and then classified with exactly one coverage status.
The taxonomy is deliberately independent of abicheck's own vocabulary, which is what lets this page find a gap on either side rather than defining the domain in abicheck's image and then trivially covering it. A column may legitimately be empty; an empty one is recorded, not filled in with the nearest plausible match.
The mapping itself is hand-maintained in docs/_meta/abi-taxonomy-coverage.json (the single source of truth this page renders and scripts/check_ai_readiness.py's abi-taxonomy-coverage check gates). Only two facts on this page are derived: each ChangeKind's owning abicheck/model/change_catalog/ module and its minimum evidence tier (scripts/evidence_tiers.py), read from those sources so they cannot go stale here.
Headline¶
65 of 88 known ABI/API failure mechanisms are COVERED -- explained by a docs/learn/ page, demonstrated by a catalog/cases/ case, and detected by at least one ChangeKind. The remaining 23: 3 KNOWN_UNDETECTABLE, 1 NOT_IMPLEMENTED, 11 MISSING_CASE, 8 PARTIALLY_COVERED.
This is the plan's intended metric: completeness against the domain, not a case count. A corpus can grow indefinitely without moving this number, and can look complete while a whole mechanism class has no case at all.
| Status | Leaves | Meaning |
|---|---|---|
NOT_APPLICABLE |
0 | outside abicheck's stated scope |
KNOWN_UNDETECTABLE |
3 | real and explained, but no static evidence distinguishes it |
NOT_IMPLEMENTED |
1 | no detector claims it at any evidence tier -- a tractable product gap |
MISSING_CASE |
11 | a detector exists, but no catalog case demonstrates it |
PARTIALLY_COVERED |
8 | detected and demonstrated, but only a narrower sub-case, or unexplained |
COVERED |
65 | explained, demonstrated, and detected |
| Total | 88 |
The six statuses are evaluated in the order listed (first match wins) -- see the plan's own Phase 3 table in ABI/API knowledge and corpus for each definition. The order, not the prose, is what keeps them mutually exclusive: a mechanism with a detector but no case satisfies both "detection is real" and "no case exists".
Phase 4 backlog¶
The 11 MISSING_CASE leaves below are Phase 4's concrete work list: a detector already claims each one, so the gap is a corpus gap. Phase 4 closes each with a paired positive/negative control through the ordinary case-authoring path (catalog/CLAUDE.md) -- it is not started, and this page does not require the list to reach zero (a tracked, visible gap is preferred to a manufactured closure).
| Leaf | Why it is open |
|---|---|
calling-contract.variadic-change |
Four detectors claim the fixed-arity/variadic transition, none has a case, and no docs/learn/ page mentions variadic functions at all -- so this leaf is a corpus gap and a documentation gap at once. |
dependency-abi.version-range-widening |
Four detectors reason about a dependency constraint admitting an incompatible version, and learn/dependency-floors.md explains the mechanism, but no case widens a range and shows the consequence. |
ecosystem-specific.cpython-limited-api-tag-change |
Three detectors (plus the vendored Stable-ABI membership set) claim the limited-API contract, and learn/packages-and-consumers.md explains abi3, but no catalog case is a CPython extension module changing its stable-ABI tag. |
ecosystem-specific.cpython-object-layout-change |
python_gil_abi_changed covers the free-threaded/no-GIL build split and python_stable_abi_violation covers reaching into a non-guaranteed field, but no case exercises either, and CPython's own object-layout evolution across interpreter versions has no fixture. |
ecosystem-specific.sycl-device-binary-format-change |
The SYCL plugin/runtime detectors exist, but the two SYCL cases in the catalog are host-side (an overload set and a device-impl pointer field); no case changes the packaged device-binary format or target list. |
export-surface.documented-contract-drift |
The surface-growth detectors exist and learn/surface-growth.md explains the mechanism, but no case exercises accretion of an undocumented surface across releases. |
export-surface.version-script-map-change |
Three detectors claim the export-map surface (an absent version script, a changed export policy, a retargeted PE ordinal), but the corpus has no case where a version script or .def file -- and nothing else -- changes the export set. |
source-abi.macro-driven-layout-change |
case164 is the false-positive control (a #ifdef-guarded field where both releases define the macro, so the correct answer is NO_CHANGE). No case demonstrates the positive mechanism -- two consumers compiling the same header under different macro state and getting different layouts -- which the context-mismatch detectors claim. |
source-api.signature-change-source-only |
case186 is the ABI-neutral negative control (a char* parameter becoming const char*, which must stay NO_CHANGE). No case demonstrates the positive mechanism: a binary-identical change that still breaks recompilation of consumer source. |
symbol-identity.alias-change |
Detection exists for the .symver alias half (plus the PE forwarder and Mach-O re-export analogues), but no catalog case exercises any of them, and no detector claims a plain __attribute__((alias)) repoint. |
toolchain-platform.endianness-change |
elf_endianness_changed claims the mechanism outright, but no case pairs a little-endian and a big-endian build -- the catalog's build fixtures are all produced on one host. |
Separately, 1 leaf is NOT_IMPLEMENTED -- a product gap rather than a corpus gap, tracked in known gaps: dependency-abi.linking-mode-change. And 3 leaves are KNOWN_UNDETECTABLE -- accepted limitations, cross-referenced from Limitations: header-only.include-guard-macro-collision, header-only.template-heavy-recompilation-drift, symbol-identity.ifunc-resolver-change.
Per-leaf mapping¶
One row per taxonomy leaf, in the taxonomy's own branch and row order. Each detector cell names the ChangeKind, the abicheck/model/change_catalog/ module that owns its registry entry, and its minimum evidence tier; -- there means the kind carries no entry in scripts/evidence_tiers.py's EVIDENCE_TIER_BY_KIND (that table covers the kinds the example catalog exercises, not every kind in the registry). A case cell marked (control only) maps a case that exercises the mechanism's non-breaking sibling -- a negative or false-positive control -- without demonstrating the mechanism itself.
1. Symbol identity (symbol-identity)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
symbol-identity.removalSymbol removal |
abi-cheat-sheet 02-symbol-contracts |
case01_symbol_removalcase12_function_removedcase182_accidental_export_removed_still_breakingcase58_var_removed |
func_removed (symbols, L0)func_removed_elf_only (symbols, L0)type_removed (types, L1)var_removed (symbols, L0) |
COVERED |
symbol-identity.renameSymbol rename |
02-symbol-contracts | case194_header_graph_rename_reconciledcase86_tag_struct_renamed |
declaration_renamed (source, L5)func_likely_renamed (symbols, --)symbol_renamed_batch (symbols, --)tag_type_renamed (types, L0) |
PARTIALLY_COVERED |
symbol-identity.mangling-scheme-changeMangling-scheme change |
04-cpp-abi modern-cpp-toolchain-hazards msvc-pe-abi-model system-library-discipline |
case104_glibcxx_dual_abi_flipcase113_abi_tag_changed |
abi_tag_changed (platform, L0)glibcxx_dual_abi_flip_detected (platform, L0)libcpp_abi_version_changed (types, --) |
COVERED |
symbol-identity.mangling-signature-changeMangling-signature change |
02-symbol-contracts 04-cpp-abi |
case02_param_type_changecase10_return_typecase166_ref_qualifier_addedcase22_method_const_changed |
func_cv_changed (types, L1)func_params_changed (symbols, L1)func_ref_qual_changed (types, L2)func_return_changed (symbols, L1) |
COVERED |
symbol-identity.linkage-changeLinkage change |
02-symbol-contracts 05-linker-elf |
case157_inline_function_removedcase59_func_became_inlinecase66_language_linkage_changed |
func_became_inline (symbols, --)func_language_linkage_changed (symbols, L0)func_lost_inline (symbols, --)func_removed_elf_only (symbols, L0)inline_function_removed (source, L4) |
COVERED |
symbol-identity.visibility-changeVisibility attribute change |
05-linker-elf abi-surface elf-symbol-filtering |
case06_visibilitycase51_protected_visibility |
func_visibility_changed (symbols, L0)func_visibility_protected_changed (platform, --)protected_visibility_changed (platform, --)symbol_elf_visibility_changed (platform, L0)type_visibility_changed (types, --)visibility_leak (platform, --) |
COVERED |
symbol-identity.version-node-changeSymbol-version-node change |
05-linker-elf system-library-discipline |
case139_symbol_version_node_removedcase13_symbol_versioningcase183_internal_version_node_churncase65_symbol_version_removed |
symbol_moved_version_node (platform, --)symbol_version_defined_added (platform, L0)symbol_version_defined_removed (platform, L0)symbol_version_node_removed (platform, L0)symbol_version_required_added (platform, L0)symbol_version_required_removed (platform, --) |
COVERED |
symbol-identity.weak-strong-binding-changeWeak/strong binding change |
abi-cheat-sheet | case128_symbol_binding_strengthenedcase180_symbol_binding_lost_uniquecase27_symbol_binding_weakened |
common_symbol_risk (platform, --)symbol_binding_became_unique (platform, L0)symbol_binding_changed (platform, L0)symbol_binding_lost_unique (platform, L0)symbol_binding_strengthened (platform, L0) |
PARTIALLY_COVERED |
symbol-identity.alias-changeSymbol alias change |
02-symbol-contracts system-library-discipline |
none | macho_reexport_changed (platform, L0)pe_forwarder_changed (platform, L0)symbol_version_alias_changed (platform, --) |
MISSING_CASE |
symbol-identity.ifunc-resolver-changeIndirect-function resolver change |
dependency-floors modern-cpp-toolchain-hazards verdicts |
case29_ifunc_transition |
ifunc_introduced (platform, L0)ifunc_removed (platform, --) |
KNOWN_UNDETECTABLE |
symbol-identity.rename(PARTIALLY_COVERED) — The catalog demonstrates rename reconciliation at the L5 source-graph tier (case194) and a tag-type rename, but no case exercises the flat exported-symbol rename detectors (func_likely_renamed/symbol_renamed_batch) on a binary pair.symbol-identity.weak-strong-binding-change(PARTIALLY_COVERED) — Detection and cases are complete, but the only docs/learn/ material is a pair of cheat-sheet table rows -- no narrative page explains weak/strong binding, interposition, or when relaxing it matters.symbol-identity.alias-change(MISSING_CASE) — Detection exists for the.symveralias half (plus the PE forwarder and Mach-O re-export analogues), but no catalog case exercises any of them, and no detector claims a plain__attribute__((alias))repoint.symbol-identity.ifunc-resolver-change(KNOWN_UNDETECTABLE) — abicheck observes ifunc adoption and removal (ifunc_introduced/ifunc_removed, case29), but the mechanism as stated is a change inside the resolver's own selection logic: which implementation binds is decided at load time from CPU features, so no static evidence from two artifacts distinguishes an unchanged resolver from one that now selects differently.
2. Function calling contract (calling-contract)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
calling-contract.parameter-type-changeParameter type change |
02-symbol-contracts | case02_param_type_changecase189_public_function_private_parameter_typecase33_pointer_levelcase46_pointer_chain_type_change |
func_params_changed (symbols, L1)param_pointer_level_changed (symbols, L1)template_param_type_changed (types, --) |
COVERED |
calling-contract.parameter-count-changeParameter count (arity) change |
02-symbol-contracts | case199_public_function_parameter_addedcase200_new_entry_point_instead_of_parameter_added |
func_params_changed (symbols, L1)mandatory_template_param_added (types, --) |
COVERED |
calling-contract.parameter-order-changeParameter order change |
02-symbol-contracts | case201_public_function_parameters_reorderedcase202_public_header_declaration_order_changed |
func_params_changed (symbols, L1) |
COVERED |
calling-contract.return-type-changeReturn type change |
02-symbol-contracts | case102_frozen_runtime_signature_changedcase10_return_typecase46_pointer_chain_type_change |
func_return_changed (symbols, L1)return_pointer_level_changed (symbols, --)template_return_type_changed (types, --)unspecified_return_now_named (types, --) |
COVERED |
calling-contract.calling-convention-changeCalling-convention change |
05-linker-elf msvc-pe-abi-model |
case64_calling_convention_changed |
calling_convention_changed (symbols, L1) |
COVERED |
calling-contract.exception-specification-abi-changeException-specification ABI change |
04-cpp-abi exception-unwinding-abi |
case130_exceptions_mode_flipcase15_noexcept_change |
exceptions_mode_changed (platform, L3)func_exception_spec_changed (symbols, L2)func_noexcept_added (symbols, --)func_noexcept_removed (symbols, --) |
COVERED |
calling-contract.variadic-changeVariadic/fixed-arity change |
none | none | func_variadic_added (symbols, L2)func_variadic_removed (symbols, L2)param_became_va_list (symbols, --)param_lost_va_list (symbols, --) |
MISSING_CASE |
calling-contract.implicit-this-changeImplicit this change |
04-cpp-abi | case21_method_became_static |
func_static_changed (types, L1) |
COVERED |
calling-contract.aggregate-classification-changeAggregate-classification change |
04-cpp-abi class-layout-abi |
case129_struct_return_conventioncase69_trivial_to_nontrivial |
standard_layout_lost (types, --)struct_return_convention_changed (platform, L1)trivially_copyable_lost (types, --)value_abi_trait_changed (platform, L1) |
COVERED |
calling-contract.pass-by-value-threshold-changePass-by-value size-threshold crossing |
04-cpp-abi class-layout-abi |
case129_struct_return_convention |
struct_return_convention_changed (platform, L1) |
PARTIALLY_COVERED |
calling-contract.variadic-change(MISSING_CASE) — Four detectors claim the fixed-arity/variadic transition, none has a case, and no docs/learn/ page mentions variadic functions at all -- so this leaf is a corpus gap and a documentation gap at once.calling-contract.pass-by-value-threshold-change(PARTIALLY_COVERED) — Detection covers the return-value register-vs-memory transition only. A by-value aggregate parameter growing across the same platform threshold is reported as an ordinary size change, with no finding stating that the argument moved from registers to an invisible reference.
3. Data layout (data-layout)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
data-layout.size-changeType size change |
03-type-layout class-layout-abi |
case07_struct_layoutcase14_cpp_class_sizecase17_template_abicase40_field_layoutcase48_leaf_struct_through_pointer |
struct_size_changed (types, L1)symbol_size_changed (symbols, L0)symbol_size_changed_const_object (symbols, --)type_size_changed (types, L1) |
COVERED |
data-layout.alignment-changeAlignment change |
03-type-layout class-layout-abi |
case42_type_alignment_changed |
exported_object_alignment_reduced (platform, L0)struct_alignment_changed (types, --)type_alignment_changed (types, L1)var_alignment_changed (symbols, L2) |
COVERED |
data-layout.field-offset-changeField offset change |
03-type-layout class-layout-abi |
case117_no_unique_addresscase43_base_class_member_addedcase77_detail_templated_base_changed |
base_class_offset_changed (types, L1)struct_field_offset_changed (types, --)type_field_offset_changed (types, L1) |
COVERED |
data-layout.field-reorderField reorder |
03-type-layout | case120_internal_struct_reordered_scopedcase198_public_struct_field_reorder |
field_renamed (types, L1)struct_field_type_changed (types, L1)type_field_offset_changed (types, L1) |
COVERED |
data-layout.padding-changePacking/padding change |
03-type-layout class-layout-abi |
case153_struct_packing_flipcase56_struct_packing_changed |
struct_packing_changed (types, L1)struct_packing_mode_changed (platform, L3) |
COVERED |
data-layout.bitfield-allocation-changeBitfield allocation change |
03-type-layout class-layout-abi |
case63_bitfield_changed |
field_bitfield_changed (types, L1) |
COVERED |
data-layout.enum-underlying-type-changeEnum underlying-type change |
03-type-layout | case152_enum_size_flag_flipcase57_enum_underlying_size_changed |
enum_became_scoped (types, L2)enum_lost_scoped (types, L2)enum_size_flag_changed (platform, L3)enum_underlying_size_changed (platform, L1) |
COVERED |
data-layout.union-active-member-changeUnion member change |
03-type-layout | case24_union_field_removedcase26_union_field_addedcase26b_union_field_added_compatible |
union_field_added (types, L1)union_field_removed (types, L1)union_field_type_changed (types, --) |
COVERED |
data-layout.embedded-array-dimension-changeEmbedded fixed-array dimension change |
03-type-layout | case45_multi_dim_array_change |
type_field_type_changed (types, L1)type_size_changed (types, L1) |
COVERED |
data-layout.flexible-array-member-changeFlexible array member change |
03-type-layout | case70_flexible_array_member_changed |
flexible_array_member_changed (types, L1) |
COVERED |
data-layout.tail-padding-reuse-changeTail-padding reuse change |
03-type-layout class-layout-abi modern-cpp-toolchain-hazards |
case117_no_unique_addresscase140_empty_base_optimization_lost |
base_class_offset_changed (types, L1)tail_padding_reuse_changed (types, --)type_field_offset_changed (types, L1) |
COVERED |
4. C++ object model (cpp-object-model)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
cpp-object-model.base-class-addition-removalBase class addition/removal |
04-cpp-abi class-layout-abi |
case188_public_class_private_base_classcase37_base_classcase60_base_class_position_changed |
base_class_offset_changed (types, L1)base_class_position_changed (types, L1)type_base_changed (types, L1) |
COVERED |
cpp-object-model.virtual-function-insertion-reorderVirtual function insertion/reorder |
04-cpp-abi class-layout-abi |
case09_cpp_vtablecase142_vtable_slot_count_binary_onlycase185_inherited_override_reuses_slotcase38_virtual_methodscase68_virtual_method_added |
func_virtual_added (symbols, L1)type_vtable_changed (types, L1)virtual_method_added (types, --)vtable_slot_count_changed (types, L0)vtable_symbol_identity_changed (platform, --) |
COVERED |
cpp-object-model.virtual-function-removalVirtual function removal |
04-cpp-abi class-layout-abi |
case168_virtual_method_devirtualized |
func_virtual_removed (symbols, L2)vtable_slot_count_changed (types, L0) |
COVERED |
cpp-object-model.pure-virtual-transitionPure/non-pure virtual transition |
04-cpp-abi | case23_pure_virtual_added |
func_pure_virtual_added (types, L1)func_virtual_became_pure (types, L1)type_became_abstract (types, L2)type_lost_abstract (types, L2) |
COVERED |
cpp-object-model.multiple-inheritance-thunk-changeMultiple-inheritance thunk/vtable change |
04-cpp-abi class-layout-abi |
case172_vtable_thunk_offset_changedcase173_vtt_slot_count_changedcase174_secondary_vtable_group_changed |
secondary_vtable_group_changed (types, L1)vtable_thunk_offset_changed (types, L0)vtable_thunk_set_changed (types, L0)vtt_slot_count_changed (types, L0) |
COVERED |
cpp-object-model.rtti-representation-changeRTTI representation change |
04-cpp-abi class-layout-abi msvc-pe-abi-model |
case131_rtti_mode_flipcase146_audit_rtti_for_internal |
rtti_for_internal_type (source, L2)rtti_inheritance_changed (types, L0)rtti_mode_changed (platform, L3) |
PARTIALLY_COVERED |
cpp-object-model.virtual-base-layout-changeVirtual base layout change |
04-cpp-abi msvc-pe-abi-model |
case167_base_became_virtual |
base_class_virtual_changed (types, L1)virtual_base_offset_changed (types, L1) |
COVERED |
cpp-object-model.covariant-return-type-changeCovariant return-type change |
04-cpp-abi | case72_covariant_return_changed |
func_return_changed (symbols, L1)type_vtable_changed (types, L1)vtable_thunk_set_changed (types, L0) |
COVERED |
cpp-object-model.vptr-presence-changeVptr presence change |
03-type-layout class-layout-abi |
case203_class_gained_vtable_pointercase204_class_gained_non_virtual_method |
type_field_offset_changed (types, L1)type_size_changed (types, L1)vptr_introduced (types, L1) |
COVERED |
cpp-object-model.rtti-representation-change(PARTIALLY_COVERED) — Detection covers RTTI being switched on/off (rtti_mode_changed), an inheritance-shape change reflected in the RTTI records, and RTTI emitted for an internal type. Thetype_inforecord's own layout or mangled type-name representation changing -- the Itanium-vs-MSVC representation question this leaf names -- has no detector and no case.
5. Inline/template/source ABI (source-abi)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
source-abi.inline-function-body-changeInline function body change |
04-cpp-abi limitations static-and-header-only |
case157_inline_function_removedcase16_inline_to_non_inlinecase47_inline_to_outlinedcase89_inline_accessor_renamed_pimpl_member |
func_became_inline (symbols, --)func_lost_inline (symbols, --)inline_body_changed (source, --)inline_body_references_renamed_member (types, L2)inline_function_removed (source, L4) |
COVERED |
source-abi.template-instantiation-set-changeTemplate instantiation-set change |
04-cpp-abi limitations template-heavy-libraries |
case122_template_signature_uninstantiatedcase79_missing_template_instantiationcase93_bundle_manifest_drift |
bundle_manifest_instantiation_added (build, --)bundle_manifest_instantiation_removed (build, L0)instantiation_missing_from_binary (types, L2)template_body_changed (source, L4)uninstantiated_template_removed (source, --) |
COVERED |
source-abi.odr-violationOne Definition Rule violation |
04-cpp-abi consumer-models static-and-header-only |
case149_xcheck_odr_variant |
identity_collision_detected (source, L4)odr_source_conflict (source, --)odr_type_variant (source, L4) |
COVERED |
source-abi.constexpr-evaluation-changeconstexpr evaluation change |
06-transitive-breaks abi-surface limitations |
case124_header_constant_value_changedcase190_public_inline_function_references_internal_constant |
constant_added (symbols, --)constant_changed (symbols, L2)constant_removed (symbols, --)constexpr_value_changed (source, --) |
COVERED |
source-abi.macro-driven-layout-changeMacro-driven layout/signature change |
build-profile-comparability build-source-data limitations |
case164_preproc_conditional_field(control only) |
compile_context_conflict (build, L3)header_binary_context_mismatch (build, L2)header_build_context_mismatch (build, L3)header_parse_context_drift (build, --)public_macro_value_changed (source, --) |
MISSING_CASE |
source-abi.default-template-argument-changeDefault template-argument change |
04-cpp-abi template-heavy-libraries |
case87_default_template_arg_changed |
default_template_arg_changed (types, L2)mandatory_template_param_added (types, --) |
COVERED |
source-abi.macro-driven-layout-change(MISSING_CASE) — case164 is the false-positive control (a#ifdef-guarded field where both releases define the macro, so the correct answer is NO_CHANGE). No case demonstrates the positive mechanism -- two consumers compiling the same header under different macro state and getting different layouts -- which the context-mismatch detectors claim.
6. Export/public-surface contract (export-surface)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
export-surface.header-export-divergenceHeader/export divergence |
abi-surface evidence-and-detectability graph-coverage |
case144_audit_private_header_leakcase150_xcheck_export_public_paircase151_xcheck_provider_matrix |
exported_not_public (source, L2)private_header_leak (source, L2)public_not_exported (source, L2)source_decl_binary_symbol_mismatch (source, --)source_surface_dso_mismatch (source, L4) |
COVERED |
export-surface.visibility-demotion-without-header-changeVisibility demotion without header change |
07-designing-for-stability abi-surface elf-symbol-filtering |
case182_accidental_export_removed_still_breakingcase59_func_became_inline |
func_removed_elf_only (symbols, L0)func_visibility_changed (symbols, L0)link_export_policy_changed (build, --)visibility_leak (platform, --) |
COVERED |
export-surface.accidental-exportAccidental export |
07-designing-for-stability abi-surface surface-growth |
case143_audit_accidental_exportcase145_audit_unversioned_export |
exported_not_public (source, L2)undocumented_export_ratio_increased (source, --)unversioned_exported_symbol (source, L0) |
COVERED |
export-surface.version-script-map-changeVersion-script/export-map change |
05-linker-elf 07-designing-for-stability system-library-discipline |
none | link_export_policy_changed (build, --)pe_ordinal_retargeted (platform, L0)version_script_missing (platform, --) |
MISSING_CASE |
export-surface.documented-contract-driftDocumented-contract drift |
abi-surface rollout-and-governance surface-growth |
none | abi_surface_explosion (platform, --)public_surface_grew (source, --)public_surface_shrank (source, --)undocumented_export_ratio_increased (source, --) |
MISSING_CASE |
export-surface.version-script-map-change(MISSING_CASE) — Three detectors claim the export-map surface (an absent version script, a changed export policy, a retargeted PE ordinal), but the corpus has no case where a version script or.deffile -- and nothing else -- changes the export set.export-surface.documented-contract-drift(MISSING_CASE) — The surface-growth detectors exist andlearn/surface-growth.mdexplains the mechanism, but no case exercises accretion of an undocumented surface across releases.
7. Dynamic linker contract (dynamic-linker)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
dynamic-linker.soname-changeSONAME change |
05-linker-elf compatibility-direction system-library-discipline |
case05_sonamecase50_soname_inconsistentcase84_bundle_soname_skew |
compat_version_changed (platform, --)soname_bump_recommended (platform, --)soname_bump_unnecessary (platform, --)soname_changed (platform, L0)soname_missing (platform, L0) |
COVERED |
dynamic-linker.symbol-versioning-scheme-changeSymbol-versioning scheme change |
05-linker-elf system-library-discipline |
case139_symbol_version_node_removedcase141_versioned_symbol_scheme |
symbol_version_node_removed (platform, L0)unversioned_exported_symbol (source, L0)versioned_symbol_scheme_detected (platform, L0) |
COVERED |
dynamic-linker.dt-needed-changeDT_NEEDED/dependency-list change |
abi-cheat-sheet 05-linker-elf environment-drift |
case138_needed_added |
imported_symbol_added (platform, L0)imported_symbol_removed (platform, L0)needed_added (platform, L0)needed_order_changed (platform, L0)needed_removed (platform, L0) |
COVERED |
dynamic-linker.rpath-runpath-changeRPATH/RUNPATH change |
05-linker-elf environment-drift |
case137_runpath_changedcase52_rpath_leak |
rpath_changed (platform, --)rpath_type_changed (platform, L0)runpath_changed (platform, L0)wheel_rpath_not_portable (build, L0) |
COVERED |
dynamic-linker.binding-mode-changeBinding-mode change |
abi-cheat-sheet 05-linker-elf |
case134_relro_weakened |
bind_now_disabled (platform, L0)dynamic_loading_flags_changed (platform, L0)pe_import_load_mode_changed (platform, L0)relro_weakened (platform, L0)symbolic_binding_mode_changed (platform, L0) |
COVERED |
dynamic-linker.plt-got-representation-changePLT/GOT representation change |
01-foundations 05-linker-elf |
case29_ifunc_transition |
dt_relr_introduced (platform, L0)dt_relr_removed (platform, L0)hash_style_removed (platform, L0)ifunc_introduced (platform, L0)text_relocation_introduced (platform, L0)text_relocation_removed (platform, L0) |
PARTIALLY_COVERED |
dynamic-linker.plt-got-representation-change(PARTIALLY_COVERED) — Six detectors cover the relocation/hash-table representation surface, but the only case is the ifunc transition -- theDT_RELR, text-relocation and hash-style changes the same leaf names have no case, and no learn page explains what changing the relocation representation costs a consumer.
8. Dependency ABI (dependency-abi)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
dependency-abi.transitive-breakTransitive dependency break |
06-transitive-breaks dependency-floors packages-and-consumers |
case18_dependency_leakcase91_bundle_intra_signature_drift |
bundle_intra_dep_signature_changed (build, L0)bundle_intra_type_changed (build, --)runtime_symbol_provider_changed (source, L0)symbol_leaked_from_dependency_changed (platform, --) |
COVERED |
dependency-abi.version-range-wideningDependency version-range widening |
dependency-floors packages-and-consumers |
none | bundle_intra_dep_resolved_to_different_version (build, --)library_version_downgraded (platform, L0)numpy_metadata_understates_required_version (build, L0)wheel_closure_dependency_violation (build, L0) |
MISSING_CASE |
dependency-abi.incompatible-substitutionABI-incompatible dependency substitution |
environment-drift products-not-libraries system-library-discipline |
case92_bundle_provider_changed |
bundle_duplicate_provider (build, L0)bundle_provider_changed (build, L0)runtime_symbol_provider_changed (source, L0)stdlib_implementation_changed (types, --) |
COVERED |
dependency-abi.linking-mode-changeDependency linking-mode change |
01-foundations static-and-header-only |
none | none | NOT_IMPLEMENTED |
dependency-abi.version-range-widening(MISSING_CASE) — Four detectors reason about a dependency constraint admitting an incompatible version, andlearn/dependency-floors.mdexplains the mechanism, but no case widens a range and shows the consequence.dependency-abi.linking-mode-change(NOT_IMPLEMENTED) — No ChangeKind states that a dependency moved between static and dynamic linking. The consequences are partly observable through unrelated kinds (needed_removedwhen the dependency leavesDT_NEEDED,symbol_leaked_from_dependency_changedwhen its symbols appear in the artifact's own export table), but nothing names the transition itself, so a reader gets two unexplained findings instead of one that says what happened. Tractable: both sides'DT_NEEDED/import tables and export sets are already collected at L0.
9. Toolchain/platform ABI (toolchain-platform)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
toolchain-platform.compiler-abi-epoch-changeCompiler ABI-epoch change |
build-profile-comparability modern-cpp-toolchain-hazards system-library-discipline |
case104_glibcxx_dual_abi_flipcase113_abi_tag_changedcase98_cxx_standard_floor_raised |
cxx_standard_floor_raised (build, --)glibcxx_dual_abi_flip_detected (platform, L0)libcpp_abi_version_changed (types, --)stdlib_implementation_changed (types, --)toolchain_version_changed (build, --) |
COVERED |
toolchain-platform.target-triple-changeTarget-triple change |
build-profile-comparability modern-cpp-toolchain-hazards |
case112_lp64_ilp64 |
elf_abi_flags_changed (platform, L0)elf_class_changed (platform, L0)elf_machine_changed (platform, L0)elf_osabi_changed (platform, L0)integer_model_changed (platform, L1)macho_cpu_type_changed (platform, L0)pe_machine_changed (platform, L0)wheel_tag_architecture_mismatch (build, L0) |
COVERED |
toolchain-platform.abi-relevant-flag-changeABI-relevant compiler-flag change |
build-profile-comparability build-source-data environment-drift |
case103_toolchain_flag_driftcase152_enum_size_flag_flipcase153_struct_packing_flipcase154_lto_mode_flipcase155_char_signedness_flipcase98_cxx_standard_floor_raised |
abi_relevant_build_flag_changed (build, L3)build_option_reaches_public_symbol (source, --)char_signedness_changed (platform, L3)enum_size_flag_changed (platform, L3)float_abi_changed (platform, L3)lto_mode_changed (platform, L3)sanitizer_mode_changed (platform, L3)struct_packing_mode_changed (platform, L3)toolchain_flag_drift (platform, L1) |
COVERED |
toolchain-platform.libc-runtime-abi-changelibc/runtime ABI change |
dependency-floors environment-drift system-library-discipline |
case170_env_runtime_floor_raisedcase97_api_depends_on_consumer_env |
macos_deployment_target_raised (build, L0)musllinux_glibc_dependency_detected (build, L0)os_deployment_floor_raised (platform, L0)platform_baseline_floor_raised (platform, L0)runtime_floor_raised (build, L0)time64_abi_changed (platform, L1) |
COVERED |
toolchain-platform.endianness-changeEndianness change |
build-profile-comparability data-wire-compatibility |
none | elf_endianness_changed (platform, L0) |
MISSING_CASE |
toolchain-platform.word-size-changeWord-size (32-bit/64-bit) change |
abi-cheat-sheet build-profile-comparability modern-cpp-toolchain-hazards |
case112_lp64_ilp64 |
elf_class_changed (platform, L0)integer_model_changed (platform, L1)long_double_abi_changed (platform, L0)wchar_model_changed (platform, L1) |
COVERED |
toolchain-platform.hardening-flag-changeHardening/mitigation flag change |
abi-cheat-sheet 05-linker-elf |
case134_relro_weakenedcase135_stack_canary_removedcase136_executable_stack_removedcase179_cet_protection_weakenedcase49_executable_stack |
branch_protection_improved (platform, L0)branch_protection_weakened (platform, L0)cet_protection_improved (platform, L0)cet_protection_weakened (platform, L0)executable_stack (platform, --)executable_stack_removed (platform, L0)fortify_source_weakened (platform, --)pe_hardening_improved (platform, L0)pe_hardening_weakened (platform, L0)pie_disabled (platform, --)stack_canary_removed (platform, L0) |
COVERED |
toolchain-platform.endianness-change(MISSING_CASE) —elf_endianness_changedclaims the mechanism outright, but no case pairs a little-endian and a big-endian build -- the catalog's build fixtures are all produced on one host.
10. Multi-library/product ABI (product-abi)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
product-abi.cross-component-contract-breakCross-component contract break |
06-transitive-breaks products-not-libraries |
case90_bundle_intra_dep_removedcase91_bundle_intra_signature_drift |
bundle_intra_dep_removed (build, L0)bundle_intra_dep_signature_changed (build, L0)bundle_intra_dep_signature_unverified (build, L0)bundle_intra_type_changed (build, --)bundle_unresolved_intra_dependency (build, L0) |
COVERED |
product-abi.version-skew-within-releaseVersion skew within a release |
products-not-libraries rollout-and-governance |
case84_bundle_soname_skewcase93_bundle_manifest_drift |
bundle_library_added (build, --)bundle_library_removed (build, --)bundle_manifest_entry_unsatisfied (build, L0)bundle_soname_skew (types, L0)bundle_variant_coverage_regressed (build, L0) |
COVERED |
product-abi.plugin-interface-breakPlugin interface break |
07-designing-for-stability consumer-models products-not-libraries |
case82_sycl_overload_set_removed |
consumer_required_symbol_removed (source, L0)sycl_overload_set_removed (types, L0)sycl_pi_entrypoint_added (platform, --)sycl_pi_entrypoint_removed (platform, --)sycl_plugin_added (platform, --)sycl_plugin_removed (platform, --) |
PARTIALLY_COVERED |
product-abi.plugin-interface-break(PARTIALLY_COVERED) — The one demonstrated plugin boundary is SYCL's. A generic host/plugin ABI break -- third-party plugins outside the release, which is the case this leaf is about -- is reachable only through the explicit--used-by/--required-symbolconsumer path (consumer_required_symbol_removed), with no case demonstrating it.
11. Source-level API compatibility (source-api)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
source-api.signature-change-source-onlySource-only signature change |
06-transitive-breaks limitations verdicts |
case186_c_api_pointee_const_abi_neutral(control only) |
func_cv_changed (types, L1)func_params_changed (symbols, L1)param_renamed (symbols, --)removed_const_overload (types, --)source_level_kind_changed (types, --) |
MISSING_CASE |
source-api.header-macro-removalPublic macro removal |
06-transitive-breaks abi-surface |
case156_public_macro_removed |
public_macro_removed (source, L4)public_macro_value_changed (source, --) |
COVERED |
source-api.deprecation-attribute-additionDeprecation-attribute addition |
02-symbol-contracts rollout-and-governance |
case205_public_function_marked_deprecatedcase206_deprecation_documented_without_attribute |
enum_deprecated_added (types, L2)field_deprecated_added (types, L2)func_deprecated_added (symbols, L2)func_deprecated_removed (symbols, L2)type_deprecated_added (types, L2)var_deprecated_added (symbols, L2) |
COVERED |
source-api.default-argument-value-changeDefault-argument value change |
abi-cheat-sheet 06-transitive-breaks |
case123_default_argument_removedcase32_param_defaults |
default_argument_changed (source, --)param_default_value_changed (symbols, L2)param_default_value_removed (symbols, L2)python_api_default_removed (symbols, L2) |
COVERED |
source-api.overload-resolution-changeOverload-resolution change |
06-transitive-breaks modern-cpp-toolchain-hazards |
case111_enumerable_thread_specific_lambda_ambiguitycase169_overload_added |
ctor_explicit_added (symbols, L2)ctor_explicit_removed (symbols, --)ctor_overload_ambiguity_risk (symbols, L2)overload_added (types, L0)overload_set_rerouted (types, --)removed_const_overload (types, --) |
COVERED |
source-api.signature-change-source-only(MISSING_CASE) — case186 is the ABI-neutral negative control (achar*parameter becomingconst char*, which must stay NO_CHANGE). No case demonstrates the positive mechanism: a binary-identical change that still breaks recompilation of consumer source.
12. Header-only compatibility (header-only)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
header-only.multiple-version-odrMultiple-version ODR violation |
consumer-models limitations static-and-header-only |
case149_xcheck_odr_variant |
odr_source_conflict (source, --)odr_type_variant (source, L4) |
PARTIALLY_COVERED |
header-only.include-guard-macro-collisionInclude-guard/macro collision |
limitations static-and-header-only |
none | none | KNOWN_UNDETECTABLE |
header-only.inline-namespace-version-stamp-changeInline-namespace version-stamp change |
07-designing-for-stability modern-cpp-toolchain-hazards system-library-discipline |
case100_experimental_removed_without_replacementcase101_inline_namespace_version_bumpedcase71_inline_namespace_moved |
experimental_graduated (types, L0)experimental_removed_without_replacement (types, L0)inline_namespace_moved (platform, L0)inline_namespace_version_bumped (types, L0) |
COVERED |
header-only.template-heavy-recompilation-driftPer-TU recompilation drift |
limitations static-and-header-only template-heavy-libraries |
case122_template_signature_uninstantiated |
header_binary_context_mismatch (build, L2)layout_unverifiable (types, --)template_body_changed (source, L4) |
KNOWN_UNDETECTABLE |
header-only.multiple-version-odr(PARTIALLY_COVERED) — The ODR detectors compare translation units within one analyzed build (case149). Two different releases of the same header-only library being included by different TUs of one consumer program is a whole-program property of an artifact abicheck is not given, so only the narrower sub-case is detected.header-only.include-guard-macro-collision(KNOWN_UNDETECTABLE) — A collision only exists relative to some other library's macro namespace in a consumer's include closure. abicheck compares two versions of one library; nothing in either snapshot -- at any evidence tier -- can establish that an unrelated third party defines the same guard, and the symptom (one definition silently suppressed) leaves no trace in the compared artifacts.header-only.template-heavy-recompilation-drift(KNOWN_UNDETECTABLE) — The mechanism is defined by the absence of the thing abicheck compares: with no compiled artifact, each consumer TU's own instantiation is the ABI, and abicheck never sees those TUs. The header-side signature change is observable (case122,template_body_changed), but per-TU drift across consumers abicheck is not given cannot be established from any evidence tier.
13. Language/ecosystem-specific mechanisms (ecosystem-specific)¶
| Leaf | learn_pages |
catalog_cases |
detector (kind, module, min evidence) |
Status |
|---|---|---|---|---|
ecosystem-specific.c-restrict-qualifier-changerestrict qualifier change |
impact-analysis | case207_pointer_parameter_gained_restrictcase208_restrict_added_to_definition_only |
param_restrict_changed (symbols, L2) |
COVERED |
ecosystem-specific.cpp-stdlib-abi-variantC++ standard-library ABI variant mismatch |
build-profile-comparability modern-cpp-toolchain-hazards system-library-discipline |
case104_glibcxx_dual_abi_flip |
glibcxx_dual_abi_flip_detected (platform, L0)libcpp_abi_version_changed (types, --)public_api_exposes_stl_by_value (symbols, --)stdlib_debug_mode_changed (build, L3)stdlib_implementation_changed (types, --) |
COVERED |
ecosystem-specific.cpython-limited-api-tag-changeCPython limited-API/stable-ABI tag change |
packages-and-consumers | none | python_abi3_dropped (symbols, L0)python_abi3_floor_raised (symbols, L0)python_stable_abi_violation (symbols, L0) |
MISSING_CASE |
ecosystem-specific.cpython-object-layout-changeCPython object layout change |
packages-and-consumers | none | numpy_abi_major_incompatible (build, L0)numpy_target_floor_raised (build, L0)python_gil_abi_changed (symbols, L0)python_stable_abi_violation (symbols, L0) |
MISSING_CASE |
ecosystem-specific.sycl-kernel-abi-changeSYCL kernel ABI change |
06-transitive-breaks packages-and-consumers |
case126_sycl_device_impl_ptrcase82_sycl_overload_set_removed |
sycl_implementation_changed (platform, --)sycl_overload_set_removed (types, L0)sycl_pi_entrypoint_added (platform, --)sycl_pi_entrypoint_removed (platform, --)sycl_pi_version_changed (platform, --) |
COVERED |
ecosystem-specific.sycl-device-binary-format-changeSYCL device-binary format change |
environment-drift packages-and-consumers |
none | sycl_backend_driver_req_changed (platform, --)sycl_plugin_added (platform, --)sycl_plugin_removed (platform, --)sycl_plugin_search_path_changed (platform, --)sycl_runtime_version_changed (platform, --) |
MISSING_CASE |
ecosystem-specific.kernel-symbol-versioning-crc-changeKernel MODVERSIONS CRC change |
packages-and-consumers system-library-discipline |
case175_kabi_crc_changedcase176_kabi_symbol_namespace_changed |
kabi_crc_changed (platform, L0)kabi_export_type_changed (platform, L0)kabi_symbol_added (platform, L0)kabi_symbol_namespace_changed (platform, L0)kabi_symbol_removed (platform, L0) |
COVERED |
ecosystem-specific.kernel-btf-type-id-changeKernel BTF type-ID/graph change |
evidence-and-detectability packages-and-consumers |
case121_kernel_btf_struct_field_added |
struct_field_offset_changed (types, --)struct_field_type_changed (types, L1)struct_size_changed (types, L1) |
PARTIALLY_COVERED |
ecosystem-specific.cpython-limited-api-tag-change(MISSING_CASE) — Three detectors (plus the vendored Stable-ABI membership set) claim the limited-API contract, andlearn/packages-and-consumers.mdexplains abi3, but no catalog case is a CPython extension module changing its stable-ABI tag.ecosystem-specific.cpython-object-layout-change(MISSING_CASE) —python_gil_abi_changedcovers the free-threaded/no-GIL build split andpython_stable_abi_violationcovers reaching into a non-guaranteed field, but no case exercises either, and CPython's own object-layout evolution across interpreter versions has no fixture.ecosystem-specific.sycl-device-binary-format-change(MISSING_CASE) — The SYCL plugin/runtime detectors exist, but the two SYCL cases in the catalog are host-side (an overload set and a device-impl pointer field); no case changes the packaged device-binary format or target list.ecosystem-specific.kernel-btf-type-id-change(PARTIALLY_COVERED) — abicheck reads BTF and reports the underlying struct layout change (case121), which is the cause. It does not model BTF type IDs, the type graph's own shape, or which CO-RE relocations a BPF program would have to be re-relocated for -- the effect this leaf names has no detector.