• v8.0.0 2ddcd6be19

    v8.0.0
    CI / pwsh (push) Successful in 2m1s
    CI / verify (push) Successful in 5m59s
    Stable

    torben released this 2026-10-06 12:37:59 +00:00 | 2 commits to main since this release

    8.0.0 - 2026-10-06 - Installation nur aus Releases, Preflight und native Windows-Unterstützung, incoming/ als Warteschlange

    Author: Torben Nehmer

    Breaking Change:

    • Page titles must form valid, unique file names on Windows and macOS: new and rename refuse forbidden characters, reserved names (including INDEX and COLLECTION), a trailing dot or space, and titles that collide with another page by case or Unicode normalization; lint reports existing violations as hard errors - rename each affected page with tools/wikitool rename
    • publish without --no-push now exits 1 before committing when the remote is unreachable or not configured, where it used to commit locally and fail at the push - an offline session or a local-only instance must pass --no-push
    • new, rename, move and raw accept refuse a target whose path below the instance root is over 160 characters (UTF-16 code units); lint reports existing files over it as Long Paths (advisory) - rename each affected page with tools/wikitool rename, and shorten an incoming/ file name before raw accept
    • tools/wikitool now refuses to start (exit 42) until tools/preflight.sh (PowerShell 7: tools/preflight.ps1) has passed in the checkout - after updating, run it once: it checks Python, git and ripgrep, records their paths in .wikitool-tools.json and sets up tools/.venv
    • An instance is installed only from a release, into an empty folder (instructions/setup-instance.md); dist export, a clone of the origin repo and a private clone with the origin as upstream are no install paths any more, and wikitool upstream merge, upstream verify and instructions/private-instance.md are gone - an instance built one of those ways is reinstalled from a release into an empty folder and its kb/, raw/ and personal files are copied over. The preflight release asset installs into its own folder, which must be empty apart from the script and a .git, instead of creating a chemenu/ subfolder
    • A file in a subdirectory of incoming/ is no longer accepted - raw accept and raw fetch --html refuse it; a subdirectory is now one source, accepted whole with raw accept incoming/. Drop files directly into incoming/ and adjust any script that writes to incoming//; files still waiting in such a subdirectory are moved up into incoming/, or, if they belong together, accepted as one folder

    Migration: none required - No page format changes: the title and path rules only refuse names, each affected page is renamed with tools/wikitool rename, and the removed install paths touch no page

    High impact

    • wikitool: one data record per command - -h, index and CONTRACT.md render from cli_contract (Gitea #121 Phase 1)
    • dist upgrade --latest: one-command update from the release feed
    • Page titles must form valid, unique file names on Windows and macOS
    • Preflight: prerequisites checked and tool paths recorded before wikitool runs (#151, POSIX half)
    • Installation only from a release, into an empty folder; upstream merge/verify and the other install paths removed (#153)
    • incoming/ as a queue: raw pending picks the next entry, raw accept takes a whole folder

    Medium impact

    • CalDAV task-tracker provider (Nextcloud Tasks, iOS Reminders); review reports unknown-value findings instead of skipping them
    • dist export no longer cuts the dist export record out of the shipped tools/CONTRACT.md
    • fail() prints the command's ON FAILURE lines on stderr
    • Budget gate and loop-breaker refusals exit without a traceback
    • Super Productivity API path: unwrap the {ok, data} envelope, exclude the inbox project, ready-aware health (#162)
    • Live tracker suite: WIKITOOL_TASKS_CONFIG override, real-tracker tests for Super Productivity and CalDAV, nightly workflow and test image
    • Bug-report collector: tools/bugreport.py and instructions/bug-report.md
    • Bug-report collector can pseudonymise identities, in two stages
    • publish: the gate lists the staged state; a missing or unreachable remote stops before the commit
    • Path budget: a file's path stays at 160 characters or fewer so a Windows checkout works without long paths (#163)
    • PowerShell 7 preflight and launcher: tools/preflight.ps1, tools/wikitool.ps1, doctor checks for execution policy and Mark of the Web
    • Preflight as a release asset: download, verify and unpack the stack, then run the tree preflight
    • trace-hook.ps1: Copilot hooks no longer open Windows' choose-an-app dialog
    • Windows-Portabilität: Pfadtrenner, Zeilenenden, Encoding und Locks
    • INSTALL.md an die Installationsinstruktionen gekoppelt: Voraussetzungen generiert, Setup-Fragen geprüft
    • tools/bugreport: Starter für den Bugreport-Sammler, überspringt die Store-Aliase (#166)
    • publish keeps a closing trailer block of --message last, so git reads Co-Authored-By again (#149)
    • Stack-Entwicklung in drei Phasen: stack-dev (Design), stack-build, stack-close - Übergabe über den Tracker, kein Modellwechsel in der Sitzung
    • raw fetch: a sanctioned intake for a URL into incoming/
    • new: a subtype gets its own page skeleton from types/..md
    • The test suite no longer ships, and dist upgrade deletes what a release stops shipping
    • Link-Katalog: Beteiligungs- und RACI-Label von der Projektseite aus
    • Organisationsseiten: Personen als Abschnitt mit Aufstieg, entity_type organization, member-of, Lint-Befund broken_anchors
    • lint: Unfilled Template Sections - a section still holding only its template's TODO placeholders (advisory)
    • Comparison and source pages accept the sources: that cite add writes; sources may cite sources
    • raw capture / raw status / --replaces-bundle: documentation from git repositories as a bundle, with drift reporting
    • wiki-ingest: updating the captured repositories is a step-1 branch over raw status
    • export guidelines: the guideline pages as a generated GUIDELINES.md, pushed into the captured repositories behind the Guideline Push Gate
    • publish/sync merge generated files mechanically and carry non-overlapping uncommitted work through a rebase
    • publish --path nimmt ungespeicherte generierte Dateien außerhalb des Pfads mit

    Low impact

    • version bump no longer points at version release in its output
    • stack-close: wait for CI through the authenticated Gitea connection, with timings and a give-up point
    • wikitool: usage lines name wikitool, and the -h acceptance checks become tests
    • Command records, Git group: NOTES as bullets, one exit line per cause, examples and prohibitions
    • Command records, Catalog and log group: bullets, examples, prohibitions
    • Command records, Distribution and versioning group: one line per cause, examples, prohibitions
    • Command records, Pages group: one line per cause, examples, prohibitions
    • Command records, Links and citations group: one line per cause, examples, prohibitions
    • Command records, Finding and checking group: one line per cause, examples, prohibitions
    • Command records, Provenance group: examples, exit lines per cause
    • Command records, Raw material and uploads group: one line per cause, examples, prohibitions
    • Command records, Workshop runs and session budget group: examples, prohibitions
    • Command records, Types, instructions and docs group: one line per cause, examples, prohibitions
    • Command records, Telemetry group: examples, the missing --fail-on-error exit line
    • Command records, Content migrations group: one line per cause, examples, prohibitions
    • Command records, Private instances group: one line per cause, examples, prohibitions
    • Command records, Instance health group: one bullet per check, examples
    • Command records: NOTES is always a tuple of bullets; every record's examples are tested
    • network: property defined; sync, publish and upstream merge marked networked
    • log append: unreadable --body-file is an ERROR line, not a traceback
    • Command records: three more mismatches from #142 aligned to code
    • docs contract: the merged-stream test pins its own ON FAILURE line
    • gates.md and a run_budget comment name kb pages by title, not by a path that moved
    • cli.py: removed a stale duplicate help-patch line outside the typer._click fallback's try (Gitea #148)
    • new: concept/source record notes name their layout-computed subdirectory; source usage names its required fields (Gitea #150)
    • new_page/type_resolver comments no longer claim only entities declare a layout:
    • Demo corpus follows the decided project pages: three states, seed with their items (#156)
    • bug-report instruction: offer WIKI_TRACE=1 for a reproduction
    • reports/CONTRACT.md: only the collector's two counting calls take the bugreport session id
    • bug-report instruction: step 1 no longer calls every bundle unpseudonymised
    • setup-instance step 15 names --no-push for a local-only first publish; gates.md and a docstring follow #159
    • raw/CONTRACT.md points at the path budget for a name accepted from incoming/
    • preflight.ps1: the asset-mode error helper is Exit-Asset, so PSScriptAnalyzer passes
    • kb/CONTRACT.md: an external article's raw_files point under raw/, a raw fetch capture names both files
    • raw fetch --html record and kb/CONTRACT.md path budget follow the folder accept
    • stack-close no longer records which model and effort ran each phase
    • lint: a wikilink wrapped across a line break is its own finding; rename and rm see it
    • Page-material passages in type-spec.md, type-guidance.md and language-boundaries.md name subtype templates
    • kb/CONTRACT.md names section anchors in wikilinks and the Broken Anchors finding
    • kb/CONTRACT.md names unwritten scaffold sections and the Unfilled Template Sections finding
    • wiki-ingest and wiki-manage call xref add with --rel, not the --rel-a/--rel-b removed in 4.0.0
    • raw accept: an occupied folder name held by a captured bundle points at --replaces-bundle
    • kb/CONVENTIONS.md.template: the guideline filter is a default, not a setup question
    • sync record: the autostash note states the behaviour, not the change
    • raw accept --replaces-bundle: Erfolgsmeldung und Record nennen die A-Liste neben git diff

    Dieser Kandidat schneidet den Weg einer Instanz neu, vom Download bis zur Aktualisierung. Eine
    Instanz entsteht nur noch aus einem Release in einem leeren Ordner; upstream merge,
    upstream verify und die übrigen Installationswege entfallen. tools/preflight.sh bzw.
    tools/preflight.ps1 prüft Python, git und ripgrep, bevor wikitool überhaupt startet, und
    dist upgrade --latest holt und prüft das nächste Release in einem Schritt. Windows unter
    PowerShell 7 wird nativ unterstützt; dafür gelten neue Regeln für Seitentitel (gültige, eindeutige
    Dateinamen auf Windows und macOS) und ein Pfadbudget von 160 Zeichen.

    incoming/ wird zur Warteschlange: raw pending nennt den nächsten Eintrag, und raw accept
    nimmt einen Unterordner als eine Quelle. Daneben gibt es zwei neue geregelte Zugänge, raw fetch
    für eine URL und raw capture für Dokumentation aus Git-Repositories. Deren Drift berichtet
    raw status, und export guidelines spielt die Leitlinien-Seiten hinter einem neuen Gate in diese
    Repositories zurück.

    Jedes Kommando trägt jetzt einen Datensatz (cli_contract), aus dem -h, der Index und
    tools/CONTRACT.md erzeugt werden, und eine Fehlermeldung nennt die passende Reaktion gleich mit.
    Außerdem neu: ein CalDAV-Tracker neben Super Productivity und eine Live-Testsuite gegen echte
    Tracker, ein Bugreport-Sammler, ein robusteres publish (prüft den Remote vor dem Commit, führt
    generierte Dateien mechanisch zusammen) und die Aufteilung der Stack-Entwicklung in drei Phasen.

    Sechs Änderungen überschreiten die Kompatibilitätsgrenze, keine verlangt eine Content-Migration.
    Nach dem Update läuft der Preflight einmal, betroffene Seiten werden mit tools/wikitool rename
    umbenannt, eine Offline-Sitzung braucht für publish --no-push, und eine Instanz aus einem der
    entfallenen Installationswege wird einmal aus einem Release neu aufgesetzt.

    Die größeren Änderungen folgen je mit einem Absatz. Alle übrigen stehen als Stichpunkt in der Liste
    oben; die ausführliche Begründung steht im jeweils genannten Gitea-Issue.

    Installation nur aus einem Release, in einen leeren Ordner (#153, #154)

    Breaking. Von vier Installationswegen bleibt einer: Eine Instanz entsteht aus dem neuesten
    Release in einem leeren Ordner (instructions/setup-instance.md). dist export ist ein
    Build-Werkzeug, ein Klon dieses Repositorys ist Entwicklung. wikitool upstream merge,
    upstream verify und instructions/private-instance.md entfallen; das Publish-Remote-Gate bleibt.
    INSTALL.md erzählt die Schritte nicht mehr nach, und docs verify hält seine
    Voraussetzungsliste und die Setup-Fragen mit den Instruktionen im Gleichschritt. Eine Instanz aus
    einem der entfallenen Wege wird einmal aus einem Release neu aufgesetzt und übernimmt kb/,
    raw/ und die persönlichen Dateien.

    Preflight: Voraussetzungen prüfen, Werkzeugpfade festhalten, anhalten statt ausweichen (#151)

    Breaking. tools/preflight.sh (POSIX sh) und tools/preflight.ps1 (PowerShell 7) prüfen
    Python 3.11+, git und ripgrep, halten deren absolute Pfade in .wikitool-tools.json fest und legen
    tools/.venv an. Fehlt etwas, endet der Lauf mit Exit 42 und einem nummerierten Block für den
    Menschen: was fehlt, warum, welcher Befehl es behebt. Bis der Preflight bestanden ist, verweigert
    tools/wikitool jeden Aufruf mit Exit 42 - ein Agent meldet eine Lücke, statt sie zu umgehen.
    tools/wikitool.ps1 ist der Launcher für Harnesses unter PowerShell 7, doctor prüft Execution
    Policy und Mark of the Web. Jedes Release trägt beide Skripte zusätzlich als Asset: Ohne Baum
    daneben laden sie Tarball und Prüfsumme, prüfen, entpacken und starten dann den Preflight des
    Baums.

    Windows-Portabilität: Pfadtrenner, Zeilenenden, Encoding und Locks (#152, #164)

    Das Python-Paket nahm an mehreren Stellen POSIX an; unter Windows scheiterte etwa
    instructions verify an allen Instruktionen. Relative Pfade werden jetzt als POSIX-Strings
    verglichen und gespeichert, rg-Pfade normalisiert, .gitattributes hält Textdateien auf LF
    (raw/ und incoming/ bleiben byte-genau), jeder subprocess-Aufruf und die Ausgabe von
    wikitool selbst laufen in UTF-8, und die Sperren funktionieren auch unter Windows. Guards in der
    normalen Linux-CI halten das fest. Copilot öffnet unter Windows für trace-hook keinen
    „App auswählen"-Dialog mehr.

    Seitentitel als gültige, eindeutige Dateinamen auf Windows und macOS (#155)

    Breaking. Ein Titel wird eins zu eins zum Dateinamen, aber nichts prüfte, ob der Name außerhalb
    von Linux taugt (CON.md, A: B.md, ein Punkt am Ende; Foo.md neben FOO.md, NFC neben NFD).
    Die Regel steht jetzt einmal in kb/CONTRACT.md § "Titles are identifiers" und gilt auf jeder
    Plattform: new und rename verweigern verbotene Zeichen, reservierte Namen (auch INDEX und
    COLLECTION), einen Punkt oder ein Leerzeichen am Ende und Kollisionen über
    Groß-/Kleinschreibung oder Unicode-Normalisierung. lint meldet bestehende Verstöße als harte
    Fehler; Abhilfe ist tools/wikitool rename.

    Pfadbudget von 160 Zeichen (#163)

    Breaking. Windows zählt 259 Zeichen für den ganzen Pfad samt Installationsordner, und auf dem
    Zielsystem sind lange Pfade aus. Unterhalb der Instanzwurzel hat jeder Pfad jetzt ein Budget von
    160 Zeichen in UTF-16-Codeeinheiten; die andere Hälfte der Summe ist das Ordnerlimit, das doctor
    und der Preflight prüfen. new, rename, move und raw accept verweigern ein längeres Ziel,
    lint meldet bestehende Dateien als Long Paths (advisory).

    incoming/ als Warteschlange: raw pending und Ordner-Accept

    Breaking. Eine Datei in einem Unterordner von incoming/ nehmen raw accept (auch mit
    --replaces) und raw fetch --html nicht mehr an. Ein Unterordner ist jetzt eine Quelle:
    raw accept incoming/<ordner> verschiebt ihn als Ganzes mit seinen relativen Pfaden nach
    raw/<JJJJ>/<MM>/<ordner>/. raw pending nennt den ältesten wartenden Eintrag, und ein
    wiki-ingest ohne Angabe nimmt genau diesen. Wer noch nach incoming/<typ>/ schreibt, legt
    Dateien direkt in incoming/ ab.

    publish und sync: Gate auf dem gestagten Stand, Remote vor dem Commit, generierte Dateien mechanisch zusammengeführt (#159, #180, #182, #149)

    Breaking. publish ohne --no-push bricht mit Exit 1 vor dem Commit ab, wenn der Remote fehlt
    oder nicht erreichbar ist, statt lokal zu committen und am Push zu scheitern; eine
    Offline-Sitzung oder eine rein lokale Instanz übergibt --no-push. Das Mass-Update-Gate listet
    genau den Stand, den der Commit enthalten wird, statt Pfade doppelt zu zählen. reconcile hinter
    sync und publish wertet kb/index.md, kb/log.md, kb/provenance.md und die
    INDEX.md-Dateien nicht mehr als Überschneidung, führt sie mechanisch zusammen und trägt nicht
    überlappende ungespeicherte Arbeit per Autostash durch einen Rebase; vorher sichert es den
    Arbeitsbaum unter refs/wikitool/reconcile-backup. publish --path nimmt die generierten Dateien
    außerhalb des Pfads mit, und ein Trailer-Block am Ende von --message bleibt dessen letzter
    Absatz, sodass git Co-Authored-By wieder liest.

    dist upgrade --latest: Aktualisierung aus dem Release-Feed in einem Befehl (#161)

    dist upgrade --latest fragt den Release-Feed nach dem neuesten Release und beurteilt die Version
    vor jedem Download: bereits installiert ist ein Erfolg ohne Wirkung, eine ältere eine
    Verweigerung, eine Beta braucht --pre. Dann lädt es Archiv und Prüfsumme, prüft sie und übergibt
    an den unveränderten Upgrade-Pfad. dist upgrade löscht außerdem, was ein Release nicht mehr
    ausliefert - etwa die Testsuite, die jetzt im Origin-Repository bleibt, weil sie dessen eigene
    Type-Specs und Konventionen testet.

    Ein Datensatz pro Kommando (#121)

    Hilfetext, Kommandoreferenz in tools/CONTRACT.md und Budget-Ausnahmen waren vier handgepflegte
    Kopien derselben Fakten und schon auseinandergelaufen. Jedes Kommando trägt jetzt einen
    cli_contract-Datensatz - Synopsis, Eigenschaften (Wirkung, Idempotenz, Atomarität, Budget,
    Netzwerk, Gates), Exit-Status je Ursache mit Reaktion, Beispiele und Verbote -, aus dem
    wikitool <cmd> -h, der Index in wikitool -h und tools/CONTRACT.md erzeugt werden. Alle
    Datensätze wurden dabei gruppenweise überarbeitet und gegen den Code abgeglichen. Scheitert ein
    Kommando, druckt fail() die passenden ON-FAILURE-Zeilen gleich nach der ERROR-Zeile auf
    stderr; Budget-Gate und Loop-Breaker verweigern ohne Traceback.

    CalDAV-Tracker und Live-Tests gegen echte Tracker (#156, #162)

    Ein zweiter Task-Tracker-Adapter, caldav (Nextcloud Tasks, iOS Erinnerungen), implementiert
    TaskReader/TaskWriter vollständig, ohne dass sich das Provider-Protokoll ändert; review
    meldet unbekannte Werte als Befund, statt sie zu überspringen. Der erste Lauf gegen ein echtes
    Super Productivity zeigte falsche Annahmen über dessen REST-API ({ok, data}-Hülle,
    Inbox-Projekt, Health-Check), die auch die Test-Fakes trugen - behoben. Die neue
    live_tracker-Suite fährt task new/list/close und review gegen echte Tracker, nächtlich und
    mit eigenem Test-Image; WIKITOOL_TASKS_CONFIG wählt die Tracker-Konfiguration.

    Bugreport-Sammler (#157, #158, #166)

    tools/bugreport.py sammelt die erste Runde Antworten zu einem Fehler in ein Bündel, auch wenn
    wikitool selbst nicht startet: nur Standardbibliothek, Python-3.8-Syntax, und ein eigener
    Starter findet sein Python und überspringt die Store-Aliase unter Windows. --pseudonymise
    ersetzt Maschinen-, Benutzer- und Pfadnamen durch Platzhalter gleicher Form. Die Prozedur für den
    Agenten steht in instructions/bug-report.md.

    raw fetch: eine URL geregelt nach incoming/ (#120)

    Bisher baute jede Sitzung ihre eigene curl-Kette, und zwei Sitzungen machten aus demselben
    Artikel zwei verschiedene raw/-Dateien. raw fetch <url> schreibt das HTML wie empfangen und
    eine daraus abgeleitete .md mit festem Kopf (URL, Abrufzeit, Status, Zeichensatz, Titel) nach
    incoming/; raw accept übernimmt beide als ein Bündel.

    raw capture, raw status, export guidelines: Dokumentation aus Git-Repositories und zurück

    raw capture <repo-url> --ref <regel> --path <glob>... holt die gewählten Dateien eines Commits
    byte-genau als Bündel nach incoming/<name>/, mit einem _capture.json, das Repository,
    Ref-Regel und Commit festhält. raw status meldet, welche erfassten Bündel sich im Repository
    geändert haben, raw capture --update holt den neuen Stand, und raw accept --replaces-bundle
    ersetzt ein Bündel als Ganzes; wiki-ingest hat dafür einen eigenen Einstieg. Die Gegenrichtung
    ist export guidelines: Es erzeugt aus ausgewählten Seiten (Standard --tag guideline) ein
    GUIDELINES.md, und --push schreibt es in jedes erfasste Repository, das sich mit einer solchen
    Datei dafür entschieden hat - hinter dem neuen Guideline Push Gate, dem fünften Gate.

    Seitenvorlagen pro Subtyp, Organisationsseiten und Beteiligungs-Label (#117, #172)

    wikitool new nimmt für einen Subtyp die Vorlage types/<typ>.<wert>.md, wenn es sie gibt, statt
    eines Templates für alle Werte. Personen, von denen eine Quelle nur Namen und Rolle hergibt,
    stehen als Abschnitt auf der Seite ihrer Organisation (neuer entity_type: organization) und
    steigen erst mit Material zur eigenen Seite auf. Der Link-Katalog bekommt involves und die
    RACI-Label staffed-by, owned-by, consults und informs, geschrieben auf der Projektseite.

    lint: neue Befunde (#94, #172)

    lint meldet Unfilled Template Sections - Abschnitte, die nur aus den TODO-Platzhaltern
    ihrer Vorlage bestehen -, Broken Anchors für ein [[Seite#Abschnitt]] ohne diesen Abschnitt und
    Wikilinks, die über einen Zeilenumbruch laufen; rename und rm erkennen solche Links jetzt.
    Die ersten beiden sind advisory, damit der Lint einer bestehenden Instanz nach dem Upgrade nicht
    rot wird.


    This note is a snapshot of the CHANGES.md entry as it stood when the tag was cut, and
    is never edited afterwards. The maintained version of this text - including any later
    correction - is the entry for this version in CHANGES.md in the repository.

    Downloads