symfonic.services.switching.release¶
release ¶
LIB-CR / LIB-OV — what one library release ships, and which side of the retirement boundary it sits on.
The two version markers are the normative names from T1.2.6. They live here as module constants because release automation, the migration error text, and the construction-time rejection all have to agree on them; three copies of "10.4" in three files is how a version boundary quietly becomes two boundaries.
ReleaseProfile
dataclass
¶
ReleaseProfile(package_version: str, static_vectors: Mapping[str, GenerationVector], constraints: ConstraintSet, override_table: Mapping[str, Sequence[GenerationVector]] = dict())
Everything the hermetic library backend is allowed to know (DMC-3).
A profile is compiled data: the static vector the release was validated against, the constraint set it shipped, and the documented override table. There is no field for "where to look this up", because looking anything up is precisely what library mode may not do.
release_line ¶
version's release line, at the width the two markers are written to.
The markers name lines, so a version is compared by its line: 10.4.1
is on 10.4 and is honoured exactly as 10.4 is. Comparing the full
parsed tuple instead put every patch of the last honouring line strictly
inside the forbidden band — parse_version("10.4.1") > (10, 4) — so the
first patch on the very line this programme is cutting could not construct
a profile at all. That was inert while nothing in src/ built one;
TA8.54 put ReleaseProfile on SymfonicAgent.__init__'s unconditional
path, which is what made it reachable.
Truncation is deliberately only to the marker width. 10.5 still
narrows to (10, 5) and still falls in the band, because LIB-OV-6 means
exactly that: a line between the markers neither honours nor rejects a pin,
and the remedy is to move both markers together by amending the ADR, not to
widen the comparison until the band disappears.