NewCurrent release: licence_audit 1.0.0-rc.2Release notes

Compatibility policy

CLI and configuration compatibility guarantees from licence_audit 1.0.0 onward.

This policy defines the compatibility promise for licence_audit from version 1.0.0 onward. It does not add features to the current release. Before 1.0.0, minor releases can include breaking changes; consult the release notes before you upgrade.

The CLI is the only supported interface. We do not provide a supported Gleam library API.

Canonical documentation

The documentation website is the canonical source for user-facing CLI and configuration behavior. Its source is website/src/pages/docs/**. Usage and flag tables are generated from the CLI definitions; the surrounding guides explain configuration, command behavior, and limits. CI checks the generated sections for drift and checks and builds the website.

The repository README and command files in docs/ link to these guides. They are not separate compatibility contracts. Release notes and contributor decision records describe changes or design history, not additional CLI interfaces.

Compatibility applies to the documentation and CLI definitions for the installed release. The latest website can describe options introduced after an older release; use that release’s tagged website sources and its --help output when checking an older installation.

Versioning

We use Semantic Versioning:

  • Patch releases fix defects without deliberate changes to the supported interface, subject to the correctness and security exceptions below.
  • Minor releases can add compatible commands, options, and configuration.
  • Major releases can change or remove supported interfaces.

Within 1.x, we preserve existing documented CLI and configuration behavior. New settings use defaults that preserve existing behavior. A deliberate change to policy semantics or enforcement defaults requires an opt-in during 1.x, or a new major release.

We document deprecations and migration steps in release notes. Deprecated interfaces remain usable until the next major release.

Commands and configuration

Existing documented commands, flags, aliases, and valid argument forms remain available within a major version. We preserve their meanings, defaults, and documented environment-variable controls.

Existing valid configuration remains valid with the same meaning. This includes configuration discovery, CLI/config precedence, and merge behavior. We can reject invalid input that an earlier version accepted because of a defect.

Compatibility works in the upgrade direction: an older release does not have to accept options or configuration introduced in a newer release.

Exit codes and output streams

We preserve the documented exit-code categories:

Code Meaning
0 Successful completion. Report-only commands do not fail because they find policy violations or vulnerabilities.
1 An enforced gate failed, CLI usage was invalid, or update could not run with non-interactive stdin.
2 An input, configuration, manifest, network, decode, or artifact-generation error prevented completion.
130 The user cancelled update.

These categories apply after the CLI starts on a supported runtime. Escript installations require Erlang/OTP 28 or newer for every command. An unsupported runtime can fail while loading the program, before CLI error handling starts (for example, a corrupt atom table error with exit 127). Such failures are outside this exit-code contract. Prefer a self-contained executable for CI.

A report-only command can still fail when it cannot complete its work. Missing or invalid policy configuration is an error, not a passing check.

Licence reports exit 2 if required package metadata cannot be fetched or decoded, even when they show results for other packages. Policy findings in a completed report still exit 0. update TOML edit and file-write failures also exit 2, not the gate/usage category 1.

Optional enrichment has separate completion rules:

  • vulns and sbom --vulns tolerate individual advisory-detail failures: they warn and retain the advisory ID with unknown severity, then exit 0. An OSV batch request failure exits 2. check --vulns also exits 2 when advisory details are unavailable because it cannot evaluate severity.
  • Default sbom generation tolerates missing Hex or local Git dependency enrichment: it warns, omits unavailable fields, and exits 0. --offline deliberately skips Hex enrichment. Without --offline, --reproducible requires metadata from locked source archives and exits 2 if it cannot obtain it. --reproducible --offline skips all dependency enrichment, including Git, and can exit 0 without dependency licence fields. Root metadata, supported sources, and artifact generation/writes remain required.

These exit-code corrections precede the 1.0 contract: incomplete licence reports previously exited 0, and update edit/write failures exited 1. Scripts that relied on those codes must use 2 for operational failure.

Reports, gate verdicts, and generated artifacts go to stdout unless the user selects an output file. Progress, warnings, and operational errors go to stderr. Commands that support --output keep stdout empty when they write the artifact to that file.

Reports stay on stdout even when an enforced gate fails or a report is incomplete. A completed check that fails a licence or vulnerability policy prints its verdict after the report and exits 1, without a duplicate stderr error. Operational failures, such as OSV batch or advisory-detail request failures, go to stderr and exit 2; any available report and exception coverage stay on stdout.

--quiet hides INFO and WARN messages on stderr, but never errors. Erlang runtime reports, including native-library load errors, also go to stderr. If SBOM generation fails before a document is available, stdout stays empty.

Use exit codes to determine command status. Do not parse diagnostic messages.

Human-readable output

We can change report wording, table layout, ordering, colors, progress messages, and interactive presentation within a major version. These are not parsing interfaces.

The notice document’s exact layout is also not stable. We can improve licence material selection and attribution handling without preserving previous text byte for byte.

Structured output

For SBOMs, we preserve support for the documented CycloneDX version and keep output valid against that version’s schema. We can add schema-permitted fields and improve metadata. We do not promise a fixed JSON layout, field order, or identical bytes across tool releases. A new default CycloneDX version requires a major release; a minor release can offer another version through opt-in.

Audit/check and vulnerability reports do not currently have a supported JSON format. If we add one, we will give its schema an explicit version. Within a schema version, we will preserve existing field names, types, meanings, and required fields. Consumers must tolerate additional fields. We will document any extensible value sets before adding values to them.

An incompatible report schema requires a new schema version. Within a major CLI version, we will preserve the old schema and default, and make the new schema opt-in.

Audit results and correctness fixes

A stable interface does not guarantee the same audit result on later runs. Package maintainers can update metadata, and advisory databases can add or correct vulnerabilities. Network availability and cache freshness can also affect a run.

We can ship correctness and security fixes in patch releases even when they change a verdict or generated artifact. Examples include correcting severity calculation, finding an advisory that we previously missed, or rejecting malformed data that we previously accepted. We identify these changes and their effects in release notes.

This exception does not permit unrelated policy redesign or new enforcement defaults in a patch release.

For sbom --reproducible, reproducibility requires the same tool version, project files, lockfile, options, and relevant environment values, including SOURCE_DATE_EPOCH. Without --offline, Hex metadata comes from checksum-verified locked package archives and Git metadata comes from the archive at the locked commit. The combined flags omit all dependency enrichment, including Git. Mutable Hex publisher and OSV advisory data are not included. Reproducibility does not extend across tool versions.

Internal details

We can change Gleam modules and functions, dependencies, build internals, and on-disk cache formats without a major release. Do not import internal modules or read cache files as an integration interface.

Cache format upgrades must not require manual repair. The CLI must migrate incompatible entries or treat them as misses. A cache miss can require a new network request.

This policy does not expand dependency-source coverage or platform support. Consult the documentation for the installed release for those limits.