tools: command records, Content migrations group - one line per cause, examples, prohibitions (#142)
CI / verify (push) Successful in 1m14s
Release / release (push) Successful in 37s

Files changed:
- CHANGES.md
- VERSION
- tools/CONTRACT.md
- tools/chemenu/commands/migrate_cmd.py
This commit is contained in:
torben committed 2026-09-26 09:26:39 +02:00
1 parent 71efdbe01b
commit 243db66134
4 files changed
+261 -79

No files matched your search

+100 -13
View File
@@ -2810,13 +2810,23 @@ List every migration document under `instructions/migrations/`.
- budget: exempt
- network: no
**EXAMPLES**
- `tools/wikitool migrate list`
**EXIT STATUS**
- 0 success
**NOTES**
Oldest target first, with its kind and obligation. Read-only and **exempt from the Iteration Budget Gate**. Never fails.
- Lists every migration document under `instructions/migrations/`, oldest target first, with its kind and obligation.
- Never fails. Read-only and **exempt from the Iteration Budget Gate**.
**SEE ALSO**
- `wikitool migrate status` - which of them this instance still owes
- `instructions/migrate-corpus.md` - how a migration is run
#### `migrate status`
@@ -2834,18 +2844,35 @@ Show the migrations this instance still owes, in the order they must run.
- budget: exempt
- network: no
**EXAMPLES**
- `tools/wikitool migrate status`
- `tools/wikitool migrate status --json`
**EXIT STATUS**
- 0 success
- 1 `.wikitool-kb.json` is missing (content version undeclared), or `VERSION` is unreadable
- 1 `.wikitool-kb.json` is missing - the content version is undeclared
- 1 `VERSION` is unreadable
**ON FAILURE**
- `.wikitool-kb.json` is missing (content version undeclared), or `VERSION` is unreadable -> For a missing declaration: run `migrate baseline <version>` once, then retry. Safe to retry freely otherwise
- `.wikitool-kb.json` is missing - the content version is undeclared -> Run `migrate baseline <version>` once, then retry
- `VERSION` is unreadable -> Fix `VERSION`, then retry
**NOTES**
Every **required** document whose `migrates_to` lies in `(kb_version, VERSION]`. `offered` documents are listed separately above the chain and never block, never count as owed, and are bounded by the applied ledger rather than by `kb_version` - taking one deliberately does not move the version, so the version cannot say whether it was taken. When a release stamp is present, also reports which shipped files this instance has since edited (from the per-file sha256 in `.wikitool-release.json`), which is what says whether an offer may be copied over or has to be reconciled by hand; without a stamp that question is reported as unanswerable rather than answered. Exits 1 only when `.wikitool-kb.json` is missing - the content's shape is a question the tool refuses to answer by guessing. Read-only and exempt from the budget gate
- Shows every **required** migration whose `migrates_to` lies in `(kb_version, VERSION]`, in the order it must run.
- `offered` migrations are listed separately above the chain: they never block, never count as owed, and are bounded by the applied ledger rather than by `kb_version` - taking one does not move the version.
- With a release stamp present, also reports which shipped files this instance has since edited (from the per-file sha256 in `.wikitool-release.json`) - which says whether an offer may be copied over or has to be reconciled by hand. Without a stamp that question is reported as unanswerable rather than answered.
- Exits 1 only when the content version is undeclared (`.wikitool-kb.json` missing) or `VERSION` is unreadable; it never guesses the content's shape.
- Read-only, safe to retry freely, and exempt from the Iteration Budget Gate.
**SEE ALSO**
- `wikitool migrate done` - records one as applied
- `instructions/migrate-corpus.md` - how a migration is run
- `instructions/upgrade-instance.md` - where an upgrade checks this
#### `migrate verify`
@@ -2863,18 +2890,40 @@ Compare `kb/` against a git revision on the invariants a content migration must
- budget: exempt
- network: no
**EXAMPLES**
- `tools/wikitool migrate verify --from HEAD`
- `tools/wikitool migrate verify --from HEAD --path kb/concepts --expect-body-change`
**EXIT STATUS**
- 0 success
- 1 Only with `--fail-on-error`: an invariant changed. Also exits 1 if `--from` is not a revision in this repository
- 1 Only with `--fail-on-error`: an invariant changed
- 1 `--from` is not a revision in this repository
**ON FAILURE**
- Only with `--fail-on-error`: an invariant changed. Also exits 1 if `--from` is not a revision in this repository -> Exit 1 from `--fail-on-error` means "act on the findings", not "the tool is broken". A finding is never fixed by re-running - it names a page and what changed on it
- Only with `--fail-on-error`: an invariant changed -> Act on the findings - exit 1 here means "act on the findings", not "the tool is broken". A finding names a page and what changed on it; it is never fixed by re-running
- `--from` is not a revision in this repository -> Fix the revision and retry
**NEVER**
- Never re-run to make a finding go away - fix the page it names.
**NOTES**
Wikilink and citation **counts** (not sets), footnote definitions, H1, structural frontmatter, and the **count of generated-region marker pairs** - a page that went from one links region to two has the same set of region names and a different count, and a lost marker turns a generated region into prose the next write appends a second one beside. Pages are matched by **title**, not path, so a page `wikitool move` (or `move --reconcile`) relocated compares as itself - reported separately as `moved` - rather than as a removed-and-added pair. Reports added/removed pages without failing on them. `--expect-body-change` additionally flags a page whose body did not change at all. Not migration-specific - worth running after any bulk rewrite, and the one question `lint` cannot answer, since it reads a single revision and so cannot see that something went missing. Read-only and exempt from the budget gate
- Compares `kb/` against the revision `--from` on the invariants a content migration must not change: wikilink and citation **counts** (not sets), footnote definitions, H1, structural frontmatter, and the **count of generated-region marker pairs**.
- Pages are matched by **title**, not path, so a page `move` (or `move --reconcile`) relocated compares as itself - reported separately as `moved` - rather than as a removed-and-added pair.
- Reports added and removed pages without failing on them.
- `--expect-body-change` additionally flags a page whose body did not change at all.
- Not migration-specific: worth running after any bulk rewrite.
- Exits 0 whatever it finds unless `--fail-on-error` is passed.
- Read-only and exempt from the Iteration Budget Gate.
**SEE ALSO**
- `instructions/migrate-corpus.md` - where a migration runs this
- `wikitool lint` - the single-revision checks
#### `migrate done`
@@ -2892,18 +2941,39 @@ Record one migration as applied, advancing `kb_version` in `.wikitool-kb.json`.
- budget: counted
- network: no
**EXAMPLES**
- `tools/wikitool migrate done 7.0.0 --pages 42 --dry-run`
- `tools/wikitool migrate done 7.0.0 --pages 42`
**EXIT STATUS**
- 0 success
- 1 Unknown version, no `.wikitool-kb.json`, nothing outstanding, or a *required* version that is not the next link in the chain
- 1 Unknown version, no `.wikitool-kb.json`, or nothing outstanding
- 1 A *required* version that is not the next link in the chain
**ON FAILURE**
- Unknown version, no `.wikitool-kb.json`, nothing outstanding, or a *required* version that is not the next link in the chain -> **Not idempotent** for a required migration: it advances the chain. For "not the next link", run `migrate status` and apply them in the order it prints - never force the order. Recording an `offered` migration *is* idempotent and safe to repeat
- Unknown version, no `.wikitool-kb.json`, or nothing outstanding -> Check `migrate status`, fix the argument, then retry once
- A *required* version that is not the next link in the chain -> Run `migrate status` and apply the migrations in the order it prints
**NEVER**
- Never force the order of required migrations.
- Never hand-edit `.wikitool-kb.json` to advance the version.
**NOTES**
**Refuses any version that is not the next link in the chain** - skipping one leaves the corpus in a shape no version describes, and an interrupted multi-step upgrade has to be resumable rather than guessable. An `offered` migration is recorded in the applied ledger *without* moving `kb_version` and with no ordering rule applied: it is not a link in the chain, so there is nothing to skip, and requiring the chain first would make an unrelated file upgrade wait on it. Re-recording one already in the ledger is a no-op, not an error
- Records one migration as applied, advancing `kb_version` in `.wikitool-kb.json` to its target.
- **Refuses any required version that is not the next link in the chain.**
- An `offered` migration is recorded in the applied ledger *without* moving `kb_version` and with no ordering rule applied. Re-recording one already in the ledger is a no-op, not an error - idempotent and safe to repeat.
- Not idempotent for a required migration: it advances the chain.
- `--dry-run` reports without writing.
**SEE ALSO**
- `wikitool migrate status` - the order to apply them in
- `instructions/migrate-corpus.md` - the migration procedure
#### `migrate baseline`
@@ -2921,18 +2991,35 @@ Declare `kb_version` once, for an instance predating `.wikitool-kb.json`.
- budget: counted
- network: no
**EXAMPLES**
- `tools/wikitool migrate baseline 6.2.0`
**EXIT STATUS**
- 0 success
- 1 Unparseable version, or a declaration already exists and `--force` was not passed
- 1 Unparseable version
- 1 A declaration already exists and `--force` was not passed
**ON FAILURE**
- Unparseable version, or a declaration already exists and `--force` was not passed -> Safe to re-run with the same version. If a declaration exists, it is almost always `migrate done` that was wanted
- Unparseable version -> Fix the version and retry
- A declaration already exists and `--force` was not passed -> It is almost always `migrate done` that was wanted
**NEVER**
- Never use `--force` to advance the version past a migration - that is `migrate done`.
**NOTES**
Refuses to overwrite an existing declaration without `--force`: advancing after a migration is `done`, which checks the chain, and this command must not become the quiet way around it
- Declares `kb_version` once, for an instance predating `.wikitool-kb.json`.
- Refuses to overwrite an existing declaration without `--force`. Advancing the version after a migration is `migrate done`, which checks the chain; this command does not.
- Safe to re-run with the same version.
**SEE ALSO**
- `wikitool migrate done` - advances the version after a migration
- `wikitool migrate status` - what is owed from the declared version
### Private instances