dist upgrade: --take-release nimmt fuer einen lokal geaenderten Pfad die Release-Fassung (#107)
CI / verify (push) Successful in 45s
Release / release (push) Successful in 37s

Befund 3 aus dem getraceten 5.0.0-auf-6.0.0-Upgrade-Lauf. --keep-local behielt
die Drift und meldete sie bei jedem kuenftigen Upgrade erneut, der andere Weg
"reconcile by hand" hatte kein Werkzeug und kostete Handkopie, Vorbedingungs-
Commit und damit einen rohen git commit an Invariante 5 vorbei.

--take-release <pfad> ist wiederholbar, komponiert pro Pfad mit --keep-local,
lehnt einen nicht blockierten Pfad auch im --dry-run ab und beendet die Drift
statt sie zu uebergehen. Die Abbruchmeldung nennt jetzt alle drei Antworten mit
eingesetzter Kommandozeile und sagt, dass keine der Default ist.

Files changed:
- CHANGES.md
- VERSION
- instructions/upgrade-instance.md
- tools/CONTRACT.md
- tools/chemenu/commands/dist_cmd.py
- tools/chemenu/tests/test_dist_upgrade.py
This commit is contained in:
2026-09-16 17:35:14 +02:00
parent 0e09cf41ea
commit 72d01beef8
6 changed files with 292 additions and 38 deletions
+19 -16
View File
@@ -19,8 +19,8 @@ a clone carries an `upstream` remote pointing at the origin.
**Two things this file deliberately does not know.** First, the copy you are reading shipped
with the release this instance is *leaving*, not the one it is going to - so nothing specific to
a particular jump is written here. That belongs to the release notes (step 2) and to the
migration documents that arrive inside the tarball. Second, two steps below work around gaps in
the tooling rather than describing its intended shape; each says so, and says what makes it
migration documents that arrive inside the tarball. Second, one step below works around a gap in
the tooling rather than describing its intended shape; it says so, and says what makes it
unnecessary.
<!-- wikitool:toc -->
@@ -99,30 +99,33 @@ fresh clone ([bootstrap.md](bootstrap.md)), and not for the clone-with-upstream
| Whose file | What to do |
|---|---|
| The instance's own | Cannot appear here, which is worth knowing so a report that looks like it is read again rather than acted on: a file the instance owns either ships only as `<name>.template` (`kb/CONVENTIONS.md`, each `COLLECTION.md`, `USER.md`/`SOUL.md`/`ENVIRONMENT.md`) and is never classified at all, or is seeded once and then kept out of the write set (`.wikitool-kb.json`, `CHANGES.md`) |
| Machinery (a `CONTRACT.md`, anything under `tools/`, `types/`, `instructions/`, `AGENTS.md`, and every `<name>.template` beside an owned file) | It should not have local changes at all. Take the release's version, per the recipe below |
| Machinery (a `CONTRACT.md`, anything under `tools/`, `types/`, `instructions/`, `AGENTS.md`, and every `<name>.template` beside an owned file) | It should not have local changes at all. Take the release's version: `--take-release <path>`, one per file |
| Machinery this instance changed **on purpose** | `--keep-local` keeps every listed file untouched - but the new stamp records the release digest anyway, so the same file is reported again at every future upgrade. That is the right answer only for a difference the instance intends to carry indefinitely |
Taking the release's version has no flag today, so it is three moves - and the middle one
exists only because the repair dirties the tree that the next command requires clean:
The decision is per path, and the two flags compose - which is what a mixed report needs, one
file reset and another kept. Preview it before it writes:
```bash
tar -xzf <tarball> -C <scratch-dir>
cp <scratch-dir>/<top-level-dir>/<path> <path>
tools/wikitool publish --message "stack: revert local drift on <path>" --no-push
tools/wikitool dist upgrade <tarball> --dry-run # now 0 locally changed
tools/wikitool dist upgrade <tarball> --dry-run --take-release <path> [--take-release <path>]
```
**The commit goes through `publish`, not `git commit`** - AGENTS.md invariant 5 has no
exception for "it is only a precondition", and `--no-push` is what keeps this from being a
push nobody asked for. This whole recipe disappears the day `dist upgrade` grows a
counterpart to `--keep-local` that writes the release's version instead of aborting.
The preview marks every named path as one it would overwrite from the release, and a path that
is not actually in the locally-changed list is refused *here* rather than in the writing run.
Nothing else is needed: no copy out of the unpacked tarball by hand, and no commit made only
to satisfy the next command's clean-tree precondition. Carry the flags you settled on into
step 7.
7. **Swap the machinery.** Note the commit the instance is on first - step 13 compares against
it:
**Where `--keep-local` answers for some paths and `--take-release` for others, both go on the
same call.** Without `--keep-local`, a locally changed path that no `--take-release` names
still aborts the run: every one of them has to be answered for, and the abort's own text
names the three answers with the command line already filled in.
7. **Swap the machinery**, with whatever step 6 settled on. Note the commit the instance is on
first - step 13 compares against it:
```bash
git rev-parse --short HEAD # the pre-swap commit; keep it
tools/wikitool dist upgrade <tarball>
tools/wikitool dist upgrade <tarball> [--take-release <path>] [--keep-local]
```
It writes, and commits nothing.