Skip to content

Scenarios S22 & S23: Application and Plugin Contracts

Not every check is "does this library's own public header/binary surface stay compatible." Two related but distinct questions ADR-047 §8 names S22 and S23:

  • S22 — application compatibility. Will this specific application still work with the new library version? Scopes the verdict to only what the application actually calls — a break in a symbol the app never uses is not a break for this check.
  • S23 — plugin/dlopen/dlsym contract. Does a fixed set of required symbols still exist, at all — not a public-header ABI comparison, since a plugin/host contract is usually a narrow, explicitly-named symbol list, not "everything public."

Both are a target-kind on an otherwise ordinary check-target/ check-project.yml check, not a different command or workflow.

S22: target-kind: app-consumer

targets:
  myapp-consumer:
    kind: app-consumer
    consumer_binary_pattern: "bin/myapp"
    library: libpvxs   # the check's baseline/candidate lookup redirects through this
    checks:
      - channel: accepted-main
        depth: headers

The check's own reporting identity stays myapp-consumer, but its baseline/candidate library lookup redirects through library:'s target — the "library redirect" every app-consumer/plugin-contract target uses. check-target's consumer-binary input forwards to the root Action's --used-by; see Application Compatibility for the full --used-by scoping model, and the check-target reference for the target-kind input table.

Beyond "is it affected": why. When the library side also carries a source graph — an L2, header-only one built automatically whenever headers are parsed at all, or a broader L4/L5 build/source graph from --sources/--build-info — abicheck can explain the actual call chain connecting a symbol myapp imports to the internal declaration that changed — not just "symbol X is missing" but "the public entry point you call internally reaches the thing that broke." See Application Compatibility → Why does this consumer depend on the changed declaration? for the full model and its current limits.

S23: target-kind: plugin-contract

targets:
  ioc-plugin-contract:
    kind: plugin-contract
    contract_file: "contracts/ioc-plugin.syms"   # one required symbol per line, # comments allowed -- NOT YAML
    library: libpvxsIoc
    checks:
      - channel: accepted-main
        depth: binary

contract-file forwards to the root Action's --required-symbols. See Plugin Systems for the full --required-symbol/--required-symbols/--policy plugin_abi model.

Neither works with channel: none

scan mode has no --used-by/--required-symbols equivalent — an app-consumer/plugin-contract check has no scope to audit without a baseline to compare against. Give it a real channel, or use kind: library for a no-baseline audit (S5) instead.

See also