version.hpp¶
The shulib API version — the mechanism behind the Freeze Register's promise.
This header declares 3 constants.
Extracted from include/shulib/version.hpp — this page is that header's documentation, reformatted, so it cannot disagree with the code. Prose about how to think about the API lives in the user guide; worked recipes live in the cookbook; this page is the complete, mechanical list of what exists.
Contents¶
kApiMajor— constantkApiMinor— constantkApiVersionString— constant
kApiMajor¶
Bumped ONLY for breaking changes to a frozen public surface, always with a migration note (policy above). 2 = the shulib v2 rebuild; the surface frozen at D2 (2026-08-12, register row F6) is API 2.0.
constant, declared at include/shulib/version.hpp:48.
kApiMinor¶
Bumped for additive extensions of a frozen surface (new verbs, new options fields, appended enumerators). Reset to 0 on a major bump. 1 = chunk F1's additive growth (2026-08-13): RoutineStopCause gains the appended MechanismFailed enumerator, then() accepts a fourth return type (manipulation::MechanismOutcome), and FaultCode appends MechanismStalled — every one the documented additive path, no frozen member changed shape. (F1 is also the change that PROVED this path works: the D2/D3 pin tests had hard-asserted kApiMinor == 0, fencing off the growth this header calls "the intended path" — a conflation fixed in those pins at F1.)
constant, declared at include/shulib/version.hpp:59.
kApiVersionString¶
"major.minor", for session headers / logs that want one printable token.
constant, declared at include/shulib/version.hpp:62.
Design commentary, from the header¶
The header opens with the reasoning behind these shapes. It is reproduced here in full because a reference that only lists signatures teaches nobody why.
The header’s own reasoning — 40 lines
The shulib API version — the mechanism behind the Freeze Register's promise.
The register (docs/roadmap.md, "Freeze Register") says a LOCKED contract
changes "only with a schemaVersion/API-version bump and a migration path".
Until D2 (2026-08-12) no such version existed anywhere in the tree; this
header is that mechanism, made inspectable in code instead of prose.
═══ The policy: what a version bump concretely IS ═══════════════════════════════
shulib is a header-only C++ library, so its API contract is SOURCE
compatibility — what user programs compile to and mean:
* BREAKING (bump kApiMajor): any change that can make a previously-
compiling user program fail to compile or silently change meaning —
removing or renaming a frozen member or type; changing a frozen
signature's parameter, return, const, ref or noexcept shape; changing
documented semantics a frozen surface carries (pre-empt, cancel's safe
state, wait-for-live, the fault policy...); re-meaning or renumbering
an existing enumerator. A major bump REQUIRES a migration note next to
the Freeze Register row: the old spelling, the new spelling, the
mechanical rewrite, and why the break was worth it.
* ADDITIVE (bump kApiMinor): every previously-valid program compiles
unchanged with unchanged behaviour — new members, new overloads, new
options-struct fields whose default preserves the old behaviour,
appended enumerators. This is the intended growth path of every frozen
surface; freezing well means never needing a major bump.
Frozen C++ surfaces are additionally enforced STRUCTURALLY: F6 carries a
compile-time signature pin (test/f6_signature_pin_test.cpp) that fails the
build, naming F6, if a frozen signature changes shape. If that pin sent
you here and the change is intended: you are making a breaking change —
update the pin, bump kApiMajor, write the migration note, and update the
register row. If the change can be re-expressed additively instead, do
that; it is almost always cheaper for everyone downstream.
The data-schema freezes (F7/F8: .vexbot sub-schemas; F9: the SHUL/2 wire
protocol) freeze DATA, not C++ source. They carry their own schemaVersion
fields inside the artifacts (designed at Phase G/H, not here) and are
governed by this same breaking-vs-additive policy.
Last updated 2026-08-15 — published from the main release branch, commit fa545ff. This site tracks releases, so between them it can lag the repository — that lag is deliberate, and it is what keeps the development log off the public site. For the current state of the code, see the repository.