Skip to main content

Module compat

Module compat 

Source
Expand description

The compatibility engine: how much the public contract moved, and therefore what the smallest honest version is.

§The authority this takes away

Before this module there were two answers to one question. scripts/ci/version-matches-surface compared the registry of two refs and said what the surface required; super::version counted feat: and fix: in the commit subjects and said what the commits implied, and that second answer was the one release bump actually wrote. So a capability deleted under a refactor: heading was a patch to the writer and a breaking change to the gate, and the tree could carry an under-versioned public contract until CI happened to look.

There is one authority here now, and it is the contract:

  surface(base) ─┐
                 ├─ diff ─ implied impact ─ policy ─ required impact ─ required version
  surface(head) ─┘                                          │
                                                            ▼
                                             one writer, which may not go under it

Conventional commits did not go away and are not worthless — they are how a change explains itself, and they are the whole of the changelog’s prose. They are carried here as CommitEvidence, beside the verdict rather than deciding it, and when they understate what the contract did the plan says so explicitly. That line is the point of the subsystem: a human label and a measured fact, disagreeing, in the open.

§Why unknown means major

compare_schema models the schema mutations it can name and refuses to guess at the rest: a key it does not understand, changed, is Impact::Major with a diagnostic saying which pointer and that it is unmodelled. A false major is an argument; a false patch is a broken caller who finds out by breaking. Prose keys are normalised away first (see super::surface::normalise) precisely so that this conservatism costs nothing on the changes that are not contract changes at all.

use majordomus_cli::release::compat::{Impact, Mode, Policy};
use majordomus_cli::release::version::Version;

// Below 1.0.0 a removal costs a minor rather than 1.0.0 — and is still named breaking.
let policy = Policy::for_version(Version::parse("0.5.0").unwrap());
assert_eq!(policy.mode, Mode::Pre1_0Strict);
assert_eq!(policy.required_of(Impact::Major), Impact::Minor);

// At 1.0.0 the shift ends and the implied impact is the requirement.
let policy = Policy::for_version(Version::parse("1.2.0").unwrap());
assert_eq!(policy.required_of(Impact::Major), Impact::Major);
assert_eq!(policy.required_of(Impact::None), Impact::None, "an unchanged surface owes nothing");

Structs§

Baseline
The release this tree is measured against, and how it was found.
CommitEvidence
What the commit subjects since the baseline said about themselves.
Diagnostic
Something about the release state that a person should be told, whatever the verdict.
LastRelease
The release a version is measured from, named without reading its surface.
Policy
The compatibility policy, named and versioned.
SurfaceChange
One movement of the public contract, with the reason it counts for what it does.
VersionPlan
The whole answer: what moved, what that requires, and what the tree declares.

Enums§

Direction
Whether a change added, removed or altered part of the contract.
Impact
How much a change moves the contract.
Mode
How this project turns a measured impact into the version it owes.
Severity
How much a diagnostic matters.
Status
Whether the tree may land or ship as it stands.
SurfaceKind
Which projection of the contract a change is in.

Constants§

POLICY_SCHEMA
The policy these verdicts were reached under, carried into every plan so that a decision recorded today can still be explained when the rules below change.

Functions§

analyze
The one analysis. Everything that answers a version question calls this.
declared_impact
The bump two version numbers already represent.
diff
Every way the contract moved between two surfaces.
last_release
The release analyze measures from when no --since is given, named without reading its surface — None when nothing was published.
unrecorded_tag
What to say about a tag the layer holds no release record for.