docs: Faktenkorrekturen in der 4.4.0-Prosa; DEVELOPMENT.md ohne zweite Kommandobeschreibung (4.4.1-beta.1, #47)
Files changed: - CHANGES.md - DEVELOPMENT.md - VERSION - docs/version-model.md - instructions/dev/version-parts.md
This commit is contained in:
+45
-6
@@ -35,6 +35,43 @@ dev-checkout concern - readable here, never shipped as something to parse.
|
||||
|
||||
---
|
||||
|
||||
## 4.4.1-beta.1 - 2026-09-03 - Faktenkorrekturen in der 4.4.0-Prosa; DEVELOPMENT.md ohne zweite Kommandobeschreibung
|
||||
|
||||
**Author:** Torben Nehmer
|
||||
|
||||
<!-- wikitool:bumps -->
|
||||
- Faktenkorrekturen in der 4.4.0-Prosa; DEVELOPMENT.md ohne zweite Kommandobeschreibung
|
||||
<!-- /wikitool:bumps -->
|
||||
|
||||
Die Prosa zu 4.4.0 - Changelog-Eintrag, `docs/version-model.md`, `instructions/dev/version-parts.md`,
|
||||
`DEVELOPMENT.md` - entstand ungeprüft: kein maschineller Check liest sie, und die Sitzung, die sie
|
||||
schrieb, hat den dafür vorgesehenen Modellwechsel aus `stack-dev` Schritt 6 übersprungen. Ein
|
||||
nachgeholter Durchgang hat drei Fehler gefunden, von denen der erste der teuerste war.
|
||||
|
||||
**Der Befund war an einer Stelle schlicht falsch.** Changelog und `docs/version-model.md`
|
||||
behaupteten, unter dem alten Modell seien Nummern vergeben worden, die „nie ausgeliefert" wurden -
|
||||
im Changelog sogar mit einer erfundenen Zahl („fünf Minor-Bumps ... vier nie ausgeliefert"). Das
|
||||
Gegenteil stimmt: weil `release.yml` auf jede `VERSION`-Bewegung feuerte, wurde **jeder** Bump zu
|
||||
einem echten, getaggten Release. Der 2026-09-03 hat vier davon in sechs Stunden erzeugt (`4.3.0`
|
||||
bis `4.3.3`), zwei für reine Prosa-Änderungen. Der Schaden war nie ein Phantom-Release, sondern
|
||||
dass „Release" aufhörte, etwas zu bedeuten - vier Upgrades an einem Nachmittag sind für einen
|
||||
Konsumenten kein kleineres Versprechen, sondern ein unleserliches. Beide Stellen tragen jetzt den
|
||||
tatsächlichen Vorgang samt Beleg.
|
||||
|
||||
Dazu zwei kleinere Korrekturen: `version-parts.md` nannte den Stack weiterhin `2.x` (er steht bei
|
||||
`4.x`), und `DEVELOPMENT.md` trug eine Tabelle, die für jeden Verify-Befehl ein zweites Mal
|
||||
beschrieb, was er prüft - eine Kopie dessen, was `tools/CONTRACT.md` hält und `docs verify` dort
|
||||
gegen die CLI prüft. Die Tabelle ist raus; dass die Datei selbst außerhalb der von diesem Check
|
||||
abgedeckten Dokumente liegt, steht jetzt an ihrer Stelle. Der Code-seitige Teil davon - ob
|
||||
`DEVELOPMENT.md` in `docs_verify.STAGE_READMES` gehört - hängt an #47, zusammen mit der Lücke im
|
||||
Skill, die den übersprungenen Modellwechsel überhaupt erst unauffällig gemacht hat.
|
||||
|
||||
Kein Verhalten geändert, nur Prosa - und bewusst als laufender Kandidat gelassen statt fixiert:
|
||||
CIs Version-Gate verlangt die `VERSION`-Bewegung, ein Release verlangt sie nicht. Genau dafür gibt
|
||||
es das Modell aus 4.4.0.
|
||||
|
||||
---
|
||||
|
||||
## 4.4.0 - 2026-09-03 - Versionskandidat statt Bump-pro-Release: VERSION traegt -beta.N, version release fixiert
|
||||
|
||||
**Author:** Torben Nehmer
|
||||
@@ -43,12 +80,14 @@ dev-checkout concern - readable here, never shipped as something to parse.
|
||||
- Versionskandidat statt Bump-pro-Release: VERSION traegt -beta.N, version release fixiert
|
||||
<!-- /wikitool:bumps -->
|
||||
|
||||
Bisher bekam jeder `version bump` sofort eine fixierte, dauerhafte Nummer, unabhängig davon, ob
|
||||
je ein Release dazu erschien - fünf Minor-Bumps ohne Release ergaben fünf Nummern, von denen vier
|
||||
nie ausgeliefert wurden. `VERSION` trägt jetzt zwischen zwei Releases **einen** laufenden
|
||||
Kandidaten (`X.Y.Z-beta.N`) statt einer neuen Nummer pro Bump: `--major/--minor/--patch`
|
||||
eskaliert diesen Kandidaten max-wins gegen den letzten Release, statt daneben eine neue Nummer zu
|
||||
schreiben, und schrittet dabei nie zurück.
|
||||
Bisher bekam jeder `version bump` sofort eine fixierte Nummer, und weil `release.yml` auf jede
|
||||
`VERSION`-Bewegung feuert, wurde daraus sofort ein Release: Nummern entstanden in
|
||||
Commit-Granularität statt in Release-Granularität. Der 2026-09-03 hat so vier Releases in sechs
|
||||
Stunden erzeugt (`4.3.0` bis `4.3.3`), zwei davon für reine Prosa-Änderungen - alle vier echt,
|
||||
keines davon eine Einheit, an der ein Konsument sich hätte orientieren können. `VERSION` trägt
|
||||
jetzt zwischen zwei Releases **einen** laufenden Kandidaten (`X.Y.Z-beta.N`):
|
||||
`--major/--minor/--patch` eskaliert diesen Kandidaten max-wins gegen den letzten Release, statt
|
||||
eine neue Nummer danebenzustellen, und geht dabei nie zurück.
|
||||
|
||||
`Version` versteht den Suffix, mit einer expliziten Ordnung
|
||||
(`4.4.0-beta.1 < 4.4.0-beta.2 < 4.4.0`, numerisch nach `N`, nicht lexikografisch). `CHANGES.md`
|
||||
|
||||
+7
-9
@@ -71,15 +71,13 @@ eine Sitzung ihn tatsächlich durchläuft:
|
||||
lädt Tarball plus Prüfsumme hoch. **CI setzt den Tag, nie eine Sitzung** - das hält
|
||||
Invariante 5 intakt.
|
||||
|
||||
## Verify-Befehle im Überblick
|
||||
|
||||
| Befehl | Prüft |
|
||||
|---|---|
|
||||
| `cd tools && .venv/bin/python -m pytest -q` | Die gesamte Testsuite, hermetisch gegen eine leere Maschine (siehe `instructions/dev/testing-conventions.md`) |
|
||||
| `tools/wikitool docs verify` | CLI-Kommandotabelle, Contract-Präsenz, Type-Drift, `.gitignore`-Kanarienvögel, `VERSION`/`CHANGES.md`-Übereinstimmung, Grenzübertritts-Dokumentation |
|
||||
| `tools/wikitool instructions verify` | Jede Instruction und jeder Skill unter `instructions/`, verwaiste Dateien, `instructions/dev/`-Referenzen von außerhalb |
|
||||
|
||||
Die volle Kommandoreferenz inklusive Fehlerkontrakt: [tools/CONTRACT.md](tools/CONTRACT.md).
|
||||
Die drei Verify-Befehle stehen oben in Schritt 3; was jeder von ihnen prüft, steht in
|
||||
[tools/CONTRACT.md](tools/CONTRACT.md) und wird dort von `docs verify` gegen die tatsächliche
|
||||
CLI gehalten. Hier steht es bewusst **nicht** noch einmal: eine zweite Beschreibung derselben
|
||||
Befehle ist genau die Kopie, die driftet (AGENTS.md Invariante 8), und dieses Dokument liegt
|
||||
außerhalb der Dateien, die der Kommandotabellen-Check von `docs verify` abdeckt - hier fällt eine
|
||||
Drift also niemandem auf. Was `pytest` an dieser Stelle vom Entwickler erwartet, steht in
|
||||
[instructions/dev/testing-conventions.md](instructions/dev/testing-conventions.md).
|
||||
|
||||
## Die CI-Hälfte
|
||||
|
||||
|
||||
+19
-14
@@ -83,22 +83,27 @@ matter just as much in practice: how many numbers get handed out along the way t
|
||||
release. For a while the answer was "one per bump," and that turned out to be the wrong grain
|
||||
entirely.
|
||||
|
||||
The two things that actually consume a version number are a release and CI's version gate - and
|
||||
they disagree about granularity. The gate wants `VERSION` to move on every push that touches
|
||||
stack-shaped paths, which is a *commit*-level question: has this tree changed since the last
|
||||
push. A release wants to know something else: has *this specific number* been published, ever.
|
||||
Handing out a fresh number per bump answers the gate's question by accident and the release's
|
||||
question wrongly - it treats every bump as if it were about to ship, when most of them are steps
|
||||
toward a release that hasn't happened yet. Four bumps in one session, on the same day, for the
|
||||
same eventual release, produced four numbers that a version-check feed would have reported as
|
||||
four different available upgrades, three of which were never real.
|
||||
Two mechanisms decide when a number gets minted, and they answer different questions. CI's
|
||||
version gate asks a *commit*-level one: has this tree changed since the last push, and if so
|
||||
has `VERSION` moved with it. A release asks something else entirely: is this a state worth
|
||||
handing to someone, under a number they will pin against. Tying the second to the first - every
|
||||
`VERSION` move firing the release workflow - answers the gate correctly and the release question
|
||||
by accident, because it treats every bump as if it were about to ship when most bumps are steps
|
||||
toward a release that has not happened yet.
|
||||
|
||||
The failure mode is not phantom numbers; every one of those releases was real, tagged and
|
||||
downloadable. It is that "real" stopped meaning anything. On 2026-09-03 this repository cut four
|
||||
releases in six hours - `4.3.0` through `4.3.3` - for one continuous arc of work, two of them for
|
||||
prose changes alone. Someone tracking the feed saw four upgrades and had no way to tell which, if
|
||||
any, was a moment worth stopping for. A release is a promise addressed to a consumer, and a
|
||||
promise made four times an afternoon is not a smaller promise, it is a less legible one.
|
||||
|
||||
The fix is not to slow the gate down - it still wants `VERSION` to move every time, and it still
|
||||
gets that. It's to stop treating every movement as a new number. Between two releases the stack
|
||||
now carries one running candidate, escalating through `-beta.N` as bumps accumulate, and only
|
||||
`version release` spends the number for real by fixing it and closing its changelog entry. A
|
||||
number is proposed by a bump and consumed by a release; conflating the two was the actual defect,
|
||||
not the arithmetic of any single bump.
|
||||
gets that. It is to stop treating every movement as a number worth publishing. Between two
|
||||
releases the stack now carries one running candidate, escalating through `-beta.N` as bumps
|
||||
accumulate, and only `version release` spends the number for real by fixing it and closing its
|
||||
changelog entry. A number is proposed by a bump and spent by a release; conflating the two was
|
||||
the actual defect, not the arithmetic of any single bump.
|
||||
|
||||
This is also why a candidate never gets to a distributed instance. The promise a released version
|
||||
makes - "install this, and it is exactly what its number says" - has no equivalent for something
|
||||
|
||||
@@ -9,7 +9,7 @@ Two questions decide a version bump, and they are **not the same question**:
|
||||
|
||||
1. **Is the new version a drop-in replacement for the old one?** This is what the version
|
||||
number itself says. Compatibility is read off the **leftmost non-zero component** - on this
|
||||
stack (`2.x`) that is MAJOR, on a `0.x` stack it is MINOR. A bump that changes it is called
|
||||
stack (`4.x`) that is MAJOR, on a `0.x` stack it is MINOR. A bump that changes it is called
|
||||
*boundary-crossing* below, because that is the term `version bump` and `docs verify` use in
|
||||
their own messages.
|
||||
2. **Must existing content be migrated?** This is a *consequence* a boundary crossing may or
|
||||
@@ -23,11 +23,13 @@ already (see the case study at the end), which is why this file exists.
|
||||
## The candidate model
|
||||
|
||||
Between two releases the stack carries **one running candidate**, not a fresh version per
|
||||
`bump`. Five bumps with no release in between used to mean five numbers, four of which nothing
|
||||
ever consumed - the release-granularity CI's version gate wants (`VERSION` must move on every
|
||||
stack-touching push) was being paid at bump granularity instead. A candidate closes that gap
|
||||
without touching the gate: `VERSION` still moves on every bump, it just escalates the *same*
|
||||
number instead of handing out a new one.
|
||||
`bump`. Before that, every bump minted a number *and* a release: CI's version gate requires
|
||||
`VERSION` to move on every stack-touching push, and `release.yml` fires on every `VERSION`
|
||||
move, so releases were being cut at commit granularity. 2026-09-03 produced four of them in
|
||||
six hours (`4.3.0` through `4.3.3`) for one arc of work - all four real, none of them a
|
||||
meaningful unit to anyone downstream. A candidate closes that gap without touching the gate:
|
||||
`VERSION` still moves on every bump, it just escalates the *same* number instead of handing out
|
||||
a new one, and only `version release` turns it into something the release workflow acts on.
|
||||
|
||||
- **State lives in `VERSION` itself**, as an optional `-beta.N` suffix (`4.4.0-beta.3`). No
|
||||
second state file: the last release is read back out of `CHANGES.md` (the newest entry with no
|
||||
@@ -35,8 +37,8 @@ number instead of handing out a new one.
|
||||
release - derived, not stored.
|
||||
- **`--major`/`--minor`/`--patch` is max-wins escalation**, not a step you can undo. A `--patch`
|
||||
bump on a candidate already at MINOR only advances its bump count (`N`); nothing ever steps a
|
||||
candidate back down. Declaring the part is still your judgment call, made the same way section
|
||||
below describes - `escalate()` only ever raises it further.
|
||||
candidate back down. Declaring the part is still your judgment call, made the same way the
|
||||
steps below describe - `escalate()` only ever raises it further.
|
||||
- **A candidate is never released.** Pre-release is a dev-checkout state; `release.yml` only acts
|
||||
on a suffix-free `VERSION`, so a distributed instance never sees a `-beta.` version at all, and
|
||||
its parser never has to know the suffix exists.
|
||||
|
||||
Reference in New Issue
Block a user