Stability policy¶
From 1.0, Openbtk follows Semantic Versioning and this policy. Before 1.0, any minor release may break things; every break is recorded in the CHANGELOG.
The policy is enforced, not aspirational: tests/api/ compares the public API,
the registry keys, the command line and the manifest schema versions against
checked-in snapshots, and Openbtk's own test suite turns its deprecation warning
into an error. A change that breaks the promise fails CI.
What is public¶
Public API is what the API reference documents — and only that. Concretely, under this policy:
| Public (stable) | Not public (may change any time) |
|---|---|
| Names on the API reference pages: signatures, pydantic fields, enum members, public methods | Anything with a leading underscore |
Registry keys (loader.clinical_text.plain_text, ...) |
Modules and names not on an API page, even if importable |
The openbtk command: sub-commands, flags, exit codes, and --json output |
The wording of human-readable output and of error messages |
Pipeline config (YAML) fields and the manifest schema (RunManifest, EvalManifest) |
Log line text and field names (OPENBTK_LOG_LEVEL and set_log_level are stable) |
| The safety properties: PHI is never written to a log, error, manifest or report; reports hold identifiers and counts only | The exact detections, scores or wording a component produces (see below) |
Detection and score outputs are not frozen. A better recognizer, a fixed heuristic or a corrected metric changes what a component returns. That is the point of the project. Such changes are listed in the CHANGELOG, and a change that makes a result less strict (finds less, blocks less) is called out under "Behaviour change" so you can re-validate. If you depend on exact output, pin the version.
What counts as a breaking change¶
Breaking, therefore major-version only:
- removing or renaming a public name, registry key, config field, manifest field,
CLI sub-command, flag or
--jsonkey; - a signature change that makes a valid call invalid (removing a parameter, adding a required one, narrowing an accepted type);
- making an optional pydantic field required, or removing one;
- a non-additive manifest change (a manifest's
manifest_versionis semver of its own, additive-only within a major); - changing an exit code's meaning.
Not breaking, allowed in a minor: adding an optional parameter, a field with a default, a registry key, a component, a CLI flag or an error subclass; widening an accepted type; and fixes (below).
Bug fixes may change behaviour in a patch or minor release when the old behaviour contradicted the documentation. They are always in the CHANGELOG's "Fixed" section. Security fixes may change behaviour in a patch release.
Deprecation¶
A public name is never removed without first being deprecated:
- In a minor release it is marked deprecated — it keeps working and emits an
OpenBTKDeprecationWarningnaming the release that will remove it and what to use instead. The CHANGELOG lists it under "Deprecated". - It stays for at least one full minor release, and is removed only in the next major.
- Registry keys, config fields and manifest fields are never removed within a
major version. A renamed key keeps its old spelling as an alias
(
Registry.register_alias(old, new, since=..., removal=...)), which warns on use; your existing YAML keeps validating.
The warning is a DeprecationWarning subclass, so Python hides it by default. To see
it, or to fail on it in your own CI:
python -W default::openbtk.core.deprecation.OpenBTKDeprecationWarning your_script.py
python -W error::openbtk.core.deprecation.OpenBTKDeprecationWarning -m pytest
For maintainers, the mechanism is openbtk.core.deprecation (deprecated,
warn_deprecated) and register_alias; see the core API.
Supported environments¶
Python 3.11 and later. A Python version is dropped only in a minor release, announced in the release before, and never before it is end-of-life upstream. The six core dependencies keep their current lower bounds within a major; optional-extra ranges may widen freely and narrow only in a minor with a note.
openbtk.integrations.langchain is stable as an Openbtk API, but it adapts to
langchain-core, whose own changes are outside our control (ADR-0001):
a LangChain release may require an adapter update in a minor.
Reading manifests across versions¶
A manifest records the schema version it was written with. Read a manifest with the same or a newer Openbtk: readers reject fields they do not know (an older library cannot read a newer minor's additions). Newer readers read every older manifest of the same major.
For contributors¶
python tests/api/surface.py --update regenerates the snapshots after a change.
Adding something is fine, but it must be a deliberate, reviewed snapshot diff. If the
diff shows a removed or changed public name, stop: that needs a deprecation cycle
first. Say why in the commit message and the CHANGELOG.