diff --git a/FABRIC-3.5.md b/FABRIC-3.5.md index 49163fdc..c9db8d53 100644 --- a/FABRIC-3.5.md +++ b/FABRIC-3.5.md @@ -2756,7 +2756,8 @@ be resurrected from memory. - ⬜ **Roadmap-table line added in two live places**, `FABRIC-2.md` §G cited not edited (§XXVIII.2). Folds into item 13. - ⬜ **Item 13's sweep greps by exclusion**, per §XXVIII.3's precedent. -- ⬜ **`VERSION` (engine) — one decision outstanding**, at tag time (§XXVIII.4). +- ✅ **`VERSION` (engine) — CLOSED as a rule** (§XXX.6), applied at tag time against the real + diff rather than guessed now. **Every design question is ruled and the release number is set.** What remains is execution, one engine-version call, and the close. @@ -2868,3 +2869,122 @@ stays machine-readable for the licensee and patent audiences it exists for. **The disagreement is narrow and worth stating once more so it is not mistaken for reluctance: the work is real and the tag is deserved. What is not yet earned is the word *long-term stable*, on code that will be new the day it ships.** + +--- + +## XXX. Versioning policy — CLOSED (Captain Bob ratified, 2026-09-19) + +§XXIX's recommendations accepted. This section is the closed policy, written as the text to +carry into the two live places §XXVIII.2 names. **Two items §XXIX left as open alternatives are +resolved here rather than left hanging.** + +### XXX.1 — The scheme + +| Field | Meaning | +|---|---| +| **Major** | **Odd = LTS line. Even = working line.** | +| **Minor** | Release within that line | +| **Patch** | Working builds within a release | +| **`+ci.N`** | CI build number, SemVer build metadata (§XXIX.4) — ignored in precedence | + +### XXX.2 — Conflict 1 RESOLVED: `X.5.0` semantics are retired + +The old encoding (`X.0.0` = QEMU release, `X.5.0` = hardware bare-metal release) **used the +minor field to carry a milestone meaning. That is retired** — minor now means only "release +within the line." Stated explicitly, per §XXIX.3.1, so `v2.5.0` cannot be read two ways the day +it is cut. + +**The milestones themselves survive; only their encoding changes.** They become roadmap +entries rather than arithmetic, which re-expresses the ladder cleanly: + +``` + v1.0.x — serial-only production (released, historical encoding) + v1.5.x — framebuffer VT100 console milestone (released, historical encoding) + v2.0.0 — QEMU release: three-arch QEMU story complete (released) + v2.0.1 — SER5 hardware-track line (historical; superseded by this policy) + v2.1.0 — Tripod/kernel reshuffle: Hermes into the kernel, Tripod = Hera/Artemis/Hestia + v2.2.0 — amd64 bare-metal bring-up (Beelink SER5) + v2.x — further working releases; riscv64 / aarch64 board bring-up + v3.0.0 — FIRST LTS, when and only when §XXX.5's criteria are met +``` + +**A pleasing consequence, not a contrivance:** the hardware bare-metal release that was going +to be `v2.5.0` is exactly the point where §XXX.5's first criterion (real-hardware boot) is +satisfied. **The milestone that used to be encoded in the minor field becomes the natural +candidate for the first LTS major.** The scheme and the roadmap agree without being forced to. + +### XXX.3 — Conflict 2 RESOLVED: the *line* signals breakage, not the major + +§XXIX.3.2 offered two options without recommending. **Resolved in favour of keeping the major +for LTS parity**, since that is the scheme's whole point, and relocating the compatibility +signal rather than abandoning it: + +> **Breaking changes land on the even (working) line. An odd (LTS) line takes non-breaking +> fixes only — backports, never redesigns.** + +So the major no longer means "something broke"; **the line you are on tells you whether +breakage is possible at all.** That is how odd/even schemes are meant to work, and it repairs +§XXIX.3.2's objection rather than absorbing it: a breaking change is expressible (bump the +minor on the working line), and an LTS line cannot silently acquire one (it is not allowed to). + +**Corollary worth writing down:** an LTS line that *needs* a breaking fix has failed as an LTS. +The fix goes to the working line and the next LTS picks it up. No exceptions, because the +exception is the whole failure mode this rule exists to prevent. + +### XXX.4 — Conflict 3 RESOLVED: the two version strings are independent and may coincide + +`LITHOS_VERSION` reaching `3.0.0` while `VERSION` (the engine) already sits at `3.1.0` is +**not** a collision to engineer around. `.claude/CLAUDE.md` already states they do not +auto-sync; they are separate fields in the generated `include/version.h` describing different +artifacts — the kernel and the embedded engine. + +**Ruling: state the independence in the policy text itself**, so a reader meeting two `3.x` +values does not infer a relationship that has never existed. Documentation, not renumbering. + +### XXX.5 — LTS criteria (ratified) + +A tag may take an **odd (LTS) major** only when **all five** hold: + +1. **Real-hardware boot demonstrated** on at least the amd64 reference board, logs committed as + audit artifacts — the existing acceptance standard, extended off QEMU. +2. **No known-reproducible silent-failure defect open** — §XIV's class specifically: a failure + producing no error, caught only by inspection. +3. **ACL Phase 8 closed**, or its absence explicitly scoped out of the LTS claim in writing. +4. **The `proof/` boundary restated and not contracted** relative to the prior LTS (§XXV.3). +5. **A soak** — the architecture unchanged for at least one full release cycle. **LTS follows + stability; it never announces it.** + +**The first tag meeting all five takes the odd major.** No judgement call, no debate about +whether it feels ready. + +### XXX.6 — The engine `VERSION` string: a rule, not a number + +§XXVIII.4 left it to tag time. **Closed here with a rule instead**, because the correct bump is +a function of the realised diff and the code is not written yet — picking a number now would be +guessing, and guessing is what §I.2's rollback was about. + +> **Engine `VERSION` bumps at tag time by what actually changed:** +> **major** — any FORTH-79-visible word semantics change; +> **minor** — words added, removed, or their registration relocated; +> **patch** — build-only, no dictionary-visible change. + +On the current plan this reshuffle is a **minor** bump (`3.1.0` → `3.2.0`): `BIRTH`'s +registration widens, a Hera-only suicide word is added, `PLOT`/`FB-*` registration relocates to +Hestia, the messaging layer is replaced — all dictionary-visible, none changing a FORTH-79 +word's semantics. **Confirm against the real diff at tag time; the rule decides, not this +paragraph.** + +Both strings stay hand-edited in `Makefile.starkernel`. The `bump-z`/`bump-y` targets were +removed 2026-08-15 as non-functional and must not be resurrected. + +### XXX.7 — Punch list + +- ✅ **Versioning policy — CLOSED** (§XXX). All three §XXIX.3 conflicts resolved; LTS criteria + ratified; engine `VERSION` closed as a rule. +- ✅ **This release is `2.1.0`** (§XXVIII), even major, working line. +- ⬜ **Carry §XXX.1–XXX.6 into `Makefile.starkernel` and `docs/lithosananke/ROADMAP.md`** + (§XXVIII.2), replacing the old roadmap table. `FABRIC-2.md` §G is cited, never edited. +- ⬜ Engine `VERSION` applied at tag time per §XXX.6's rule. + +**Every decision this document required is now made.** What remains is execution: the surgical +strip, the build, the Isabelle pass, the sweep, the SBOM, the merge, the tag, and the close.