• v10.1.0
    CI / verify (push) Successful in 8m10s
    CI / pwsh (push) Successful in 2m46s
    Release / converters (push) Successful in 9m25s
    Release / release (push) Successful in 39s
    Release / wiki-mirror (push) Successful in 24s
    Stable

    torben released this 2026-10-16 14:43:11 +00:00 | 2 commits to main since this release

    10.1.0 - 2026-10-16 - Große PDFs und lange Quellen beim Ingest, vollständiger Export, Konverter-Tests gegen echte Dokumente

    Author: Torben Nehmer

    Medium impact

    • raw derive PDF: Gliederung mit Seite und Zeile im Kopf, Hinterlegungen, Durchstreichungen und abweichende Textfarben als Auszeichnung im Text, Bildseiten als CHECK
    • Konverter-Testkorpus und Harness ziehen in das private Repository chemenu-testfiles; neuer Workflow Converters, Freigabe-Gate im Release
    • raw derive PDF: Auszeichnungen auf ein Minimum - Struktur zuerst, ~~ ** * nur wo eindeutig, Bildseiten-CHECK nur für Inhaltsbilder
    • raw derive PDF: Kopf nennt die Bildseiten (images) und die nicht zugeordneten Seiten (unmatched); neue Anweisung read-page-images für den gezielten Blick auf diese Seiten
    • Länge als dritte Größenachse beim Ingest: raw derive und raw fetch melden einen Text über der Längenschwelle mit einer CHECK-Zeile, raw pending markiert eine lange Textdatei; ingest-large-tree liest ihn in Teilen nach der Gliederung, mit einer Faktenliste je Teil (#226)
    • wiki-query liest den Wortlaut geführt in der Rohdatei nach: über Seite, Source-Seite und Gliederung der Ableitung bis zum Zeilenbereich, nie freies Suchen in raw/; kb/CONTRACT.md präzisiert das Qualitätsziel auf die Substanz (#227)
    • export run: commit= im Marker je Seite statt je Ziel - ein Commit schreibt nur die Dateien der Seiten neu, die er berührt hat; der erste Lauf nach dem Update schreibt jede Datei einmal neu (#221)
    • wiki-ingest: ein Lauf endet nach einer Quelle mit Stopp und /clear-Empfehlung - keine Schleife über mehrere Einträge im selben Kontext; capture-session delegiert wiki-ingest nicht mehr an Subagents (#219)
    • tools/bugreport: eine nach dem Sammeln korrigierte Chronologie wird mit --bundle/--chronology in das vorhandene Bündel getauscht (gleiche Verarbeitung, kein zweiter Lauf, kein zweites Bündel); bug-report.md prüft die Chronologie vor dem Sammeln (#220)
    • Export- und Eingangsordner dürfen im Backup-Ziel neben git/ und den Maschinenordnern liegen: die Überschneidungsregel gilt nur noch für /git und den eigenen Maschinenordner, upload collect und export run weisen Ordner in oder unter Backup-/Export-Daten fremder Maschinen zur Laufzeit ab
    • Export: include "all" wählt die ganze KB, index: true schreibt index.md und INDEX.md im Ziel

    Low impact

    • instructions/dev: Konverter-Vergleich – eigene Ableitung gegen Referenzwerkzeuge am privaten Korpus, mit Grundlinie
    • instructions/dev: converter-comparison nennt harness/compare/README.md als Ort der Einrichtung
    • raw derive PDF: Durchstreichung und Textmarker lassen Programmtext aus, wie der Vertrag sagt (#231)
    • read-page-images: liest der Harness mit Subagenten, öffnet die Ingest-Sitzung die Seitenbilder gar nicht selbst, auch nicht zur Kontrolle (#234)
    • wiki-ingest step 1 sends the session to read-page-images.md before the discussion, so up to the threshold the page images are no question for the user
    • gates.md/session-setup.md: die Regel für eine neue Session-Id steht nur noch in gates.md, mit dem ausdrücklich gewünschten weiteren Ingest-Lauf als zweiter Grenze neben plan.md (#219)
    • export run/upload collect: Fehlertexte im Kommandovertrag nennen die Backup-Ordner statt backup.target und die Laufzeit-Ablehnung von Backup- und Exportdaten (#216)
    • publish-and-ci: CI-Wartezeiten auf gemessene Laufzeiten gesetzt - ein Runner, Jobs nacheinander, ca. 12 Min bis zum letzten grünen Lauf (Konverter ca. 22), Aufgeben nach 25 (35) statt 15 Min
    • publish-and-ci: hält fest, dass der Runner derzeit keine parallelen Jobs fährt, und dass die Wartezeiten neu zu messen sind, sobald er es tut
    • publish-and-ci: Wartezeit zählt ab freiem Runner, nicht ab dem Push - offene Läufe eines früheren Pushs laufen zuerst, und der Runner hält die Push-Reihenfolge nicht ein
    • Export: setup-instance und How-to nennen auch die ganze KB als Exportumfang, page_export-Docstring nennt die Index-Dateien (#217 close)

    Dieses Release macht den Ingest großer und langer Quellen belastbarer und den Export vollständiger. raw derive liest PDFs mit Gliederung, Auszeichnungen und gezielter Seitenbild-Prüfung, und die Länge ist als dritte Größenachse eingeführt, sodass lange Einzeldokumente in Teilen mit Faktenliste gelesen werden. wiki-query liest den Wortlaut geführt in der Rohdatei nach. Ein Ingest-Lauf endet nach einer Quelle. Der Export schreibt je Seite nur die betroffenen Dateien neu und kann die ganze KB samt Index-Dateien ausgeben. Die Konverter-Tests laufen gegen echte Dokumente im privaten Repository, mit Freigabe-Gate im Release.

    Konverter-Tests gegen echte Dokumente im privaten Repository

    Der Testkorpus mit echten Dokumenten (PDF, Mail, Office, ZIP) und sein Test liegen nicht mehr in diesem Repository, sondern in dem privaten torben/chemenu-testfiles, das ein Entwickler als ignoriertes testfiles/ neben den Stack klont (kein Submodul; ohne Zugriff fehlt nur dieser Lauf). Der neue Workflow Converters führt den Harness bei einem Push auf main aus, der die Konverter berührt, und auf Zuruf; release.yml führt ihn vor jedem Release ohne Suffix aus und bricht bei Rot vor dem Tag ab. Die gewöhnliche CI enthält den Test nicht mehr, die Abdeckungsgrenze hält. Eine Instanz merkt davon nichts.

    Große PDFs: Gliederung und Auszeichnungen

    Bei einem PDF schreibt raw derive die Gliederung als Feld outline in den Kopf, je Eintrag mit Ebene, Seite und der Zeile der Seitenmarke in derived.md. Im Text stehen drei Auszeichnungen als gewöhnliches Markdown für das, was die Seite nur durch ihre Form sagt: ~~…~~ für Durchstreichung, **…** für Textmarker, Fettdruck oder eine deutlich andere Textfarbe, *…* für Kursiv. Die Ableitung bestimmt erst die Struktur (Fließtext, Code, Tabellengitter, wiederkehrende Vorlagen) und zeichnet nur aus, wo die Form eindeutig ist; Fett, Kursiv und Farbe zählen nur im Fließtext. Ohne die Auszeichnungen ist der Text derselbe wie zuvor. Das Feld markings ist die Legende mit höchstens drei Zeilen, kein Tag überschreitet eine Zeile oder Seitenmarke. Der CHECK nennt nur Seiten mit inhaltlichem Bild oder Diagramm. Das Layout liest pdfminer.six, neu in requirements.txt; vorhandene derived.md bleiben unberührt.

    Lange Dokumente: Länge als dritte Größenachse (#226)

    Ein einzelnes langes Dokument mit wenigen Themen löste bisher keine der beiden Größenachsen aus und wurde in einem Zug gelesen. Jetzt melden raw derive und raw fetch jeden geschriebenen Text über der Längenschwelle (Zeichen, nicht Tokens; der Wert steht in raw derive -h) mit einer CHECK-Zeile, und raw pending markiert eine lange .md/.txt mit long: (JSON: length). ingest-large-tree liest einen solchen Text in Teilen entlang seiner Gliederung, je Teil nur dessen Zeilenbereich, und hält je Teil eine Faktenliste mit Fundstelle, Bedingung, Ausnahme und Modalität fest; die eine Source-Seite entsteht aus allen Listen, nicht aus Zusammenfassungen.

    Wortlaut geführt nachlesen (#227)

    Das Qualitätsziel in kb/CONTRACT.md gilt der Substanz, nicht dem Wortlaut: Fragt jemand, was eine Regel genau sagt, darf wiki-query die Rohdatei lesen, aber nur auf festem Weg – von der Seite über ihre Source-Seite und raw_files: zur Gliederung im Kopf der Ableitung und dort nur den Zeilenbereich des Abschnitts. raw/ wird nie durchsucht. Ohne Gliederung wird ein Text unter der Längenschwelle ganz gelesen, darüber nennt die Antwort den Weg über eine neue Ableitung. Zitiert wird in der Originalsprache mit Seitenzahl, ohne die Auszeichnungen der Ableitung; Gestrichenes heißt gestrichen. Steht die Antwort nur in der Rohdatei, benennt die Antwort die unvollständige Seite und schreibt nichts. Der MCP-Leseserver bleibt ohne Rohzugriff.


    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
  • v10.0.0
    CI / verify (push) Successful in 8m40s
    CI / pwsh (push) Successful in 2m47s
    Release / release (push) Successful in 40s
    Release / wiki-mirror (push) Successful in 27s
    Stable

    torben released this 2026-10-13 06:20:55 +00:00 | 30 commits to main since this release

    10.0.0 - 2026-10-13 - Einstellungen in drei Stufen, Eingangskanäle, raw fetch mit Site-Handlern und Login, Backup und Exporte

    Author: Torben Nehmer

    Breaking Change:

    • Die vier Dateien .wikitool-remotes.json, .wikitool-telemetry.json, .wikitool-upload.json und .wikitool-tasks.json werden nicht mehr gelesen; ein Kommando, das die Einstellung braucht, endet mit Exit 42, bis 'tools/wikitool config migrate' sie in wikitool.json, .wikitool-local.json und die Secrets-Referenzen übernommen hat
    • Die Quarantäne heißt quarantine/ statt mcp-upload/. Eine Instanz mit wartenden Einreichungen verschiebt das Verzeichnis einmal von Hand (Migrationsschritt); bis dahin enden die upload-Kommandos mit Exit 1.

    Migration: required - instructions/migrations/10.0.0-settings-tiers.md

    High impact

    • Die Einzeldateien .wikitool-remotes/-telemetry/-upload/-tasks.json sind in den drei Einstellungsstufen aufgegangen; neues Kommando config migrate
    • Eingangskanäle: der intake-Abschnitt kennt mehrere Kanäle (mcp, folder, command), alle enden in quarantine/; neues Kommando upload collect zieht Sync-Ordner und Programme in die Quarantäne

    Medium impact

    • Einstellungen in drei Stufen: wikitool.json (Instanz), .wikitool-local.json (Checkout), Secrets nur per Verweis - auch über die 1Password-CLI; neues Kommando config set
    • Site-Handler für raw fetch: Standardform der URL, Bereinigung und Hinweise pro Website als Code-Registry (learn.microsoft.com zuerst); Abschnitt sites in den Einstellungen
    • Site-Handler der Instanz als JSON-Dateien in sites/, nach denselben Bausteinen wie die des Stacks - die nun ebenfalls Datendateien sind
    • raw fetch --scope: eine Seite und die Unterseiten, die ihr Site-Handler anbietet, als ein Bündel in incoming/
    • raw fetch hinter einem Login: raw login speichert die Session des Nutzers als Secret, raw fetch holt damit; gerenderte Seiten über die optionale Browser-Komponente, externe Abrufer pro Host
    • Gesprächssprache: AGENTS.md § Conversation language legt fest, dass der Agent im Chat die KB-Sprache spricht; instructions sync schreibt den Sprachwert als generierte Zeile in jedes veröffentlichte SKILL.md, instructions verify und doctor melden eine geänderte Sprache als Drift
    • Backup in einen Sync-Ordner (OneDrive): backup init legt ein Bare-Repo unter /git als origin an, backup run und publish spiegeln die Maschinendaten nach //, doctor warnt vor .git im Sync-Ordner
    • Exporte als konfigurierte Ziele: export run schreibt eine abgeleitete, schreibgeschützte Lesefassung von kb/ je Zielordner (Markdown oder über ein Konvertierprogramm), auf Wunsch nach jedem publish; raw accept lehnt auch Dateien ab, die in einem Export-Manifest stehen

    Low impact

    • Ketten von Paketen: stack-dev schreibt ## Kette, stack-close nennt das nächste Glied
    • raw_cmd.py in ein Paket zerlegt: ein Modul je Unterkommando, Ausgabe unverändert
    • Testkorrektur: die Live-Tracker-Suite importiert, was ihr CalDAV-Anleger braucht
    • doctor: die Beschreibung der Strukturprüfung nennt sites/CONTRACT.md, die doctor seit den Site-Handlern der Instanz verlangt
    • raw fetch --scope ist die Entscheidung des Nutzers: raw/CONTRACT.md und wiki-ingest sagen, wer es anstößt und warum es kein Folgen von Links ist
    • AGENTS.md § Gates and mcp-read-server name every intake channel behind the Upload Review Gate, not only submit (#213 close)
    • publish-cycle: what a WARN or ERROR from the page export after publish means; architecture names the page export as the way out for a reader that cannot ask (#214 close)

    Dieses Release ordnet die Konfiguration neu und öffnet die Instanz nach außen. Einstellungen liegen in drei Stufen - wikitool.json für die Instanz, .wikitool-local.json für den Checkout, Secrets nur als Verweis, auch über 1Password -, und die vier alten .wikitool-*.json-Dateien sind darin aufgegangen; der Pflicht-Migrationsschritt führt config migrate aus und verschiebt mcp-upload/ nach quarantine/. raw fetch kennt Site-Handler je Website, auch als Dateien der Instanz in sites/, holt mit --scope eine Seite samt Unterseiten als Bündel und arbeitet hinter einem Login. Neue Wege hinein und hinaus: mehrere Eingangskanäle (MCP, Sync-Ordner, Programm) enden alle in der Quarantäne vor dem Upload Review Gate, backup sichert eine Instanz ohne Git-Server in einen Sync-Ordner, und export run schreibt eine schreibgeschützte Lesefassung von kb/ in konfigurierte Zielordner. Dazu spricht der Agent im Chat die KB-Sprache.

    Einstellungen in drei Stufen, Secrets nur per Verweis (#207)

    Neue Einstellungen liegen in wikitool.json (eingecheckt, gleich in jedem Klon) oder .wikitool-local.json (gitignoriert, nur dieser Checkout); jedes Feld deklariert seine Stufe, ein Wert in der falschen Datei ist ein Fehler, keine Überschreibung. Ein Feld, das ein Programm benennt oder ein Gate betrifft, ist nie instance. Secrets stehen nur als Verweis in den Dateien: {"ref": "<name>"} über WIKITOOL_SECRET_<NAME> oder eine Secret-Datei im Nutzerverzeichnis, {"ref": "op://..."} über die 1Password-CLI, die der Preflight als optionales Werkzeug erfasst; gesperrtes 1Password ergibt exit 42. config set schreibt dorthin, wo die Stufe es verlangt, und verweigert Secret-Werte; doctor zeigt eine Zeile pro Stufe, docs verify prüft wikitool.json auf Klartext-Secrets. Noch liest kein Feature seine Einstellungen so.

    Site-Handler für raw fetch (#200, #210)

    Für URLs einer bekannten Website holt raw fetch die Seite in Standardform, leitet den Text ohne Seitenbedienung ab und gibt Hinweise als CHECK-Zeilen aus, nur wenn sie zutreffen. Handler sind JSON-Dateien nach tools/chemenu/sites/site.schema.json: die des Stacks unter tools/chemenu/sites/handlers/ (zuerst learn-microsoft und learn-microsoft-powershell-module), die der Instanz unter sites/; ein Handler der Instanz mit demselben Host und Pfad ersetzt den des Stacks. doctor meldet eine unbrauchbare Datei als FAIL, und raw fetch bricht für deren Host mit Exit 1 ab, bevor etwas geholt wird. Der Header nennt site: (<name> (instance) bei der Instanz) und requested_url; das .html bleibt byte-genau. Der Abschnitt sites der Einstellungen schaltet Handler ab, wählt das Gebietsschema und nimmt Hinweiszeilen je Host-Muster auf. Regeln: sites/CONTRACT.md.

    raw fetch --scope: ein Bündel aus Index und Unterseiten

    Bietet der Site-Handler einer Seite Unterseiten an (Baustein subpages in der Handler-Datei; der Modulindex von learn.microsoft.com bietet seine Cmdlet-Seiten an), nennt raw fetch das als eine CHECK-Zeile, und raw fetch <url> --scope holt Index und Unterseiten als einen Ordner incoming/<name>/ mit einem Paar je Seite und dem Manifest _scope.json; raw accept incoming/<name> nimmt ihn unverändert an. Geholt wird nur, was der Handler benennt, nie von einem anderen Host. Vorher prüft der Befehl robots.txt und die Obergrenze sites.max_pages (Standard 200); jeder Fehler bricht ab, bevor etwas in incoming/ liegt. Zwischen den Unterseiten wartet er sites.pause_seconds (Standard 1). Ob --scope läuft, entscheidet der Nutzer: wiki-ingest fragt ihn, wenn die CHECK-Zeile es anbietet.

    raw fetch hinter einem Login (#169)

    Der Abschnitt fetch der Einstellungen ordnet einem Host einen Abrufweg zu. Bei session holt raw fetch mit der Session, die der Nutzer einmal mit raw login <host> im Browserfenster hinterlassen hat. Sie liegt als Secret außerhalb des Baums, ein Passwort wird nie gespeichert. Der Site-Handler nennt die Login-Seite und das Zeichen einer eingeloggten Seite. Fehlt die Session oder ist sie abgelaufen, endet der Abruf mit Exit 42 ohne Teaser. render: true holt über einen Browser (rendered: true). Ein anderer Weg nennt einen externen Abrufer aus .wikitool-local.json. Playwright ist optional (preflight --with browser), und doctor meldet es in der Zeile browser.

    Altlasten der Konfiguration bereinigt (#208)

    Die vier Einzeldateien .wikitool-remotes.json, .wikitool-telemetry.json, .wikitool-upload.json und .wikitool-tasks.json gibt es nicht mehr; ihre Felder sind die Abschnitte remotes, telemetry, upload, tasks, superproductivity und caldav der drei Stufen. Zugangsdaten sind dort nur noch Verweise. Der Code liest die alten Dateien nicht mehr: ein Kommando, das die Einstellung braucht, endet mit Exit 42 und nennt tools/wikitool config migrate, doctor meldet FAIL, der Telemetrie-Hook bleibt still. config migrate läuft einmal je Checkout, ist wiederholbar und lässt bei jedem Abbruch die alten Dateien unverändert. WIKITOOL_TASKS_CONFIG zeigt auf ein Profil im Format von .wikitool-local.json. Nur .wikitool-tools.json bleibt eine eigene Datei.

    Eingangskanäle: mehrere Wege in dieselbe Quarantäne (#213)

    Der Abschnitt intake in .wikitool-local.json ersetzt upload und führt benannte Kanäle mit einem Handler: mcp (das submit-Werkzeug, höchstens einer), folder (ein Ordner außerhalb der Instanz, den ein Sync-Client füllt) und command (ein Programm aus commands). Alle enden in quarantine/ (vorher mcp-upload/), jede Einreichung trägt channel, handler und origin, und upload accept bleibt das Gate. Neu ist upload collect [<kanal>...]: es zieht Ordner und Programme in die Quarantäne, entfernt eine Quelle erst, wenn die Kopie fertig ist und die Quelle noch Größe und sha256 hat, und lässt alles andere liegen. config migrate macht aus .wikitool-upload.json den Kanal mcp; wartende Einreichungen in mcp-upload/ verschiebt der Migrationsschritt von Hand, bis dahin enden die upload-Kommandos mit Exit 1.

    Backup in einen Sync-Ordner (#186)

    Ohne Git-Server bleibt der Arbeitsbaum außerhalb des Sync-Ordners; gesichert wird in das Ziel, das die Sektion backup von .wikitool-local.json nennt. backup init legt <ziel>/git als Bare-Repo an und macht es zu origin, wenn keins existiert. Mit machine_data: true spiegelt jedes publish nach dem Push .wikitool-local.json, ENVIRONMENT.md, incoming/ und die extra-Pfade nach <ziel>/<maschine>/ samt Manifest; backup run tut dasselbe von Hand. Geschrieben wird nur dort und atomar, gelesen nur innerhalb der Instanz, Secrets nie. Eine gescheiterte Sicherung nach dem Push ist eine WARN-Zeile mit Exit 0, eine fehlerhafte Sektion stoppt publish vor dem Commit. doctor meldet sync-folder und backup. Ablauf und Wiederherstellung: docs/how-to/back-up-to-a-synced-folder.md.


    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
  • v9.0.0 7cfafd75b2

    v9.0.0
    CI / verify (push) Successful in 7m45s
    CI / pwsh (push) Successful in 2m21s
    Release / release (push) Successful in 38s
    Release / wiki-mirror (push) Successful in 27s
    Stable

    torben released this 2026-10-09 15:39:33 +00:00 | 56 commits to main since this release

    9.0.0 - 2026-10-09 - Docs sorted into four areas, generated references, raw derive for real documents

    Author: Torben Nehmer

    Breaking Change: The seven pages that sat directly in docs/ now live in docs/explanation/, with nothing left at the old paths. An instance's own kb/CONVENTIONS.md still links ../docs/language-boundaries.md, so docs verify reports a dead link after the upgrade until the required migration document rewrites the path - step 12 of the upgrade.

    Migration: required - instructions/migrations/9.0.0-docs-diataxis.md

    High impact

    • docs/ sorted into tutorials, how-to, reference and explanation plus an unshipped docs/dev/; explanation pages moved, developer guide moved and translated, human docs English

    Medium impact

    • Changelog kompakt: ein Absatz pro Thema, Größenbudget, Migrationsverweis
    • docs reference: human command reference under docs/reference/, generated from the command records
    • docs reference: skill catalogue and page types under docs/reference/, generated from the shipped defaults in the origin repo only
    • docs/: how-to guides, configuration reference and two explanation pages carved out of README.md, INSTALL.md, INSTALL-MCP.md and EVALS.md; the last two retired
    • INSTALL.md is an English installation tutorial; new tutorial from a first source to a first answer with a shipped sample; README.md a landing page
    • Die Formen der vier handgeschriebenen .wikitool-*.json stehen je in einem Datensatz (config_shapes), aus dem Lader, doctor und die Konfigurationsreferenz lesen
    • Gate-Liste: AGENTS.md § Gates ist die eine Liste (mit Rebase-Review Gate), cli_contract.GATES hält sie, docs verify vergleicht beide
    • Asset-Preflight: Verschieben aus dem Entpackordner wird bis ca. 30 s wiederholt, nennt die Systemmeldung und rollt nach endgültigem Scheitern zurück
    • raw derive reads PDF-free documents: Office files and mail become a folder with the original and a derived text
    • raw derive unpacks ZIP archives and mails with attachments into a folder
    • raw derive reads PDF and Outlook MSG through lazily imported packages; doctor shows each import filter
    • raw derive (Mail): ein Platzhalter-Plaintext (unter 10 % des HTML-Texts) verdrängt den HTML-Text nicht mehr, und die zweite Fassung des Mailtexts wird kein Anhang (#204)

    Low impact

    • version bump: Abschlussmeldung nennt Stichpunkt oder Themenabsatz statt pauschal Prosa
    • AGENTS.md routing line and a toc.py docstring describe docs/ as the whole human documentation
    • tools/README.md module tree names reference_doc.py and the fourth view cli_contract renders
    • Rebase-Review Gate: Anzeigename in Hilfe- und Fehlertexten von sync und publish angeglichen
    • tools/README.md: Asset-Modus beschreibt Entpacken in den eigenen Ordner, Wiederholung und Zurückrollen
    • Gitea-Wiki als generierter Spiegel von docs/: Konverter, Push-Skript, Workflows
    • raw pending names only the raw fetch pair as a bundle; a derived document is a folder
    • raw derive writes an Excel file's sheets as tab-separated files with a formula list; derived.md becomes the overview (#202)
    • testfiles: real documents get short names and a source table, personal data is replaced by same-length filler, and the derive test now compares the sheet TSVs (#203)

    This release reorganises the stack's human documentation and teaches raw derive real-world documents. docs/ is now sorted into tutorials, how-to guides, reference and explanation, with the developer guide in an unshipped docs/dev/; the command, skill and page-type references are generated from the shipped records, the root documents shrink to a landing page and an English installation tutorial, and docs/ is mirrored into the Gitea wiki. The explanation pages moved, so an instance runs the required migration document to repair the one path its kb/CONVENTIONS.md links. raw derive now turns Office files, mail with attachments, ZIP archives, PDF, Outlook MSG and Excel sheets into a folder with the original and a derived text. Smaller changes: the shapes of the four hand-written .wikitool-*.json files live in one record, AGENTS.md § Gates is the single gate list, and the asset preflight retries a blocked move.

    Tutorials: installation in English, and a first source to a first answer (#191)

    INSTALL.md stays at the root and is now the English installation tutorial, the first one docs/tutorials/README.md lists; its generated prerequisites lists and setup-question markers are unchanged, and docs verify's finding for a missing question names the English section "What the agent asks you". The new docs/tutorials/first-source-to-first-answer.md walks a fresh instance through one ingest and two questions, one the wiki answers with citations and one it has no source for, using docs/tutorials/sample-source.md, a short made-up note that ships with every instance. README.md's "Your first ingestion" is a link to it, which finishes README.md as a landing page.

    The root documents split into docs/ pages (#190)

    The task and explanation parts of README.md, INSTALL.md, INSTALL-MCP.md and EVALS.md are now single English pages: eleven how-to guides under docs/how-to/ (ingest, capture, guideline export, query, maintenance, weekly review, Obsidian, updating an instance, troubleshooting, the MCP read server, tracing and scoring sessions), docs/reference/configuration.md, and docs/explanation/architecture.md and telemetry-and-evaluation.md. A guide says what to prepare, what to tell the agent and where it stops; it links an agent's procedure instead of retelling it. INSTALL-MCP.md and EVALS.md are gone from the root and from dist export, so an upgrade removes them as retired; README.md is a landing page, and INSTALL.md keeps only the installation itself. Pointers in messages and command records, among them version check's, name the new pages.

    Doku-Gerüst nach Diátaxis unter docs/ (#187)

    docs/ hat vier Bereiche – tutorials/, how-to/, reference/, explanation/, je mit einer
    README.md – und docs/dev/, das dist export wie instructions/dev/ weglässt. Die sieben
    Erklärseiten liegen jetzt unter docs/explanation/, ohne Stub am alten Ort; DEVELOPMENT.md ist
    als docs/dev/development.md englisch. docs verify meldet jede Datei, die direkt in docs/ oder
    außerhalb der fünf Bereiche liegt. AGENTS.md § File naming legt fest, dass die menschliche Doku
    des Stacks englisch ist, unabhängig von language:. Das bestehende kb/CONVENTIONS.md einer
    Instanz verlinkt noch den alten Pfad, deshalb führt das Pflicht-Migrationsdokument ihn nach.

    Changelog-Einträge mit Größenbudget und Migrationsverweis (#184)

    Ein Eintrag bekommt ###-Abschnitte pro Thema statt pro Bump; eine kleinere Änderung steht nur
    als Bump-Titel in der Liste. docs verify und version release halten den obersten Eintrag bei
    höchstens 32 000 Bytes und jeden ###-Abschnitt bei genau einem Absatz von höchstens 1 000 Bytes,
    die Überschrift nicht mitgezählt; ältere Einträge bleiben ungeprüft. Zielt ein erforderliches
    Migrationsdokument auf die Basis des Kandidaten, schreibt jeder version bump die Zeile
    **Migration:** required - <pfad> anstelle von none required, und docs verify meldet einen
    grenzüberschreitenden Eintrag, der sein Dokument nicht nennt. Die Formregeln stehen nur noch in
    instructions/dev/version-parts.md.

    Generierte Referenz für Menschen unter docs/reference/ (#188, #189, #193)

    wikitool docs reference [--apply] erzeugt aus den Kommando-Datensätzen eine Seite je Gruppe samt
    Übersicht und exit-codes.md, ohne die an Agenten gerichteten Reaktionen. skills.md und
    page-types.md beschreiben die ausgelieferten Vorgaben und entstehen nur im Ursprungs-Repo. Die
    Formen von .wikitool-telemetry.json, -remotes, -upload und -tasks stehen je in einem
    Datensatz in config_shapes.py; die Lader lesen daraus Felder, Defaults und Expected:-Texte bei
    unveränderter Akzeptanz, und configuration.md trägt je Datei eine generierte Region, auch in einer
    Instanz. doctor warnt bei einer Telemetrie-Datei, die still anders gelesen wird. docs verify
    meldet veraltete Regionen.


    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
  • v8.0.0 2ddcd6be19

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

    torben released this 2026-10-06 12:37:59 +00:00 | 85 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
  • v7.0.0 4446424e01

    v7.0.0
    CI / verify (push) Successful in 58s
    Release / release (push) Successful in 38s
    Stable

    torben released this 2026-09-22 20:56:08 +00:00 | 186 commits to main since this release

    7.0.0 - 2026-09-22 - Task-Tracker-Anbindung: Vorhaben als Seitenart, Verpflichtungsschicht, Weekly Review als Read-Time-Join

    Author: Torben Nehmer

    Breaking Change:

    • docs verify now requires an adopted project type-spec (schema requiring state:) and its kb/gtd/ collection - an instance must adopt types/project.md(.schema.yaml) and kb/gtd/COLLECTION.md from their .template before docs verify passes again
    • superproductivity's provider section in .wikitool-tasks.json now requires 'access' ('api' or 'snapshot'), no default and no fallback between the two; 'db_path' no longer exists at all. An existing config must add 'access' and, if it used 'db_path', switch to 'backups_dir' (see INSTALL.md's example).

    Migration: none required - No kb/ page content changes - the break is confined to .wikitool-tasks.json, an instance-owned, gitignored file every operator already edits by hand per INSTALL.md's example.

    High impact

    • SP-Zugriffsweg explizit (access: api/snapshot, #133) und follow_up_at-Korrektur (dueWithTime/dueDay, #135)

    Medium impact

    • Typ project und Collection kb/gtd/: das Vorhaben als eigene Seitenart
    • Task-tracker provider layer, with a Super Productivity adapter
    • wikitool review: the weekly GTD review as a read-time join
    • wikitool new project: Seite und Tracker-Projekt unter einem Namen
    • Skill weekly-review: turning wikitool review's findings into decisions
    • Doku-Nachzug zu #119: die Verpflichtungsschicht erreicht Installation, Setup und docs/
    • task new: einen zweiten Schreibweg in den Tracker (ein Posten, keine Seite)
    • wiki-ingest: raw accept rückt hinter die Verpflichtungsentscheidung
    • Weekly review proposes task new/task close; tracker gains a closing write path

    Low impact

    • new project: Testabdeckung fuer die required-responsibility-Ablehnung
    • docs/-Nachzug: Exit 42 als Haltung, und die Adoption eines neu ausgelieferten Templates
    • Skill-Namensfamilien: weekly-review -> gtd-weekly-review, dritte Person in allen Descriptions
    • Veraltete Skill-Aufzaehlungen in der Instruction-Schicht nachgezogen
    • gtd-weekly-review: task new nachgezogen, veralteter Begründungszeiger korrigiert
    • instructions/CONTRACT.md drops other files' step counts from the copy-in-checklist rationale

    Dieser Kandidat bringt die Verpflichtungsschicht in den Stack: ein neuer Seitentyp project und
    die Collection kb/gtd/ geben dem Vorhaben (Ziel, Beteiligte, dauerhafter Status) eine eigene
    Seitenart neben dem Artefakt; eine Task-Tracker-Provider-Schicht (chemenu.tasks) verbindet das
    mit einem echten Tracker, mit Super Productivity als erstem Adapter; wikitool review liest beide
    Seiten zur Laufzeit zusammen statt sie zu synchronisieren, und das neue Skill
    gtd-weekly-review macht dessen Funde zu Entscheidungen. Der Tracker bekommt zwei neue
    Schreibwege dazu (task new, task close) neben den bestehenden Lesekommandos, und wiki-ingest
    stellt seither bei jeder Quelle die Verpflichtungsfrage in beide Richtungen. Zwei
    Grenzübertritte kommen mit: docs verify verlangt jetzt den adoptierten Typ project und die
    Collection kb/gtd/, und .wikitool-tasks.jsons Provider-Abschnitt verlangt ein explizites
    access (api/snapshot) ohne Fallback auf db_path. Der Rest der Bumps sind Nacharbeiten und
    kleinere Korrekturen an genau dieser Naht - Doku-Nachzug, Namensfamilien, eine korrigierte
    Zurückweisungs-Meldung, und die hier laufende Bereinigung veralteter Schrittzahlen in der
    Instruction-Schicht.

    Typ project und Collection kb/gtd/: das Vorhaben als eigene Seitenart

    Gitea #119 (Paket #123): ein neuer Seitentyp project fuer das Vorhaben - Ziel, Beteiligte,
    dauerhafter Status, offene Schleifen - abgegrenzt gegen das Artefakt (entity/codebase, seit
    6.2.0). types/project.md/.schema.yaml und die neue Collection kb/gtd/ (Bereiche haus/,
    finanzen/, technik/ ueber responsibility:) folgen exakt dem Muster, das entity/concept/
    source/comparison schon vorgeben - kein Code noetig fuer wikitool new project, types list
    oder den Template-Versand, alles daran ist bereits generisch.

    Neu ist nur eine Zeile Code: project tritt neben source in
    kb_collections.STACK_REQUIRED_TYPES, nach demselben "fordern statt besitzen"-Idiom (D16) - ein
    Type-Spec name: project, dessen Schema state: fuehrt, muss existieren, weil der
    Wochenrueckblick (#125) sonst nichts hat, wogegen er ein Tracker-Projekt abgleichen kann. Das
    macht docs verify zum Grenzuebertritt (siehe Breaking Change oben): eine Instanz, die die
    neue tools/-Fassung uebernimmt, ohne types/project.md.template und
    kb/gtd/COLLECTION.md.template zu adoptieren, faellt fortan durch, wo sie vorher bestand. Dabei
    aufgefallen und mitkorrigiert: kb_collections.declaration_issues()s Meldung fuer eine fehlende
    Pflicht-Collection nannte immer source, unabhaengig davon, welcher Typ tatsaechlich fehlte -
    jetzt benennt sie den Typ, den stack_required_collection_owners() tatsaechlich dafuer
    verantwortlich macht. kb/entities/COLLECTION.md traegt jetzt einen gtd:-Block (vorerst nur
    see-also), ohne den keine Kante von einer Entity auf ein Vorhaben autorisierbar waere - das ist
    der Block, auf den #118 wartet.

    Task-tracker provider layer, with a Super Productivity adapter

    Gitea #119 (Paket #124): die Schicht, ueber die wikitool an einen Aufgaben-Tracker kommt -
    ohne dass eine Instruction je erfaehrt, welcher es ist (D25). chemenu.tasks.protocol deklariert
    TaskReader/TaskWriter als getrennte Protocols, chemenu.tasks.superproductivity implementiert
    beide gegen Super Productivity, .wikitool-tasks.json (chemenu.tasks.config) traegt Provider,
    Verbindungsangaben und die drei Schwellwerte des Wochenrueckblicks (#125). wikitool doctor
    berichtet den konfigurierten Provider, seinen Lesepfad-Status und ob seine lokale REST-API
    antwortet - read-only, FAILt nur auf eine kaputte Konfiguration, nie auf einen nicht laufenden
    Tracker. Kein Kommando entsteht hier (#124s eigene Abgrenzung) - das ist #125/#126.

    Zwei Zwischenbefunde aus der Umsetzung, gegen den tatsaechlichen Quellcode von
    super-productivity/super-productivity (master, 2026-09-19) verifiziert:

    • Der Lesepfad liest keine db.json - die gibt es auf dem Desktop nicht, der Live-Zustand
      liegt in IndexedDB. Gelesen wird die neueste Datei unter dessen periodischen
      Dateisystem-Backups (electron/backup.ts, <userData>/backups/<timestamp>.json), deren
      Inhalt exakt die verifizierte Form hat.
    • Die lokale REST-API kann keine Projekte anlegen - GET /projects existiert,
      POST /projects nicht (electron/local-rest-api-handler.service.ts). Damit entfaellt fuer
      diesen Provider der in #119 D31 vorgesehene automatische Schreibpfad; create_project prueft
      weiterhin die Namenskollision (D8), verlangt dann aber menschliches Eingreifen statt es zu
      simulieren: SuperProductivityWriter.create_project wirft ein neues
      chemenu.errors.HumanInterventionRequired mit Anweisungen fuer den Menschen und einem
      verify(), das den Lesepfad danach erneut befragt statt der Bestaetigung einfach zu glauben.
      Dieselbe Klasse haengt sich an den bestehenden EXIT_NEEDS_CLEARANCE-Code (42) - keine neue
      benannte Gate, aber dieselbe Haltung: dem Menschen die Ausgabe zeigen und anhalten, statt eine
      Umgehung zu erfinden. Die CLI-seitige Uebersetzung (needs_clearance) folgt mit dem Kommando
      in #126; #124 liefert nur die Bibliotheksseite. #119s Umsetzungstabelle und #124s eigener
      Akzeptanzkriterien-Absatz sind entsprechend nachgezogen.

    Ausserdem verifiziert, ohne Designfolgen: Super Productivitys Someday/Maybe-Aequivalent ist der
    bestehende backlogTaskIds-Puffer je Projekt, keine eigene Tag-Konvention.

    wikitool review: the weekly GTD review as a read-time join

    Gitea #119 (Paket #125): das tragende Bauteil - wikitool review joint die Tracker-Seite
    (chemenu.tasks, #124) und die kb/gtd/-Projektseiten ueber den case-normalisierten Namen und
    gibt einen Bericht aus. Es speichert nichts, nicht einmal eine reports/-Datei (D3) - search
    ist das naechste Vorbild dafuer, und review ist deshalb genauso vom Iterationsbudget
    ausgenommen.

    Fuenf Pruefungen (#119 D10/D26), alle in chemenu.review.run_review: stalled (Tracker-
    Projekt ohne offene Posten, kb/-Seite state: active - dormant/completed/abandoned
    melden nie, D27), waiting_overdue (follow_up_at aelter als stalled_waiting_days),
    unpaged_project (Tracker-Projekt ohne kb/-Seite, aelter als unpaged_project_weeks),
    no_open_loop (kb/-Seite active, aber kein Tracker-Projekt dieses Namens oder keine
    offenen Posten - die Gegenrichtung des vorigen Abgleichs, D8s beidseitiger unmatched-Bericht),
    someday_stale (Someday-Posten seit someday_stale_months unveraendert, ueber Kalendermonate
    gerechnet statt ueber Tage / 30). Ein Tracker-Projekt ohne offene Posten mit aktiver kb/-Seite
    erfuellt zugleich stalled und no_open_loop - beide melden, das ist keine Dopplung, sondern zwei
    verschiedene Aussagen ueber denselben Zustand.

    Jeder Providerzugriff ist einzeln abgesichert: scheitert projects(), entfallen die vier darauf
    aufbauenden Pruefungen; scheitert someday_items(), entfaellt nur die fuenfte; scheitert
    open_items() fuer ein einzelnes Tracker-Projekt, faellt nur dieses eine aus den betroffenen
    Pruefungen heraus, der Rest laeuft weiter. Ein so unvollstaendiger Bericht setzt complete auf
    false, druckt trotzdem alles, was noch entschieden werden konnte, und die CLI beendet sich mit
    Exit 1 - nie mit einem leisen Teilbericht, der wie eine ruhige Woche aussieht. Fehlt
    .wikitool-tasks.json ganz, oder ist es kaputt, scheitert der Aufruf sofort und sagt das - das
    ist ein Konfigurationsfehler, kein Erreichbarkeitsproblem, und braucht deshalb keinen Teilbericht.

    --json traegt dieselben Befunde maschinenlesbar (findings/checks_run/checks_skipped/
    kb_project_count/complete); ein Test haelt beide Formen gegeneinander, wie es
    test_mcp_server.py fuer den MCP-Lesepfad gegen die CLI tut.

    wikitool new project: Seite und Tracker-Projekt unter einem Namen

    Gitea #119 (Paket #126): wikitool new project --name X --set responsibility=Y legt jetzt, wenn
    .wikitool-tasks.json einen Tracker konfiguriert, zusaetzlich ein gleichnamiges Tracker-Projekt
    an - ein Geburtsort, ein Name (D8/D31). Tracker vor Seite: erst steht die Tracker-Seite fest,
    erst danach wird die kb/-Seite geschrieben, damit ein Fehlschlag zwischen beiden immer im
    selben, bereits bekannten Zustand landet - "Tracker-Projekt ohne Seite", das reviews Pruefung 3
    ohnehin meldet - nie im unbekannten "Seite ohne Tracker-Projekt". Ist kein Tracker konfiguriert,
    bleibt es bei der reinen Seitenanlage, jetzt aber ausdruecklich als solche vermerkt statt
    stillschweigend.

    chemenu.tasks.build_reader/build_writer (neu in chemenu/tasks/__init__.py) sind die eine
    Dispatch-Tabelle von TasksConfig.provider auf einen konkreten Adapter, jetzt von review.py
    und new_page.py geteilt statt zweimal derselben if cfg.provider == "superproductivity".

    Fuer einen Provider ohne Schreibpfad (Super Productivity, #124: keine POST /projects) wirft
    create_project chemenu.errors.HumanInterventionRequired - das Kommando zeigt die Anweisung
    und beendet sich mit Exit 42, ohne irgendetwas anzulegen. Die offene Frage aus #126s eigenem
    Issue-Text war, wie ein zustandsloser CLI-Prozess bei einem erneuten Aufruf eine echte
    Namenskollision von "der Mensch hat gerade getan, worum genau dieses Kommando gebeten hat"
    unterscheidet - beides sieht am Lesepfad identisch aus (Tracker hat den Namen, kb/ noch keine
    Seite). Entschieden (mit dem Betreiber, nicht allein): ein explizites --resume, das ein Treffer
    im Tracker als bestaetigte Fortsetzung liest statt als Kollision - ohne --resume bleibt jeder
    Treffer eine Ablehnung samt Fundort, auch bei einem Wiederholungsaufruf. --resume ohne einen
    tatsaechlich fehlenden Tracker-Eintrag wirft dieselbe HumanInterventionRequired-Meldung erneut,
    keine stille Weiterarbeit auf Zuruf. --resume bei jedem anderen Typ wird abgelehnt.

    Ein erzwungener Fehlschlag der eigentlichen Seiten-Schreibaktion (Schritt 3) nach bereits
    bestaetigtem Tracker-Projekt ist eigens getestet: die Meldung nennt, dass die Tracker-Seite schon
    steht und nur die kb/-Seite fehlt, nie umgekehrt.

    new project: Testabdeckung fuer die required-responsibility-Ablehnung

    Gitea #119 (Paket #126s eigenes AC): --responsibility ist Pflicht und ein Wert ausserhalb des
    Enums wird abgelehnt - beides galt schon vorher generisch ueber types/project.schema.yamls
    required:/enum: (#123), ohne dass #126 dafuer neuen Code brauchte. Nachgetragen: ein Test,
    der das fuer den fehlenden Fall (--set responsibility=... ganz weggelassen) tatsaechlich belegt,
    statt es nur zu behaupten.

    Skill weekly-review: turning wikitool review's findings into decisions

    Gitea #119 (Paket #127): instructions/weekly-review/SKILL.md, publiziert nach .agents/skills/
    und .claude/skills/. wikitool review liefert fuenf Befunde (#125); dieser Skill fuehrt das
    Gespraech, das aus jedem eine Entscheidung macht - je Befund mindestens zwei Handlungsoptionen und
    ein Unterscheidungsmerkmal, wie in #127s Akzeptanzkriterien gefordert.

    Der Skill nennt bewusst keinen Provider, keine Datei- und keine API-Form (D25) - eine neue
    Regressionstest (test_weekly_review_skill_names_no_provider) haelt das am echten Repo-Inhalt
    fest, nicht nur als Review-Behauptung. Erinnert im Text an D28 (Personen in ## Beteiligte
    bleiben Erwaehnung, bekommen keine Seite) und D7 (die Seite fasst die Aufgabenliste nie
    zusammen). Die Kommandoflaeche bleibt bei review/new project; alles Aufgabenbezogene - eine
    naechste Aktion anlegen, follow_up_at verschieben, einen Someday-Eintrag streichen - bleibt eine
    Handlung im Tracker selbst, weil dafuer kein wikitool-Kommando existiert (D31).

    Doku-Nachzug zu #119: die Verpflichtungsschicht erreicht Installation, Setup und docs/

    Gitea #119, nach Abschluss von #122-#127: die sechs Umsetzungspakete haben ihre Vertragszeilen
    jeweils mitgebracht (tools/CONTRACT.md, kb/CONTRACT.md), aber drei Flaechen blieben zurueck,
    die kein Paket fuer sich allein besass - und keine davon faellt bei docs verify auf, weil dort
    keine Zeile fehlt, sondern Prosa.

    • INSTALL.md § Konfiguration kannte .wikitool-tasks.json nicht. Die Datei stand in
      tools/CONTRACT.mds doctor-Zeile und in reviews Fehlerkontrakt, also dort, wo ein Agent
      nachschlaegt - nur nicht dort, wo ein Mensch die Form nachschlaegt. Sie steht jetzt neben
      .wikitool-telemetry.json und .wikitool-remotes.json, mit vollstaendigem Beispiel, den drei
      Schwellwerten als Konfiguration statt Schema, und dem fuer Super Productivity getrennten
      Lese-/Schreibpfad. Die doctor-Beschreibung unter § Verifikation nennt den Tracker jetzt mit.
    • setup-instance.md bot den Tracker nie an. Eine neue Instanz bekam Typ und Collection ueber
      die generische Template-Adoption (Schritt 5), aber nichts fragte nach der anderen Haelfte des
      Rueckblicks. Neuer Entscheidungspunkt (Schritt 11, parallel zur Telemetrie): einmal fragen,
      .wikitool-tasks.json anlegen oder nichts tun - kein Tracker ist ein gueltiger Endzustand. Die
      Form steht nicht hier, sondern in INSTALL.md (Invariante 8). Folgenummern 12-16 nachgezogen,
      Skill-Liste um weekly-review ergaenzt.
    • upgrade-instance.md hatte keinen Pfad fuer ein neu ausgeliefertes .template. Genau der
      Fall, den 7.0.0 erzwingt: Schritt 5 sagte „new braucht keine Entscheidung", und die
      Schritt-6-Tabelle sagt, instanzeigene Dateien koennten dort gar nicht auftauchen - beides
      richtig und zusammen irrefuehrend, weil ein neues types/<name>.md.template fuer einen
      geforderten Typ sehr wohl eine Handlung braucht. Schritt 5 benennt diese eine Ausnahme jetzt,
      Schritt 9 traegt die Reparatur neben der TOC-Reparatur: die gewoehnliche Adoption, mit den zwei
      cp-Zeilen, ausdruecklich keine Datenmigration.

    Dazu die Begruendung selbst: docs/knowledge-and-commitment.md ist neu und haelt fest, warum
    Wissen und Verpflichtung zwei Schichten sind (verschiedene Halbwertszeiten), warum nicht
    synchronisiert wird (Muster 4, mit den drei verworfenen Anordnungen), warum der Join zur Lesezeit
    passiert und nichts speichert, warum ein Name die Pflichten eines Identifiers erbt, warum eine
    Seite ihre Aufgabenliste nie zusammenfasst, warum Archivierung ein state:-Wert ist, und warum
    keine Instruction je den Provider nennt. Das stand bisher ausschliesslich in Gitea #119 - und ein
    Issue ist genau das, was dist export nicht mitliefert: eine ausgelieferte Instanz bekam den
    Mechanismus ohne das Warum. AGENTS.md § File naming zaehlt jetzt sechs statt fuenf von dort
    verlinkte docs/-Seiten.

    tools/README.md § Layout fuehrt review.py und das Paket tasks/; und
    instructions/dev/doc-pull-through.md bekommt die zwei Zeilen, deren Fehlen dieser Nachzug ist:
    eine fuer eine instanzeigene Konfigurationsdatei (INSTALL.md § Konfiguration + der
    setup-instance-Entscheidungspunkt + doctors Vertragszeile), eine fuer einen neuen geforderten
    Seitentyp oder eine neue Collection (Type-Spec/COLLECTION.md + kb/CONTRACT.md + beide
    Adoptionspfade). Die Zeile zur docs/-Begruendung sagt jetzt zusaetzlich, dass eine Entscheidung
    ohne Seite die eigentliche Luecke ist, weil Begruendungen aus einem Issue nie ausgeliefert werden.

    docs/-Nachzug: Exit 42 als Haltung, und die Adoption eines neu ausgelieferten Templates

    Die Abschlusspruefung dieses Kandidaten (stack-close Schritt 3) hat zwei docs/-Seiten gefunden,
    deren Begruendung die Pakete #124/#126 bzw. #123 verschoben hatten, ohne dass jemand sie nachzog -
    beide unpruefbar, weil eine docs/-Seite per Konstruktion keinen normativen Satz traegt.

    • docs/why-gates-are-code.md kannte Exit 42 nur als Gate. Die Seite oeffnet mit „vier harte
      Grenzen", und seit #124/#126 verlaesst HumanInterventionRequired denselben Code, ohne eine
      fuenfte Gate zu sein. Neuer Abschnitt „Exit 42 is a posture, and it outgrew the gates": die vier
      Gates teilen eine Weigerung (die Operation waere moeglich, das Werkzeug fuehrt sie
      unbesehen nicht aus), der neue Fall ist das Gegenteil (die Operation ist gar nicht moeglich, kein
      Token koennte das aendern) - gemeinsam ist beiden nur, was der Exit-Code tatsaechlich sagt:
      anhalten, einem Menschen zeigen, nichts umgehen. Dazu die verworfene Alternative, die Luecke in
      der Instruction-Schicht zu beschreiben - genau die Prosa-Regel, gegen die diese Seite argumentiert.
    • docs/ownership-and-templates.md beschrieb die .template-Kategorie nur von innen. „Wird
      von einem Upgrade nie geschrieben" stimmt weiterhin fuer eine bereits adoptierte Datei; der Fall,
      dass ein Release ein Template fuer einen Typ liefert, den die Instanz noch gar nicht hat, stand
      nirgends - und genau der ist seit #123 der Grenzuebertritt. Die Kategorie nennt ihn jetzt als die
      eine Gestalt, in der „das Upgrade schreibt diese Datei nie" zu Arbeit wird, mit Verweis auf den
      Schritt in upgrade-instance.md, den Stack 7.0.0-beta.7 dort angelegt hat.

    Skill-Namensfamilien: weekly-review -> gtd-weekly-review, dritte Person in allen Descriptions

    Gitea #129: the published skill collection had drifted into three naming shapes where it should
    have three families. weekly-review (added earlier in this same candidate, never released)
    named neither its domain nor its distribution boundary, unlike wiki-* and stack-* either
    side of it - renamed to gtd-weekly-review, joining a new gtd- prefix for the commitment layer
    (kb/gtd/, types/project.md, docs/knowledge-and-commitment.md) that sits beside wiki- (the
    knowledge pipeline) and stack- (the stack's own development, under instructions/dev/).
    instructions/CONTRACT.md § "Writing an instruction" now states both the family-prefix
    convention and, separately, that a skill's description speaks in third person per Anthropic's
    skill-authoring guidance - all eight published skills' descriptions were rewritten to match
    ("Processes...", not "Process..."); the flat instructions/<name>.md form keeps its existing
    imperative-title convention, since its description is read on demand rather than injected into
    the system prompt. No --breaking line: the renamed skill was introduced by this same
    unreleased candidate, so no existing instance carries the old name to migrate away from.

    Veraltete Skill-Aufzaehlungen in der Instruction-Schicht nachgezogen

    Gitea #129s Abschlusspruefung: die Skill-Umbenennung hat sichtbar gemacht, dass mehrere Dokumente
    die Skill-Liste hart aufzaehlen und beim Wachsen der Liste still veralten. Vier Stellen waren
    falsch, eine davon schon vor diesem Paket:

    • instructions/CONTRACT.md § "When a skill carries a copy-in checklist" zaehlte „die zwei
      Skills mit Block und die drei ohne" - also fuenf von inzwischen acht. Die Zahlen im Einstiegssatz
      sind jetzt ganz raus (sie unterscheiden sich ohnehin zwischen diesem Repo und einer
      ausgelieferten Instanz, die instructions/dev/ nicht hat), die Aufzaehlung nennt alle
      ausgelieferten Skills, und die beiden Dev-Skills stehen in einem dist:strip-Block.
    • Dieselbe Passage nannte wiki-query mit sechs Schritten - es sind sieben, und zwar schon
      laenger. Die Regel selbst (ein Flow ab acht Schritten und still scheiternde Schritte) bleibt
      unveraendert; kein Skill wechselt dadurch die Seite.
    • instructions/CONTRACT.md § "outbound reference" sprach im Praesens von „this repo's seven
      skills", wo die Zahl zu einer datierten Messung (52 von 58 Links) gehoert - jetzt als „at the
      time" markiert, statt die Messung nachzurechnen.
    • instructions/bootstrap.md und die Scope-Abschnitte von stack-dev/stack-close listeten
      die Content-Skills ohne gtd-weekly-review auf.

    Dazu test_the_real_repo_publishes_the_six_wiki_skills -> ..._every_skill: der Test pruefte
    sechs der acht Skills und trug die veraltete Zahl im Namen; er nennt jetzt alle acht, nach
    Familien erklaert. Dass die Passage weiterhin Schrittzahlen fremder Dateien zitiert, die genauso
    still veralten koennen, ist als eigene Frage festgehalten und hier bewusst nicht geloest.

    SP-Zugriffsweg explizit (access: api/snapshot, #133) und follow_up_at-Korrektur (dueWithTime/dueDay, #135)

    Gitea #133: der Super-Productivity-Adapter unterscheidet jetzt zwei sich ausschliessende
    Zugriffswege, per Pflichtfeld access ohne Default und ohne Laufzeit-Ruckfall - "api" liest
    und (fuer #132 vorbereitet) schreibt ausschliesslich ueber die lokale REST-API und den aktuellen
    Zustand, "snapshot" liest ausschliesslich den juengsten Backup-Schnappschuss und ist von dort
    aus nie schreibbar. db_path entfaellt vollstaendig, backups_dirs Glob ist auf das echte
    Zeitstempelmuster (YYYY-MM-DD_HHmmss.json) gehaertet, und beide Wege blenden archivierte
    Tracker-Projekte aus - verifiziert gegen den tatsaechlichen Quellcode von
    super-productivity/super-productivity (master, 2026-09-20). SuperProductivityApiReader ist
    der neue Leser fuer access: "api", gegen eine Attrappe getestet, nie gegen eine laufende App.
    tools/wikitool new project verweigert auf einer access: "snapshot"-Instanz jetzt vollstaendig
    (Exit 1, weder Tracker-Projekt noch Seite) statt den nicht mehr moeglichen 42er-Menschenschritt zu
    versuchen; wikitool doctor und wikitool review berichten nur noch den tatsaechlich
    konfigurierten Weg, und jede Antwort von review nennt jetzt explizit, aus welchem Weg sie
    stammt (bei snapshot samt Alter des gelesenen Schnappschusses). Aufgeloest damit: #134, dessen
    Verdacht (--resume koennte gegen einen veralteten Schnappschuss verifizieren) durch den Wegfall
    der Projektanlage auf snapshot-Instanzen gegenstandslos wurde.

    Gitea #135, im selben Zug korrigiert: follow_up_at las bislang remindAt, das sich nur bei
    einer mit Uhrzeit terminierten und benachrichtigten Aufgabe fuellt - ein ganztaegiger, stiller
    Tickler (dueDay ohne dueWithTime, das haeufigste WAITING-Muster) hatte dadurch nie einen
    follow_up_at und fiel bei Pruefung 2 des Wochenrueckblicks still durch. Gelesen wird jetzt
    dueWithTime, sonst dueDay - Super Productivitys eigene Leseregel - nie deadline* (D9 bleibt
    in der Sache unveraendert, nur die falsche Berufung auf sie ist korrigiert). Bestehende Instanzen
    sehen dadurch rueckblickend mehr Befunde, nicht weniger.

    task new: einen zweiten Schreibweg in den Tracker (ein Posten, keine Seite)

    Gitea #132: eine Quelle kann Wissen und eine Verpflichtung zugleich tragen (eine Kundenreklamation
    etwa), und bislang hatte nur die Wissenshaelfte einen Schreibweg. chemenu.tasks.protocol.TaskWriter
    traegt jetzt eine zweite Methode, create_item - Projekt, Titel, optional WAITING mit
    follow_up_at, optional ein Freitext-Rueckverweis in notes -, darueber das neue Kommando
    wikitool task new. Anders als create_project schreibt sie tatsaechlich: bei Super Productivity
    existiert POST /tasks, wo POST /projects fehlt, also gibt es hier keinen
    HumanInterventionRequired-Fall. Das Kommando ordnet kein Projekt selbst zu - ein --project, das
    zu keinem Tracker-Projekt passt, oder --waiting ohne vorhandenen waiting-Tag scheitert laut,
    exit 1, statt zu raten oder einen Posten ohne seinen Status anzulegen. Die Eingangs-Ablage
    (--inbox) ist eine eigene, ausdrueckliche Form am Kommando, nie ein Ersatz fuer ein vergessenes
    --project.

    Verifiziert gegen super-productivity/super-productivity@master (2026-09-20): Super Productivitys
    INBOX_PROJECT ist zwar immer ein echtes Projekt-Entity im Store, aber
    selectUnarchivedProjects - der Selektor hinter GET /projects - filtert es ueber seine feste id
    unbedingt heraus. Ein per --inbox abgelegter Posten erscheint deshalb in keiner
    wikitool review-Pruefung, nicht weil eine Ausnahme dafuer noetig waere, sondern weil der Eingang
    in der Projektliste schlicht nie auftaucht - der Ingest-Skill nennt diese Kosten jetzt ausdruecklich,
    wenn er die Route anbietet.

    Der Ingest-Skill (instructions/wiki-ingest/SKILL.md) fragt in Schritt 5 jetzt auch nach einer
    Verpflichtung, nicht nur nach dem Wissen, und legt Titel und vorgeschlagenes Projekt in einem
    Bestaetigungsschritt vor (nie eine automatische Zuordnung, auch nicht bei einem eindeutigen
    search-Treffer). Der Posten wird vor der Quellenseite angelegt - dieselbe Tracker-vor-Seite-
    Reihenfolge, die new project schon haelt, hier mit eigenem Beleg: eine Rohdatei ohne Quellenseite
    meldet lint als uncovered_raw_files, eine stillschweigend verlorene Verpflichtung meldet
    nichts. Der bestehende Regressionstest, der sicherstellt, dass kein Skill den Tracker-Provider
    nennt, ist entsprechend auf wiki-ingest erweitert. docs/knowledge-and-commitment.md und
    tools/CONTRACT.md sind nachgezogen; Gitea #128 (der zweite Adapter) traegt jetzt create_item
    in seiner eigenen Flaeche.

    wiki-ingest: raw accept rückt hinter die Verpflichtungsentscheidung

    Gitea #136, eine offen gebliebene Teilfrage aus #132: raw accept lief dort weiterhin ganz am
    Anfang des Laufs, vor Lesen, Diskussion und Verpflichtungserkennung - scheiterte task new, fand
    sich eine bereits nach raw/ befoerderte Rohdatei vor, obwohl #132s eigenes Kriterium "keine
    Seite geschrieben und keine Rohdatei befoerdert" verlangte. docs/knowledge-and-commitment.md
    behauptete diese Eigenschaft seit demselben Commit bereits als Tatsache; der Baum beschrieb ein
    Design, das es nicht gab.

    wiki-ingests Schritte 1-5 sind neu geordnet: lesen, Metadaten, search, Diskussion inklusive
    Verpflichtung und task new, dann erst raw accept. Die Schritte 6-12 behalten ihre Nummern
    unveraendert, ebenso jeder Fremdverweis, der eine dieser Nummern nennt. Zwei Stellen sind dabei
    verschaerft, nicht nur verschoben: die fidelity/authority-Frage in Schritt 5 benennt jetzt
    ausdruecklich, dass die Datei zu diesem Zeitpunkt schon vollstaendig gelesen ist - der Moment, in
    dem die Versuchung, den Wert aus dem Inhalt zu erschliessen statt ihn zu erfragen, am groessten
    ist -, und derselbe Schritt benennt, dass seine Kollisionsverweigerung jetzt spaeter faellt, nach
    Lesen, Diskussion und moeglicherweise bereits angelegtem Tracker-Posten.

    Eine Ausnahme bleibt bewusst bestehen: ein Lauf, der wegen Volumen oder Breite an
    instructions/ingest-large-tree.md uebergibt, befoerdert weiterhin vor der Verpflichtungsfrage -
    dessen work new --input <pfad> verweigert jeden Pfad ausserhalb raw/, und der Lauf ist ohnehin
    nicht atomar, da er unit-weise ueber Tage publiziert und seine eigene Verpflichtungsfrage erst in
    Schritt 5d je Unit stellt. docs/knowledge-and-commitment.md nennt diese Ausnahme jetzt explizit,
    statt die Eigenschaft unbedingt zu behaupten. README.md und instructions/CONTRACT.md sind
    nachgezogen.

    Zwei Fragen, die sich beim Durchsehen der Naht zwischen Wissen und Verpflichtungen zusaetzlich
    zeigten - gtd-weekly-reviews veraltete Zaehlung der GTD-Kommandos, und ob der Weekly Review
    task new kuenftig anbieten soll -, sind bewusst nicht Teil dieser Aenderung: Gitea #137 und #138.

    gtd-weekly-review: task new nachgezogen, veralteter Begründungszeiger korrigiert

    Gitea #137, der liegengebliebene Pull-Through von #132 am GTD-Rand: instructions/gtd-weekly- review/SKILL.md behauptete zweimal, review und new project seien die einzigen zwei
    GTD-Kommandos, und begruendete die Haltung "der Nutzer handelt selbst in seinem Tracker" mit
    "because wikitool has no command for it" - seit #132s task new schlicht falsch. Der
    Begruendungszeiger fuer die schmale Kommandoflaeche zeigte zudem auf types/project.md und
    kb/gtd/COLLECTION.md; die Begruendung steht tatsaechlich in
    docs/knowledge-and-commitment.md § "Status has exactly one home", die #132 korrekt nachzog,
    waehrend dieses Skill unberuehrt blieb.

    Beide Stellen benennen task new jetzt als drittes, tatsaechlich vorhandenes Kommando, das dieses
    Skill bewusst nicht aufruft - die Haltung selbst ist unveraendert, nur ihre Begruendung ist jetzt
    eine Wahl statt eine Behauptung ueber eine fehlende Faehigkeit. Ob der Weekly Review task new
    kuenftig anbieten soll, bleibt unentschieden in Gitea #138; dieses Issue korrigiert nur, was
    nachweislich falsch dastand.

    Weekly review proposes task new/task close; tracker gains a closing write path

    Gitea #138 entschied die dort offene Frage: der Weekly Review bietet task new jetzt bei
    stalled/no_open_loop Option (a) an, nach ausdruecklicher Bestaetigung von Titel und Projekt in
    einer Frage - dieselbe Haltung wie im Ingest. Die zweite Haelfte derselben Naht war unentschieden
    liegen geblieben: eine Quelle kann eine Verpflichtung anlegen, aber nie schliessen. Der Tracker
    bekommt dafuer einen dritten, letzten Schreibweg, task close --id, der einen Posten erledigt
    markiert - niemals loescht, verifiziert gegen Super Productivitys master-Branch, dass
    PATCH /tasks/:id mit isDone: true bit-identisch zur eigenen "erledigt"-Checkbox der App ist.
    task list --project liefert dazu die Item-Ids, die task close und die Review-Funde fuer
    waiting_overdue/someday_stale jetzt mitfuehren. wiki-ingest stellt die Verpflichtungsfrage
    seither in beide Richtungen (oeffnen und schliessen), und ingest-large-tree Schritt 5d begruendet
    jetzt in einem Satz, warum diese Frage pro Unit gestellt wird statt einmal pro Baum.

    Die zwei Instruktionsstellen, an denen die Haltung zum Tracker-Schreibzugriff bislang doppelt
    stand, sind auf eine zusammengezogen; die zweite verweist nur noch.
    docs/knowledge-and-commitment.md § "Status has exactly one home" zaehlt die Kommandoflaeche
    korrekt (zwei Lese-, drei Schreibkommandos) und haelt fest, warum sie bei "anlegen" und "erledigt
    markieren" endet, nie bei "loeschen" oder "aendern".

    instructions/CONTRACT.md drops other files' step counts from the copy-in-checklist rationale

    instructions/CONTRACT.md § "When a skill carries a copy-in checklist" used to justify the
    threshold by citing each other skill's step count by number - evidence that the two-halves test
    (length and a silently-omittable step) is what actually decides wiki-ingest/wiki-lint, not a
    count fitted after the fact. Nothing kept those numbers in sync with the SKILL.md files they
    described: one of them had already drifted silently (wiki-query cited at six steps where it had
    been seven for a while), and the passage itself named only five of the eight skills that exist -
    neither wrong number failed any check, because docs verify reads presence, not another file's
    prose (instructions/dev/doc-pull-through.md).

    Of the three fixes considered - a docs verify check against a codified step-counting convention,
    a qualitative rewrite that drops the numbers, or tracking the sync as a manual doc-pull-through.md
    duty - the qualitative rewrite won: it is the only one of the three that removes the possibility of
    drift rather than catching or documenting it, and the per-skill counts were decoration for the
    two-halves test, never load-bearing for it. The passage now names which skills qualify and why,
    without citing a number that belongs to a file it does not own. Today's counts were checked against
    the actual files before this bump (wiki-ingest twelve, wiki-lint nine, wiki-manage two flows
    of seven, wiki-query seven, wiki-status five, gtd-weekly-review five, stack-dev six,
    stack-close four) - all correct, confirming the passage was not itself wrong, only unguarded.


    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
  • v6.2.0 3c9d669729

    v6.2.0
    CI / verify (push) Successful in 48s
    Release / release (push) Successful in 39s
    Stable

    torben released this 2026-09-19 15:45:07 +00:00 | 204 commits to main since this release

    6.2.0 - 2026-09-19 - Entity-Subtyp project nach codebase umbenannt

    Author: Torben Nehmer

    • Entity-Subtyp project nach codebase umbenannt

    Entity-Subtyp project nach codebase umbenannt

    entity_type: project bezeichnete in diesem Korpus ausnahmslos Codebasen; Gitea #119 zieht
    daraus einen eigenen Typ fuer das Vorhaben (gtd/project, Paket #123), wodurch der bisherige
    Wert homonym geworden waere. types/entity.schema.yaml und types/entity.md fuehren jetzt
    codebase statt project, kb/entities/projects/ heisst kb/entities/codebases/, und die elf
    betroffenen Seiten wurden ausschliesslich ueber wikitool touch/move umgezogen. Kein
    Grenzuebertritt: types/entity.md ist .template-basiert, dist upgrade schreibt nie die
    adoptierte Kopie einer Instanz, nur den mitgelieferten Standard daneben - eine bestehende
    Instanz behaelt ihren eigenen project-Wert unangetastet und uebernimmt die Umbenennung erst,
    wenn sie es sich vornimmt.


    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
  • v6.1.0 11c400c670

    v6.1.0
    CI / verify (push) Successful in 55s
    Release / release (push) Successful in 41s
    Stable

    torben released this 2026-09-17 07:18:09 +00:00 | 205 commits to main since this release

    6.1.0 - 2026-09-17 - Upgrade-Pfad und Iteration-Budget-Gate gehaertet, wiki/-Pfadliterale bereinigt

    Author: Torben Nehmer

    High impact

    • Session-Id-Fallback: Harness-Variable schliesst die Luecke zwischen Telemetrie-Join und Iteration-Budget-Gate

    Medium impact

    • Upgrade-Prozedur als eigene Instruktion statt als Prosa in INSTALL.md
    • Migrationsdokument prueft gegen eine festgehaltene Vorher-Ausgabe, Beispielverweis auf die .template-Form
    • dist upgrade: --take-release nimmt fuer einen lokal geaenderten Pfad die Release-Fassung
    • version notes antwortet auf einer ausgelieferten Instanz aus dem Release-Feed
    • new: scaffold materializes a schema default only for a required field

    Low impact

    • Stale wiki/ path literals swept out of tools/ and types/, with a test guarding against the next rename
    • CHANGES.md/Guard-Docstring: die Zahl der nachgezogenen Pfadliterale korrigiert (33, nicht 27)

    Dieser Kandidat sammelt, was ein getraceter 5.0.0-auf-6.0.0-Upgrade-Lauf auf einer echten Instanz
    offengelegt hat: ein fehlender Upgrade-Leitfaden, zwei falsche Verweise im Migrationsdokument,
    eine fehlende dritte Antwort in dist upgrade fuer eine lokal geaenderte Datei, und
    version notes, das auf einer ausgelieferten Instanz nie antworten konnte. Im selben Lauf zerfiel
    die Sitzung durch einen PID-basierten Session-Id-Fallback in 21 Telemetrie-Buckets, wodurch das
    Iteration-Budget-Gate strukturell unerreichbar blieb - behoben durch eine Registry bekannter
    Harness-Session-Variablen, mit einem SIGPIPE-Nebenbefund im CLI-Emitter gleich mit. Dazu,
    unabhaengig vom getraceten Lauf: ein Scaffold-Fix, der obligation: required nicht mehr in jede
    neue Instruktion schreibt, und eine Bereinigung von 33 stehengebliebenen wiki/-Pfadliteralen aus
    der wiki/-nach-kb/-Umbenennung, mit einem Test-Guard gegen die naechste Umbenennung.

    Kein Grenzuebertritt: jede Aenderung ist in beide Richtungen ein Drop-in, additiv gegenueber
    6.0.1.

    Upgrade-Prozedur als eigene Instruktion statt als Prosa in INSTALL.md

    Der Upgrade-Pfad einer ausgelieferten Instanz stand nur in INSTALL.md § "Eine Instanz
    aktualisieren" - einem Dokument fuer Menschen, das AGENTS.md § File naming ausdruecklich als
    "never by an agent as instruction" fuehrt. Ausgefuehrt wird er aber von einer Agent-Sitzung,
    jedes Mal. Der getracete 5.0.0-auf-6.0.0-Lauf auf einer echten Instanz zeigt, was daraus folgt:
    der erste Tool-Call listete instructions/ mit, fand keine passende Instruktion, oeffnete die
    naechstliegende (private-instance.md, der falsche der beiden Wege) und fiel dann auf INSTALL.md
    zurueck. migrate verify --from <commit vor dem Tausch> - INSTALL.md Schritt 6, erster
    Pruefschritt - lief in 33 Werkzeugaufrufen kein einziges Mal, und die Agent-Sitzung wurde nie neu
    gestartet, obwohl AGENTS.md im selben Commit +44/-3 bekommen hatte. Die anschliessende Migration
    lief damit unter dem alten Kontrollplan.

    Dahinter lagen drei Reihenfolgen nebeneinander: die in INSTALL.md, die im Abschlussbericht von
    dist upgrade, und die tatsaechlich gelaufene. Genau der Zustand, den Invariante 8 verbietet.

    instructions/upgrade-instance.md ist jetzt die eine Fassung: dreizehn Schritte von der
    Sitzungs-Id bis zum zweiten Publish, mit dem Sitzungsneustart an der Stelle, an der der neue
    Kontrollplan zu gelten anfaengt - nach dem Publish der Maschinerie, vor der Migrationskette, und
    mit migrate status als Wiedereinstiegspunkt fuer die neue Sitzung. manual: true, weil die
    Prozedur einmal pro Release laeuft und nie implizit aufgegriffen werden darf; ein Skill wuerde
    seine description dafuer in jede Sitzung legen. Auffindbar ist sie ueber den Abschlussbericht
    von dist upgrade, der statt einer eigenen Schrittliste jetzt die Datei nennt und das Kommando,
    bei dem der Lauf weitergeht (instructions sync). INSTALL.md behaelt, was ein Mensch vorher
    entscheidet, und den einen Sonderfall, den die Instruktion nicht abdecken kann, weil es sie dort
    noch nicht gibt: den ersten Sprung auf 4.5.0.

    Zwei Schritte der Instruktion sagen ausdruecklich, dass sie eine Luecke umgehen, und was sie
    ueberfluessig macht. Schritt 2 liest die Release-Notes von der Release-Seite statt mit
    version notes, weil eine Instanz ihre CHANGES.md als Stub bekommt und dist upgrade sie nie
    ueberschreibt - der Befehl kann dort nicht heute und nicht spaeter antworten. Schritt 6 nimmt fuer
    eine lokal veraenderte stackeigene Datei die Release-Fassung von Hand, weil es zu --keep-local
    kein Gegenstueck gibt; dabei geht der noetige Commit ueber publish --no-push, nicht ueber
    git commit - Invariante 5 kennt keine Ausnahme fuer "ist ja nur eine Vorbedingung", und genau
    diese Ausnahme hat sich der beobachtete Lauf genommen.

    instructions/session-setup.md sagt jetzt, dass ein export nur traegt, solange die Shell
    traegt. Mehrere Harnesses starten pro Tool-Call eine frische Shell - das Arbeitsverzeichnis
    ueberlebt, Shell-State nicht - und dann faellt jeder Aufruf auf seine eigene Parent-PID zurueck.
    Im gemessenen Lauf wurde eine Sitzung so zu 21 Telemetrie-Buckets mit hoechstens drei Aufrufen
    pro Bucket: das Iteration-Budget-Gate (60) und der Loop-Breaker (3 identische in Folge) konnten
    strukturell nicht ausloesen. Die Anleitung nennt deshalb die Inline-Form pro Aufruf und den
    Einzeiler, mit dem sich beantworten laesst, welcher Fall vorliegt.

    Verifiziert: docs verify (73 ausgelieferte Dokumente, 58 Referenzdateien),
    instructions verify (23 Instruktionen, 7 Skills) und 1276 Tests gruen - einer davon neu und auf
    genau die Stelle gerichtet, an der die Doppelung wieder entstehen wuerde: der Abschlussbericht
    von dist upgrade muss die Instruktion und ihr Wiedereinstiegskommando nennen, nicht eine zweite
    Kopie der Liste.

    Kein Grenzuebertritt: eine neue Instruktionsdatei und ein geaenderter Meldungstext sind in beide
    Richtungen ein Drop-in. Eine Instanz, die zurueckgeht, behaelt die Datei als ueberzaehlige Datei,
    und nichts liest sie automatisch - manual: true heisst genau das.

    Migrationsdokument prueft gegen eine festgehaltene Vorher-Ausgabe, Beispielverweis auf die .template-Form

    instructions/migrations/6.0.0-type-guidance-split.md verlangte in seinem Verifikationsschritt,
    die Ausgabe von types describe <name> muesse "read the same as it did before this migration" -
    ohne dass ein Schritt davor dieses Vorher festhielt. Eine Pruefung gegen einen Zustand, den
    niemand aufgeschrieben hat, faellt auf das Gedaechtnis des Ausfuehrenden zurueck, und bei ueber
    150 Zeilen Ausgabe je Typ ist das keins. Der getracete 6.0.0-Lauf hat entsprechend durch
    | head -250 und | tail -80 geprueft und "structurally identical to before" geurteilt; was
    das uebersah, lag in der Mitte der source-Ausgabe. Das Dokument schreibt die Ausgabe jetzt in
    einem eigenen Schritt vor der Aenderung in eine Datei und diffed hinterher, mit
    grep -c '^## Authoring guidance' als Ein-Zahl-Probe: zwei Koepfe sind richtig - einen setzt
    types describe selbst, einen bringt die Guidance-Datei mit.

    Als generisches Muster steht dasselbe jetzt in instructions/migrate-corpus.md § "Writing the
    migration document", weil es nicht an diesem einen Dokument haengt: migrate verify traegt seine
    Baseline im letzten Commit, ob jemand daran denkt oder nicht - eine Migration an der Maschinerie
    statt an kb/ hat gar keine, und genau dort entsteht die Behauptung, die sich nicht widerlegen
    laesst.

    Zweiter Fehler im selben Dokument: der Beispielverweis auf types/entity.md zeigt in einer
    ausgelieferten Instanz auf die beim Setup adoptierte Kopie - also auf genau den Vorher-Zustand,
    den der Schritt entfernen laesst. Der Nachher-Zustand liegt dort unter
    types/entity.md.template, und im Ursprungs-Repo existiert diese Datei ueberhaupt nicht:
    dist export re-keyt types/<name>.md erst beim Export. Der Satz konnte in einer Instanz also
    nicht bloss unguenstig sein, er konnte dort nie stimmen. Dazu sagt der Schritt jetzt die Sprache
    des Pointer-Absatzes - englisch, weil Anleitungsprosa an einen Agenten Control Plane ist,
    unabhaengig davon, wem die Datei gehoert - und dass das auch fuer behaltene lokale Prosa gilt:
    die wird uebersetzt, nicht umbenannt. Die Tabelle dazu wird verlinkt statt kopiert
    (types/type-spec.md § "Who owns a type-spec"), und ein behaltener Abschnitt bekommt einen
    eigenen Namen statt der Ueberschrift, die types describe schon selbst setzt.

    Derselbe Defekt eine Ebene hoeher, gefunden beim Nachmessen: types/source.md trug hier im
    Ursprungs-Repo noch einen Rest-Abschnitt ## Authoring guidance mit einem einzigen Bullet, der
    die title_prefix-Frontmatter wiederholte - types describe source gab drei Koepfe aus, die
    anderen drei Typen zwei. Die Sprachzentralisierung hat den Abschnitt uebersetzt, der
    Guidance-Split den Rest der Prosa ausgelagert und diesen Bullet stehenlassen. Die Datei wird beim
    Export zu types/source.md.template, also haette ihn jede neu aufgesetzte Instanz mit adoptiert.
    Entfernt, geprueft mit genau dem Muster, das der Schritt oben jetzt vorschreibt: Vorher-Datei,
    Diff, vier entfernte Zeilen und sonst nichts, alle vier Typen komponieren jetzt mit zwei Koepfen.

    Verifiziert: docs verify (73 ausgelieferte Dokumente, 58 Referenzdateien),
    instructions verify (23 Instruktionen, 7 Skills) und 1276 Tests gruen. Kein neuer Test: die
    Aenderung ist Prosa in zwei Instruktionen und ein entfernter Abschnitt aus einem Type-Spec -
    was hier mechanisch pruefbar waere, prueft docs verify bereits als Type-Spec gegen sein Schema.

    Kein Grenzuebertritt: in beide Richtungen ein Drop-in. Die Korrektur gilt denen, die noch
    upgraden - eine Instanz, die das Angebot bereits genommen hat, liest das Dokument nicht noch
    einmal. Fuer sie lohnt der eine Befehl, mit dem der Schaden hier gefunden wurde:
    grep -c '^## Authoring guidance' ueber types describe <name> fuer alle vier Typen, drei
    bedeutet einen Rest-Abschnitt im eigenen Type-Spec.

    dist upgrade: --take-release nimmt fuer einen lokal geaenderten Pfad die Release-Fassung

    dist upgrade kannte zwei Antworten auf eine lokal geaenderte Datei und die dritte, die man
    eigentlich will, war keine davon. --keep-local behaelt die Aenderung - und weil der neue Stamp
    die Release-Digest trotzdem schreibt, wird dieselbe Datei bei jedem kuenftigen Upgrade erneut
    gemeldet. Fuer eine Datei, die der Instanz gar nicht gehoert, ist das der dauerhaft falsche
    Zustand. Der andere angebotene Weg, "reconcile them by hand first", hatte kein Werkzeug: im
    getraceten 5.0.0-auf-6.0.0-Lauf war eine kb/CONTRACT.md durch ein Format-on-Save um
    Tabellen-Whitespace verschoben, und das kostete eine Handkopie aus dem entpackten Tarball, einen
    Commit nur zur Herstellung der Clean-Tree-Vorbedingung des naechsten Kommandos - und damit einen
    rohen git commit, an AGENTS.md Invariante 5 vorbei, die fuer "ist ja nur eine Vorbedingung"
    keine Ausnahme kennt.

    --take-release <pfad> ist die fehlende Antwort: schreibe fuer diesen Pfad die Release-Fassung,
    statt abzubrechen. Wiederholbar, weil der Pfad die Entscheidung benennt - --keep-local verliert
    nichts, --take-release verwirft eine lokale Aenderung, und die zwei sind darum nicht symmetrisch
    genug fuer ein pauschales Flag. Beide gelten pro Pfad und komponieren auf einem Aufruf, was der
    gemischte Fall braucht: eine Datei zuruecksetzen, eine andere behalten. Ohne --keep-local bricht
    ein blockierter Pfad, zu dem nichts gesagt wurde, weiter ab; ein --take-release-Pfad, der gar
    nicht blockiert ist, wird abgelehnt - auch im --dry-run, denn das ist ein Fehler im Argument
    und nicht ein Zustand des Baums, und ein still ignorierter Tippfehler haette ein erfolgreiches
    Upgrade gemeldet und die Aenderung behalten, die verworfen werden sollte.

    Anders als bei --keep-local ist die Drift danach weg und nicht bloss uebergangen: die Datei
    stimmt wieder mit der Digest ueberein, die der Stamp fuehrt, und verschwindet aus der Meldung.

    Dazu die Abbruchmeldung selbst, die den Fehlgriff mitverursacht hat. Sie nannte --keep-local und
    "reconcile by hand", sagte aber nicht, dass es zu --keep-local kein Gegenstueck gibt - der Lauf
    kuendigte woertlich an, "I'll let the upgrade take the release's version", und rief das Kommando
    ohne Flag auf. Jetzt nennt sie alle drei Antworten mit fertig eingesetzter Kommandozeile, im Muster
    des Mass-Update-Gates, und sagt ausdruecklich, dass keine davon der Default ist.

    instructions/upgrade-instance.md Schritt 6 traegt entsprechend nicht mehr die Drei-Schritt-Handreparatur, sondern die Entscheidung und den Dry-Run, mit dem man sie vorher sieht.

    version notes antwortet auf einer ausgelieferten Instanz aus dem Release-Feed

    version notes liest die lokale CHANGES.md. Eine ausgelieferte Instanz bekommt die aber als
    neunzeiligen Stub ohne einen einzigen Versionseintrag, und CHANGES.md steht in
    chemenu.ownership.is_upgrade_preserved - dist upgrade ueberschreibt sie also nie. Der Stub
    bleibt der Stub, dauerhaft. Der Befehl konnte dort nicht nur heute nicht antworten, sondern nie,
    und das an genau der Stelle, an der die Antwort am meisten zaehlt: dem Grenzuebertritt, vor dem
    Breaking Change: und Migration: gelesen werden muessen. Der getracete
    5.0.0-auf-6.0.0-Lauf kam nur weiter, weil er die Release-Notes ueber einen MCP-Server holte - ein
    Weg, den die Anleitung nicht nannte und den eine Instanz ohne erreichbaren Server gar nicht hat.

    Fehlt der Eintrag lokal, fragt der Befehl jetzt den Feed aus update_url - denselben, den
    version check benutzt - und druckt den body des Release, den release.yml im Ursprungs-Repo
    ohnehin aus version notes baut. Drei Praezisierungen halten das von einem stillen Netzaufruf
    auseinander:

    • Nur mit Release-Stamp. Ein Baum ohne .wikitool-release.json ist ein Dev-Checkout und
      behaelt die alte Fehlermeldung. Damit kann der neue Pfad im Ursprungs-Repo und in CI nicht
      betreten werden - auch nicht von release.ymls eigenem version notes.
    • stdout traegt nur die Notes. Die Zeile, welcher Feed gefragt wird, und die, welche Version
      geantwortet hat, gehen nach stderr. release.yml leitet stdout in die Datei um, die es als
      Release-Body postet; alles andere dort waere Inhalt im Release.
    • --offline verweigert den Aufruf und scheitert mit der release_url aus dem Stamp. Dieselbe
      Seite nennt auch jeder Fehlerfall des Feeds, damit ein Lauf, der die Notes nicht lesen kann,
      wenigstens weiss, wo sie stehen. Ein leerer body ist ebenfalls ein Fehler: eine leere Antwort
      darf nicht als "dieses Release hat nichts zu melden" durchgehen.

    Gefragt werden kann nur das neueste Release: update_url ist die einzige URL, die der Stamp
    fuehrt, und eine /releases/tags/<tag>-URL daraus zusammenzusetzen waere eine geratene
    API-Form statt einer gelesenen (Invariante 7). Antwortet der Feed eine andere Version als die
    gefragte, wird das auf stderr benannt und die Notes werden trotzdem gedruckt - das ist nicht der
    Randfall, sondern der Hauptfall, weil die Notes vor dem Tausch gelesen werden, wenn VERSION
    noch das Release nennt, das verlassen wird.

    instructions/upgrade-instance.md Schritt 2 und INSTALL.md § "Version und Updates" tragen
    entsprechend nicht mehr den Hinweis, dass der Befehl auf einer Instanz nicht antwortet; damit ist
    auch die letzte der beiden Werkzeugluecken aus dieser Instruktion heraus, und ihr Vorwort nennt
    keine mehr.

    Bei der Gelegenheit zwei Eintraege aus tools/CONTRACT.md § "Future considerations (not
    implemented)" entfernt, die dort seit ihrer Umsetzung falsch standen: der MCP-Server-Wrapper und
    dist upgrade selbst. Beide sind im selben Dokument weiter oben als existierend beschrieben.

    Session-Id-Fallback: Harness-Variable schliesst die Luecke zwischen Telemetrie-Join und Iteration-Budget-Gate

    Gemessen an einem getracten Lauf (33 wikitool-Aufrufe, eine Sitzung): unter Claude Code, dessen
    Bash-Tool jeden Aufruf in einer frisch initialisierten Shell ausfuehrt, fiel chemenu.session
    ohne gesetztes WIKITOOL_SESSION_ID auf os.getppid() zurueck - eine neue "Sitzung" pro Aufruf.
    Der Lauf zerfiel so in 21 Telemetrie-Buckets (hoechster Bucket: 3 von 33 Aufrufen), und das
    Iteration-Budget-Gate (60 Aufrufe, Loop-Breaker bei 3 identischen in Folge) sah nie mehr als 3 von
    60 - strukturell unerreichbar, obwohl AGENTS.md es als eine der vier code-durchgesetzten
    Sicherungen fuehrt. Derselbe Bruch traf den Telemetrie-Join: Hook-Events (prompt.submitted)
    trugen die Harness-UUID, wikitool.call-Events die wechselnde PID - kein gemeinsamer Schluessel,
    und eval score bewertete 1-3 Aufrufe statt 33.

    chemenu.session bekommt eine dritte Stufe zwischen der expliziten Variable und dem
    PID-Fallback: eine kleine Registry bekannter Harness-Session-Variablen (HARNESS_ENV_VARS),
    heute mit einem verifizierten Eintrag, CLAUDE_CODE_SESSION_ID. Verifiziert heisst: gegen eine
    echte Sitzung gemessen, dass die Variable ueber Tool-Aufrufe hinweg stabil bleibt (anders als die
    Shell-PID) und exakt der Wert ist, den der UserPromptSubmit-Hook in die Trace schreibt - der
    Wert wird unveraendert als Schluessel uebernommen, kein Praefix, keine Umschreibung, sonst waere
    der Join wieder zerstoert. Ein Eintrag wird nur nach genau dieser Verifikation aufgenommen: ein
    Variablenname, der zufaellig existiert und etwas anderes bedeutet, waere ein stillerer Fehler als
    der PID-Fallback, den er ersetzt.

    run_budgets Zustandsdatei (budget.json) traegt je Eintrag jetzt die Herkunft seiner Id; faellt
    dieselbe Id-Zeichenkette unter eine andere Herkunft als die gespeicherte, beginnt ein neuer
    Zaehler statt einen fremden zu erben - ein Eintrag ohne das Feld (vor dieser Aenderung
    geschrieben) behaelt seinen Count unveraendert. doctor ist jetzt dreiwertig (OK fuer eine
    explizite Variable oder eine erkannte Harness-Variable, WARN nur noch fuer den reinen
    PID-Fallback), und sowohl budget status als auch der session.start-Event der wikitool-
    Telemetriequelle nennen die Herkunft der Id.

    Im selben Lauf gemessener Nebenbefund auf der Emitter-Seite: ein durch eine geschlossene Pipe
    abgebrochener, ansonsten erfolgreicher Aufruf (... | head) stand mit exit_code: 1 in der
    Trace - Click faengt BrokenPipeError selbst ab und erzwingt sys.exit(1), ununterscheidbar von
    einem echten Fehler. cli.py installiert jetzt vor jedem Dispatch einen Wrapper um
    stdout/stderr, der einen EPIPE-Schreibfehler schluckt, bevor Click ihn sieht, und markiert den
    Trace-Eintrag stattdessen mit stdout_truncated: true bei unveraendertem, dem tatsaechlichen
    Kommandoerfolg entsprechendem exit_code.

    Reproduziert mit Tests, die echte Subprozesse statt In-Process-Aufrufe verwenden - os.getppid()
    ist sonst ueber die Testlaufzeit hinweg konstant: 61 Aufrufe aus je eigenem Prozess mit nur der
    Harness-Variablen loesen das Gate jetzt aus, drei identische ebenso den Loop-Breaker; vor dieser
    Aenderung waeren beide Tests gruen und blind gewesen.

    --minor: additiv (ein neues optionales source-Feld in budget.json, die Id faellt weiterhin
    auf getppid() zurueck, wo keine Variable greift), keine der beiden Drop-in-Richtungen verletzt.

    new: scaffold materializes a schema default only for a required field

    tools/wikitool new instruction --name "x" schrieb bislang obligation: required in jede neue
    Instruktion. obligation: ist ein Migrationsfeld (instructions/CONTRACT.md
    § instructions/migrations/) - eine gewoehnliche Instruktion ist keine Migration und hat nichts,
    was laufen muesste. Ursache: new_page._build_frontmatter() materialisierte jedes
    Schema-default: unbesehen; ueber alle acht types/*.schema.yaml gibt es genau zwei
    (entity/concepts provenance, in required:; instructions obligation:, nicht).

    Die Regel jetzt: ein Schema-default: wird nur fuer ein Feld materialisiert, das das Schema auch
    in required: fuehrt. Auf einem optionalen Feld ist ein default: eine Lese-Annahme (was ein
    fehlendes Feld bedeutet), keine Schreib-Vorgabe - sie hinzuschreiben macht aus der stillen
    Annahme eine ausgesprochene Behauptung. instruction.obligations eigene Lese-Annahme steht
    unveraendert und unabhaengig in kb_state.py (frontmatter.get("obligation") or REQUIRED).
    Der array-Zweig direkt daneben (leere Liste fuer ein unbesetztes Array-Feld wie tags:) ist
    davon ausdruecklich nicht betroffen - er bleibt fuer optionale wie Pflichtfelder gleich, weil ein
    fehlender Schluessel sonst den Template-Filter-Suffix woertlich in den Body schreiben wuerde
    ({related|bullets} -> das Wort "bullets").

    --patch: kein Bestandsdokument aendert sich (obligation: stand bislang nur explizit oder auf
    den beiden Migrationsdokumenten), keine Migration noetig, und ein zurueckgerolltes Werkzeug
    schriebe das Feld nur wieder mit.

    Stale wiki/ path literals swept out of tools/ and types/, with a test guarding against the next rename

    Die Wissensschicht wurde am 2026-08-21 von wiki/ nach kb/ umbenannt. Das Verzeichnis zog um,
    die Zeichenkette nicht: 33 Stellen nannten weiter einen Pfad, den es nicht mehr gibt. Gemeldet
    war davon eine - die Kopfzeile des Lint-Reports (Scanned N pages under `wiki/` ) - als
    kosmetischer Einzelfall. Der Scan selbst war immer korrekt: run_lint(kb_dir) laeuft ueber
    kb/, gezaehlt wird, was dort liegt. Falsch waren ausschliesslich die Beschriftungen.

    Dreizehn davon sind nutzersichtbar. Die Fehlermeldungen von xref, cite, touch,
    move, rm, rename, raw accept und log status nannten wiki/, ebenso die --help-Texte
    von cite sync --all, provenance rebuild-index --dry-run und move --reconcile. Dazu die
    description:-Felder in types/type-spec.schema.yaml, die ueber types describe und ueber jede
    Schema-Validierungsmeldung bei einem Agenten landen. Zwei Stellen waren doppelt falsch:
    git_publish.py und run_budget.py verwiesen auf wiki/concepts/Mass-Update Gate.md, waehrend
    die Seite unter kb/concepts/workflows/Mass-Update Gate.md liegt - dort war auch die
    Collection-Ebene veraltet.

    Nicht angefasst: raw/ (unveraenderlich, was immer dort steht) und die Alteintraege dieser
    Datei. Beide sind Aufzeichnungen dessen, was zu ihrer Zeit galt, keine Wegweiser - dieselbe
    Unterscheidung, die instructions/dev/issue-tracking.md fuer den Tracker trifft.

    Dass es vier Wochen unbemerkt blieb, ist der eigentliche Befund: kein Check liest ein Pfadliteral
    in Quelltext. docs verify kam dafuer nicht in Frage, weil es shipped_prose() liest, also
    Markdown - der Grossteil des Defekts sass in .py-Zeichenketten. Der Guard ist deshalb ein Test:
    tools/chemenu/tests/test_source_hygiene.py scannt jede .py-Datei unter tools/chemenu/ sowie
    tools/wikitool gegen eine Tabelle stillgelegter Stufenpfade. Die naechste Umbenennung traegt
    dort eine Zeile nach und bekommt jede vergessene Stelle als Testfehler, statt als Zeichenkette,
    die ein Jahr lang niemand liest. Die zwei Ausnahmen stehen bewusst als Liste mit Begruendung und
    nicht als geschickteres Muster: eine Fixture-URL, in der wiki ein Repository-Name ist, und die
    Guard-Datei selbst, die die stillgelegten Pfade ja gerade deklariert.

    kb/entities/projects/Chemenu.md trug denselben Fehler in einer Kerndaten-Zeile und wurde ueber
    touch nachgezogen. "Dreilagig" blieb dort stehen: das deckt sich mit der Concept-Seite
    Three-Layer Architecture, die reports/ ausdruecklich als vierte Phase neben den drei
    Schichten fuehrt.

    --patch: keine Schnittstelle aendert sich, kein Verhalten, keine Migration. Ein
    zurueckgerolltes Werkzeug gibt nur wieder die alten Beschriftungen aus.

    CHANGES.md/Guard-Docstring: die Zahl der nachgezogenen Pfadliterale korrigiert (33, nicht 27)

    Der Eintrag darueber nannte 27 nachgezogene Stellen und "rund die Haelfte davon nutzersichtbar".
    Beides war falsch. Die 27 stammten aus einem wc -l, das nur tools/**/*.py gezaehlt hatte -
    tools/wikitool, types/type-spec.md und die vier description:-Felder in
    types/type-spec.schema.yaml fehlten darin. Nachgezaehlt am Commit selbst
    (git show <sha> | grep -c '^-.*wiki/'): 33, davon 32 im Stack und eine auf der Seite
    Chemenu. Nutzersichtbar sind davon dreizehn, also gut ein Drittel und nicht die Haelfte.

    Derselbe Zahlendreher stand im Docstring von tools/chemenu/tests/test_source_hygiene.py, wo er
    kuenftigen Lesern erklaert, wogegen der Guard schuetzt - dort ebenfalls korrigiert. Dass diese
    Korrektur einen eigenen Bump braucht, ist kein Formalismus: der Docstring liegt unter tools/,
    und das Version-Gate in .gitea/workflows/ci.yml ist nach Pfad geschnitten, nicht nach Absicht.

    --patch: reine Prosakorrektur, kein Verhalten, keine Schnittstelle.


    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
  • v6.0.1 f3c80747a5

    v6.0.1
    CI / verify (push) Successful in 48s
    Release / release (push) Successful in 41s
    Stable

    torben released this 2026-09-16 04:47:50 +00:00 | 216 commits to main since this release

    6.0.1 - 2026-09-16 - docs toc/verify erreichen die .template-Form einer Referenzdatei

    Author: Torben Nehmer

    High impact

    • docs toc/verify erreichen die .template-Form einer Referenzdatei

    docs toc/verify erreichen die .template-Form einer Referenzdatei

    kb/CONVENTIONS.md.template war 105 Zeilen lang und trug keine TOC-Region. toc.target_files()
    berechnete den Dateisatz ueber die adoptierten Namen, und eine Datei auf .md.template faellt
    aus jedem dieser Walks heraus - also hat docs toc --apply das Template nie angefasst und
    docs verify es nie gelesen. Eine Instanz, die es nach instructions/setup-instance.md
    adoptiert, bekam damit eine kb/CONVENTIONS.md ohne Region und fiel am docs verify in
    Schritt 13 derselben Anleitung um - dem Befehl, mit dem das Setup endet. Ausgeliefert war das in
    6.0.0.

    Eine in Scope stehende Datei nimmt ihr <name>.template jetzt mit hinein: das Template ist
    dasselbe Dokument einen Schritt frueher in seinem Leben, und wer es auslaesst, laesst die
    adoptierte Kopie den Fehler erben. docs verify prueft im Ursprungs-Repo damit 57 statt 56
    Referenzdateien, in einer frisch exportierten Instanz 59.

    Ausgeloest hat es ein Wachstum um sechs Zeilen: f350999 hat das Template von 99 auf 105 Zeilen
    gebracht und damit ueber die Schwelle von 100. Seither war ci.yml auf jedem Push rot (Laeufe
    279 bis 289) - was als Flackern gelesen wurde, weil jeder Push zusaetzlich einen gruenen
    release.yml-Lauf erzeugt und die Paare wie Lauf und Wiederholung aussehen. Sie sind zwei
    verschiedene Workflows.

    Grenzuebertritt-Frage geprueft und verneint, gegen den dokumentierten Update-Weg: das Template ist
    stack-eigen (ownership.is_stack_owned - jede .template unter einer Content-Stage), steht nicht
    in UPGRADE_PRESERVED_PATHS, und dist upgrade schreibt es damit mit. Eine Instanz bekommt das
    reparierte Template also durch den Upgrade selbst, ohne Handarbeit; der Rueckweg funktioniert
    ebenso, weil die alte Maschinerie das Template gar nicht erst prueft. Handarbeit faellt nur an, wo
    eine Instanz ihr stack-eigenes Template lokal veraendert hat - dist upgrade meldet genau das als
    blocked und verlangt --keep-local.

    Verifiziert: docs verify/instructions verify gruen, 1275 Tests gruen (3 neu: das Template einer
    in Scope stehenden Datei steht im Dateisatz, ein .template ohne solche Datei daneben nicht
    (USER.md.template), und ein Template ueber der Schwelle ohne Region ist ein Befund - der letzte
    waere am heutigen Stand rot gewesen). Dazu der vollstaendige setup-instance.md-Replay gegen einen
    frischen dist export: doctor, docs verify, instructions verify und lint laufen in der
    frischen Instanz durch.


    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
  • v6.0.0 5d26698cd0

    v6.0.0
    CI / verify (push) Failing after 40s
    Release / release (push) Successful in 40s
    Stable

    torben released this 2026-09-15 19:38:53 +00:00 | 217 commits to main since this release

    6.0.0 - 2026-09-15 - search: Pfad und Titel vollstaendig, Trunkierung sichtbar

    Author: Torben Nehmer

    Breaking Change:

    • docs verify loest ab dieser Version jeden relativen Markdown-Link in den Referenzdateien auf und meldet ein totes Ziel als Fehler - auch in kb/CONVENTIONS.md und kb//COLLECTION.md, die eine Instanz selbst besitzt und die ein Drop-in-Copy der Maschinerie nicht ersetzt. Eine Instanz, deren eigene Konventions- oder Collection-Datei einen relativen Link mit falscher ../-Tiefe oder auf eine inzwischen geloeschte Datei traegt, sieht docs verify nach dem Update fehlschlagen, wo es vorher durchlief. Reparatur: den in der Meldung genannten Datei:Zeile-Link korrigieren - kein Werkzeuglauf, keine Inhaltsmigration.
    • docs verify prueft die TOC-Region ab dieser Version auch auf types/.md und docs/.md. Eine Instanz, die die Page-Type-Spec-Templates adoptiert hat, traegt types/source.md und types/concept.md ohne Region und sieht docs verify nach dem Update fehlschlagen, wo es vorher durchlief; dasselbe gilt fuer eine selbst angelegte oder lokal geaenderte docs/-Seite ueber 100 Zeilen. Reparatur: tools/wikitool docs toc --apply - ein Werkzeuglauf, keine Inhaltsmigration.

    Migration: none required - Keine kb/-Seite aendert ihre Form. Der Grenzuebertritt ist ein strengerer Check auf instanz-eigener Prosa, keine Schema- oder Frontmatteraenderung.

    High impact

    • SKILL.md: relative Links durch repo-root-relative Pfade ersetzt, docs verify/instructions verify pruefen Linkziele
    • docs verify: der Linkziel-Check erreicht auch die instanz-eigenen kb/CONVENTIONS.md und COLLECTION.md - daher Grenzuebertritt
    • TOC-Scope auf types/ und docs/ erweitert, Sprachregeln zentralisiert, --breaking akkumuliert
    • types/: Seiten-Type-Spec-Anleitungsprosa in stackeigene guidance-Datei ausgelagert

    Medium impact

    • docs verify: ein nur als .template ausgeliefertes Linkziel gilt als aufgeloest
    • Control-Plane-Sprache universell: Achse ist das Publikum, kein Instanz-Schalter
    • types/type-spec.schema.yaml enforced against real type-spec frontmatter
    • search: Pfad und Titel vollstaendig, Trunkierung sichtbar

    Low impact

    • gates.md/session-setup.md: die Budget-Ausnahme von version regrade haengt an der Aufrufform
    • types/type-spec.md: Ownership und Sprache getrennt benannt (Nachzug zu #99)

    Ausgangspunkt war ein realer Bruch: instructions sync kopiert jede SKILL.md in eine andere
    Verzeichnistiefe, und 52 von 58 relativen Links darin zeigten in der publizierten Kopie ins Leere,
    unbemerkt, weil kein Check je ein Linkziel gelesen hat. Die Reparatur - repo-root-relative Pfade
    statt ../-Links - zieht zwei neue mechanische Checks nach sich (instructions verify verbietet
    relative Links in SKILL.md, docs verify loest Linkziele in allen Referenzdateien auf), und der
    zweite Check erreicht auch instanz-eigene Prosa (kb/CONVENTIONS.md, COLLECTION.md), die ein
    Drop-in-Copy nicht ersetzt - der Grenzuebertritt, der diesen Kandidaten auf 6.0.0 eskaliert hat.
    Denselben Linkziel-Check bekommt die TOC-Pflicht gleich mit auf types/ und docs/ erweitert, und
    die Sprachregeln fuer die Control-Plane sind zu einer einzigen, publikumsbasierten Regel in
    AGENTS.md zentralisiert statt eines Instanz-Schalters. Daneben, unabhaengig vom Linkproblem: die
    Seiten-Type-Spec-Anleitungsprosa ist in eine stackeigene Guidance-Datei ausgelagert,
    type-spec.schema.yaml wird jetzt gegen echte Type-Spec-Frontmatter durchgesetzt, und search
    zeigt Pfad und Titel eines Treffers vollstaendig statt trunkiert.

    gates.md/session-setup.md: die Budget-Ausnahme von version regrade haengt an der Aufrufform

    Doku-Nachzug zu 5.1.0. Beide Dateien beschrieben die Budget-Ausnahme als feste Liste pro
    Kommandoname ("fixed allowlist"); version regrade ist die erste Ausnahme, die nur in einer
    Aufrufform liest - bar listet sie, mit Positionen schreibt sie CHANGES.md. Die Liste selbst
    bleibt an ihrem einen Ort (tools/CONTRACT.md), beide Stellen benennen jetzt aber, dass dort ein
    Eintrag pro Aufruf statt pro Namen gilt. Aufgefallen in der Schlussphase derselben Arbeit, deshalb
    ein eigener Patch-Bump: der Pfad instructions/ liegt im Version-Gate der CI.

    SKILL.md: relative Links durch repo-root-relative Pfade ersetzt, docs verify/instructions verify pruefen Linkziele

    instructions sync kopiert jede SKILL.md byteidentisch in .agents/skills/ und
    .claude/skills/ - eine andere Verzeichnistiefe als die Quelle, ohne deren Nachbardateien. 52 von
    58 relativen Markdown-Links in den sieben Skills zeigten deshalb in der publizierten Kopie ins
    Leere, unbemerkt, weil kein Check je ein Linkziel gelesen hat (Gitea-Meldung: ein session-setup.md-Read
    schlug in einer ausgelieferten Instanz fehl). Alle 58 Links sind jetzt repo-root-relative
    Klartextpfade (instructions/session-setup.md statt [session-setup.md](../session-setup.md)) -
    sie ueberleben die Kopie unveraendert, weil sie nicht von der Position der lesenden Datei abhaengen.
    instructions/CONTRACT.md § "A skill's outbound reference is a plain path, not a link" traegt die
    Regel.

    Zwei neue mechanische Checks verhindern das Wiederauftreten: instructions verify verbietet jeden
    relativen Markdown-Link in einer SKILL.md (check_skill_reference_paths), docs verify loest
    jeden relativen Link in den flachen Instructions und Contracts gegen den Arbeitsbaum auf
    (check_reference_targets, ueber denselben Dateisatz wie docs toc). Nebenbei behoben:
    instructions/dev/doc-pull-through.md hatte zwei Links mit falscher ../-Tiefe, unabhaengig vom
    Skill-Copy-Problem.

    docs verify: der Linkziel-Check erreicht auch die instanz-eigenen kb/CONVENTIONS.md und COLLECTION.md - daher Grenzuebertritt

    Nachtraegliche Neueinstufung des Bumps darueber, kein zusaetzlicher Code. check_reference_targets
    laeuft ueber den Dateisatz von docs toc, und fuenf Dateien darin gehoeren der Instanz statt dem
    Stack: kb/CONVENTIONS.md und die vier kb/<collection>/COLLECTION.md. Ein Drop-in-Copy von
    tools/, types/, instructions/ und AGENTS.md ersetzt sie nicht - ein toter relativer Link
    darin laesst docs verify nach dem Update fehlschlagen, wo es vorher durchlief. Genau die Form,
    die tools/README.md § Adding a command Schritt 5 als MAJOR-Zeile benennt ("a stricter check that
    newly fails on shipped content an instance already had"), und instructions/dev/version-parts.md
    entscheidet den Zweifelsfall zugunsten des Grenzuebertritts.

    Gemessen bricht heute nichts: die zweite bekannte Instanz traegt 25 relative Links in diesen fuenf
    Dateien, davon null tote; dieses Repo ebenso. Die Einstufung folgt der Reichweite des Checks, nicht
    einem beobachteten Schaden - der Preis einer unnoetigen MAJOR ist eine Release-Notiz, der Preis
    einer MINOR, die doch bricht, ist eine Instanz mit fehlschlagendem Update-Pfad unter einer
    Versionsnummer, die Drop-in versprochen hat. Aufgefallen ist es in der Schlussphase beim Lesen der
    eigenen Regel in tools/README.md, nicht durch einen Check - was docs/version-model.md ueber
    genau diese Stelle sagt ("a person looking at the diff ... not a validator"), hat sich hier
    wiederholt.

    docs verify: ein nur als .template ausgeliefertes Linkziel gilt als aufgeloest

    Defektbehebung am Check aus den beiden Bumps darueber, gefunden unmittelbar nach deren Publish.
    check_reference_targets meldete auf einem frisch exportierten Baum 13 tote Links - kb/CONTRACT.md
    neunmal, dazu german-terminology.md, kb-profiles.md und link-taxonomy.md - und zwar dafuer,
    dass der Export tut, was er soll. kb/CONVENTIONS.md und die vier kb/<name>/COLLECTION.md sind
    instanz-eigen: die Distribution traegt <name>.template, und die Instanz uebernimmt sie erst im
    Personalisierungsschritt von instructions/setup-instance.md durch Umbenennen. Zwischen
    dist export und diesem Schritt existiert die fertige Datei berechtigterweise nicht, waehrend die
    stack-eigenen Dateien sie unter ihrem kuenftigen Namen verlinken - korrekt, denn so wird sie heissen.

    Ein Linkziel gilt jetzt auch dann als aufgeloest, wenn daneben <ziel>.template liegt. Die
    Ausnahme ist eng: fehlt beides, bleibt es ein Befund. Damit beschreibt der Check nicht laenger
    "noch nicht personalisiert" als "kaputter Link" - diesen Zustand meldet doctor unter
    conventions praezise und zustaendig.

    CI war davon nie rot: der Replay in .gitea/workflows/ci.yml uebernimmt die Templates, bevor er
    docs verify aufruft, und der dokumentierte Weg in setup-instance.md stellt die Personalisierung
    (Schritt 5/6) ebenfalls vor die Verifikation (Schritt 13). Getroffen haette es jeden, der nach dem
    Export einmal zur Kontrolle docs verify aufruft. Aufgefallen ist es, weil die Verifikation des
    vorherigen Publishes den Arbeitsbaum geprueft hatte und nicht den exportierten - ausgerechnet bei
    einer Aenderung, deren ganzer Gegenstand Kopien in anderer Verzeichnistiefe sind.

    TOC-Scope auf types/ und docs/ erweitert, Sprachregeln zentralisiert, --breaking akkumuliert

    Drei Straenge, ausgeloest von einer Beobachtung: manche agentengeladene Referenzdatei trug keine
    TOC, und manche Instruction war teilweise deutsch.

    TOC-Scope. Die Pflicht aus 5.0.0 galt fuer AGENTS.md, die Stage-Contracts,
    kb/CONVENTIONS.md, jede COLLECTION.md und die flache instructions/**.md-Form. docs/ und die
    Seiten-Type-Specs fielen ohne genannten Grund heraus - waehrend SKILL.md und die Menschendoku
    ihren Ausschlussgrund im Docstring stehen hatten, was die beiden anderen Luecken wie Absicht
    aussehen liess. docs/ ist dabei genau der Fall, fuer den die Schwelle existiert:
    AGENTS.md § File naming fuehrt es als agentengeladen per Link, also am zweiten Hop. Beide sind
    jetzt drin; vier Dateien haben eine Region bekommen. SKILL.md bleibt die eine Ausnahme, und
    zwar belegt statt behauptet: die vendorte Guidance setzt den SKILL.md-Body auf die Ladeebene, die
    beim Triggern ganz gelesen wird, und richtet ihren eigenen TOC-Rat an die gebuendelten
    Referenzdateien daneben. Ein Type-Spec wird zwar auch ganz geladen, aber eben auch als Datei
    gelesen - deshalb traegt es eine Region, und types describe strippt sie aus seiner Ausgabe, weil
    dort der ganze Body ohnehin mitkommt.

    Sprache. Die Regel gab es schon ("the control plane stays English"), sie stand nur in
    kb/CONVENTIONS.md - einer Datei, die der Instanz gehoert und die sie umschreiben darf, waehrend
    die Regel stackeigene Dateien bindet. Sie ist nach AGENTS.md § File naming gezogen, zusammen mit
    einer zweiten, die vorher gar nicht geschrieben stand: ein Agent spricht die KB-Sprache der
    Instanz
    . Der Wert dafuer lebt weiter in kb/CONVENTIONS.mds language:; SOUL.mds eigene
    Sprache:-Zeile war damit eine Dublette und ist weg. instructions/setup-instance.md - 297 Zeilen,
    die einzige vollstaendig deutsche Instruction, verbatim an jede Instanz ausgeliefert - ist
    uebersetzt, samt description:. Die zwei deutschen Blockquotes in den Dev-Skills sind es auch; sie
    lesen sich jetzt als englisches Modell der Nachricht, die der Agent in der KB-Sprache ausspricht.

    Dieselbe Regel gilt fuer alles, was als Template ausgeliefert wird - eine Instanz adoptiert es,
    bevor sie ihre Sprache ueberhaupt gewaehlt hat. USER.md.template, SOUL.md.template und
    ENVIRONMENT.md.template waren vollstaendig deutsch und sind uebersetzt; kb/sources/ und
    kb/concepts/COLLECTION.md waren es in Teilen und ziehen jetzt mit kb/entities/ und
    kb/comparisons/ gleich, die es laengst waren. Bei den vier Seiten-Type-Specs laeuft der Schnitt
    mitten durch die Datei, und zwar entlang derselben Prosa/Identifier-Grenze, die kb/CONTRACT.md
    schon innerhalb einer Seite zieht: die Anleitungsprosa ist Anweisung an einen Agenten und damit
    Control Plane, der ## Template-Block und die layout:-Titel sind Seitentext und bleiben in der
    KB-Sprache - wikitool new entity scaffoldet also weiter deutsche Ueberschriften.
    kb/CONVENTIONS.md behauptete bis hierher, die Type-Specs folgten als Ganzes der KB-Sprache; der
    Satz ist auf den tatsaechlichen Schnitt nachgezogen.
    Mechanisch geprueft wird nichts davon: ein Stoppwort-Scan schluege auf dem zitierten Vokabular in
    kb-profiles.md und link-taxonomy.md falsch an. Stattdessen nennen
    instructions/CONTRACT.md § "Writing an instruction" und stack-dev die Regel an der Stelle, an
    der sie befolgt oder verloren wird.

    --breaking akkumuliert. Bis hierher ersetzte ein zweites --breaking die Zeile des
    Kandidaten - der Eintrag versprach dann einen Bruch und lieferte zwei. Genau dieser Kandidat ist der
    Fall: sein Linkziel-Uebertritt aus beta.1 und der TOC-Uebertritt von hier sind zwei Dinge, auf die
    ein Betreiber getrennt reagieren muss. Eine Begruendung bleibt flach auf der Markerzeile, ab der
    zweiten werden es Bullets; eine vor dieser Aenderung geschriebene Einzelzeile liest sich unveraendert
    als Ein-Element-Liste zurueck, also musste kein bestehender Eintrag angefasst werden. --migration:
    bleibt bewusst eine Einzelzeile - sie beantwortet eine Ja/Nein-Frage ueber den Kandidaten als Ganzes,
    und --migration-required ist ihr Ruecknahmepfad. Fuer eine falsche Breaking-Begruendung gibt es
    keinen; der Kandidat ist bis zum Release dev-lokal.

    Nebenbefund, den die Scope-Erweiterung sofort aufgedeckt hat: docs/version-model.md verlinkte nach
    instructions/dev/version-parts.md, das dist export wegschneidet - im Ursprungs-Repo gruen, in
    jeder ausgelieferten Instanz ein toter Link. Jetzt ein Klartextpfad mit dem Satz, warum er keiner
    ist.

    types/type-spec.md: Ownership und Sprache getrennt benannt (Nachzug zu #99)

    types/type-spec.md sagte weiterhin, Prosa, ## Template-Body und Sprache eines
    Seiten-Type-Specs gehoerten der Instanz, die bei anderer KB-Sprache "einfach die Datei
    uebersetzt" - genau das Gegenteil des Schnitts, den der Bump davor ausgeliefert hat. Aufgefallen
    in der Schlussphase, beim Nachdenken darueber, welche Sprachregel fuer einen instanz-eigenen
    neuen Seitentyp gilt.

    Der Abschnitt trennt die zwei Fragen jetzt: Ownership sagt, wer eine Zeile aendern darf, die
    Sprache folgt davon unabhaengig dem Publikum der Zeile - Anleitungsprosa an einen Agenten ist
    Control Plane und englisch, ## Template-Body und layout:-Titel sind Seitentext in der
    KB-Sprache, Feldnamen und Enum-Werte sind Identifier und werden nie uebersetzt. Als Tabelle, weil
    der Schnitt mitten durch eine Datei laeuft und eine Aufzaehlung im Fliesstext ihn genau deshalb
    nicht haelt. Der Satz bindet ausdruecklich auch einen Type-Spec, den eine Instanz sich selbst
    schreibt: der ist zwar durchgaengig instanzeigen, aber seine Anleitungshaelfte hat trotzdem einen
    Agenten als Leser.

    Control-Plane-Sprache universell: Achse ist das Publikum, kein Instanz-Schalter

    Die Sprachregel in AGENTS.md ruhte auf einer Begruendung, die schmaler war als sie selbst:
    "Every file in the table above belongs to the stack and ships to instances that share none of
    this instance's language choices, so:". Das traegt nur fuer ausgeliefertes Material und laesst
    offen, was fuer ein Control-Plane-Dokument gilt, das eine Instanz nur fuer sich selbst schreibt -
    eine eigene Instruction, ein selbst angelegter Seitentyp (types/ nimmt einen ohne Code-Aenderung
    auf), ein weiterer Stage-Contract. Genau dort fallen Ownership und Publikum auseinander: die Datei
    ist durchgaengig instanzeigen, ihre Anleitungshaelfte hat trotzdem einen Agenten als Leser.

    Der Vorsatz nennt jetzt die tatsaechliche Achse - die For-Spalte der Tabelle darueber, also wer
    die Zeile liest, und weder wem die Datei gehoert noch ob sie den Checkout je verlaesst. Regel 1
    sagt ausdruecklich, dass sie auch fuer ein nie ausgeliefertes Control-Plane-Dokument gilt und dass
    es neben kb/CONVENTIONS.mds language: bewusst keinen zweiten Sprachwert gibt.
    kb/CONVENTIONS.md und ihr .template sagen dasselbe von ihrer Seite aus: die
    Control-Plane-Sprache ist keine Einstellung, die diese Datei zurueckhaelt - es ist gar keine.

    Die Begruendung dazu steht als neue docs/-Seite
    (docs/language-boundaries.md), weil sie sonst in einem Jahr neu
    verhandelt wird: warum Englisch (der Stack redet fast nur ueber Identifier, und die sind
    englisch), warum kein Parameter (die Kosten traegt jede Datei, den Nutzen haette ein Dokument, das
    ohnehin nur ein Agent liest), und was die Entscheidung wieder aufmachen wuerde. Die Seite haelt
    zugleich fest, welches Argument falsch war: "Sprache folgt der Ownership" hat funktioniert,
    solange nur ausgeliefertes Material betrachtet wurde, und faellt am instanz-eigenen Typ.

    Nebenbei zwei Befunde derselben Ecke behoben. Der Docstring von
    dist_cmd.instance_owned_type_stems() behauptete weiter, "its prose, its template and its
    language are the instance's business" - Stand vor dem TOC-/Sprach-Bump oben. Und die
    Aufzaehlung der docs/-Seiten in AGENTS.md sagte "Four pages exist today", waehrend das
    Verzeichnis fuenf trug: docs/model-and-effort-selection.md fehlte, und zwar absichtlich, weil
    ein Link dorthin die Claude-Code-eigene Entscheidung in die anderen drei Harnesses laden wuerde.
    Der Satz zaehlt jetzt, was von hier aus verlinkt ist, und benennt die sechste Seite samt Grund.

    types/: Seiten-Type-Spec-Anleitungsprosa in stackeigene guidance-Datei ausgelagert

    Ein root: kb Type-Spec (entity, concept, source, comparison) hatte zwei Publika in
    einer Datei: Anleitungsprosa fuer den Agenten (When to use/When NOT to use/Authoring guidance),
    und Seitenmaterial (## Template-Block, layout:-Titel). Ownership gilt pro Datei, also wurde
    die ganze Datei beim Setup als .template adoptiert und danach nie wieder angefasst - eine
    Instanz, die ihre Type-Specs frueh adoptiert hat, las bis in alle Zukunft die Anleitung vom Tag
    ihrer Erzeugung, weil dist upgrade das .template neben die adoptierte Datei schrieb, nie die
    Datei selbst (docs/ownership-and-templates.md § "Where the file boundary strains").

    Der urspruengliche Vorschlag drehte den Schnitt um (Type-Spec stackeigen, Seitenmaterial heraus)
    und wurde beim Pruefen gegen setup-instance.md und evolve-subtypes.md verworfen: die
    Frontmatter-Konfiguration (layout:, Enum-Werte, base_dir) ist instanzeigener Inhalt, keine
    Stack-Maschinerie - beide Instructions weisen die Instanz an, Enum und layout:-Eintrag in
    derselben Aenderung zu setzen. Stattdessen bleibt der Type-Spec instanzeigen, und nur die
    maschinenabgeleitete Anleitungsprosa zieht in eine neue, stackeigene types/<name>.guidance.md,
    verknuepft ueber ein optionales guidance:-Frontmatterfeld (neuer, nicht instanziierbarer Typ
    type-guidance, wie lint-report ohne base_dir:). tools/wikitool types describe <name>
    komponiert beide Haelften weiterhin zu einer Antwort - ein Agent muss nie wissen, dass ein Typ aus
    zwei Dateien besteht. type_resolver.extract_template() liest das Template unveraendert allein
    aus types/<name>.md; kein zweiter Ladepfad fuer wikitool new.

    dist_cmd._plan_types()/find_leaks() teilten sich vorher name.split(".", 1)[0] als
    Stamm-Berechnung - beides haette entity.guidance.md faelschlich als instanzeigenen Stamm
    "entity" erkannt (die eine haette sie zum .template gemacht, die andere sie als Leak gemeldet).
    Neuer gemeinsamer Prädikat _owned_type_stem() prueft die exakte Endung (<stem>.md oder
    <stem>.schema.yaml), nicht den ersten Punkt.

    Grenzuebertritt-Frage bewusst geprueft und verneint: Drop-in in beide Richtungen (ein Type-Spec
    ohne guidance: verhaelt sich unveraendert, eine alte Maschinerie liest types/<name>.md wie
    zuvor und die Guidance-Datei ist fuer sie inert), also --minor statt --major. Die einmalige
    Adoption in einer bestehenden Instanz ist als instructions/migrations/6.0.0-type-guidance-split.md
    dokumentiert - obligation: offered, der erste Gebrauch dieses seit 4.0.0 existierenden, bis jetzt
    unbenutzten Mechanismus fuer ein instanzeigenes, upgradebares Machinery-File.

    Verifiziert: tools/wikitool docs verify/instructions verify gruen, 1261 Tests gruen (8 neu:
    get_guidance, das Template bleibt auf types/<name>.md allein geladen, die Guidance-Datei
    schifft verbatim neben einem .template-adoptierten Type-Spec statt als weiteres .template,
    ein dist upgrade schreibt verbesserte Guidance-Prosa in eine adoptierte Instanz obwohl deren
    Type-Spec selbst nie im Stamp stand, types describe komponiert beide Haelften in JSON und
    Textausgabe getrennt nachweisbar).

    types/type-spec.schema.yaml enforced against real type-spec frontmatter

    Bei der Vorbereitung der Aenderung oben fiel auf: types/type-spec.schema.yaml traegt
    additionalProperties: false, kannte aber root: und capture_fields: nicht, obwohl
    types/instruction.md bzw. types/source.md beide Felder tragen und type_resolver.get_root()/
    get_capture_fields() sie lesen. Gegen das Schema validiert waeren beide Type-Specs ungueltig
    gewesen. Dass es niemandem auffiel, war der eigentliche Befund: Type-Spec-Frontmatter wurde
    nirgends gegen sein eigenes Schema validiert - resolver.validate_frontmatter() lief nur ueber
    kb/-Seiten, neu erzeugte Seiten und Instruktionsdateien, nie ueber die Type-Specs selbst.
    TypeResolver._validate_type_spec(), der einzige Weg, den der Selbstbezug type: types/type-spec.md
    nimmt, prueft ausschliesslich, ob type/name/description vorhanden sind.

    Beide fehlenden Felder ergaenzt (root: als Enum kb/repo, capture_fields: als Liste wie
    page_ref_fields:), dazu guidance: (seit der Aenderung oben real benutzt, aber noch nie im
    Schema). docs verify bekommt eine neue Pruefung: jede Datei unter types/ mit
    type: types/type-spec.md validiert jetzt gegen types/type-spec.schema.yaml
    (check_type_spec_frontmatter(), wiederverwendet resolver.list_type_specs() statt eines zweiten
    Parse-Durchlaufs). types/type-spec.md § Validation Contract und die beiden docs verify-Zeilen
    in tools/CONTRACT.md nennen das jetzt.

    Daneben ein zweiter, unabhaengiger Befund derselben Aufraeumrunde behoben:
    instructions/dev/doc-pull-through.md verwies fuer docs/-Seiten weiter auf "AGENTS.md § File
    naming lists all four" - der Zaehler in AGENTS.md selbst war beim vorigen Bump schon auf fuenf
    (plus eine sechste, nur von CLAUDE.md aus verlinkte) korrigiert worden, diese eine verbliebene
    Stelle nicht.

    Grenzuebertritt-Frage geprueft und verneint: additiv in beide Richtungen - eine bestehende Instanz
    validiert bereits (0 Befunde gegen den realen Baum), und ein Type-Spec ohne die drei neuen Felder
    bleibt unveraendert gueltig. --patch, kein --breaking, keine neue Migration noetig.

    Verifiziert: tools/wikitool docs verify/instructions verify gruen, 1263 Tests gruen (2 neu:
    alle Type-Specs dieses Repos validieren gegen ihr eigenes Schema; ein Type-Spec mit einem dem
    Schema unbekannten Feld wird gemeldet, mit Dateiname und Feldname in der Meldung).

    search: Pfad und Titel vollstaendig, Trunkierung sichtbar

    Gemeldet wurde eine Sitzung, die nach wikitool search zusaetzlich grep -rl ueber kb/
    laufen liess. Der Grep war redundant - search ist ein rg-Lauf ueber kb/ und kann keine
    Seite verfehlen, die ein Grep findet -, aber die Ausgabe gab ihr drei Gruende dafuer, und die
    sind der eigentliche Befund.

    Die Tabelle nannte keinen Pfad, obwohl wiki-query verlangt, nur die Seiten zu lesen, auf
    die die Suche zeigt. Sie kappte ausserdem den Titel auf 34 Zeichen - im gemeldeten
    Transkript vier von fuenf Treffern -, und der Titel ist nach Invariante 2 der einzige
    Identifier einer Seite und das Argument, das touch, xref add und cite add nehmen. Die
    Sitzung hatte also weder etwas zum Oeffnen noch etwas zum Weiterreichen; grep -rl lieferte
    genau beides.

    Drittens war N result(s). die gekappte Zahl: run_search gab nur die beschnittene Liste
    zurueck, also konnte kein Adapter die Gesamtzahl melden, und 20 result(s). auf einer Anfrage
    mit 182 Treffern war von einem vollstaendigen Ergebnis nicht zu unterscheiden. Eine
    Vollstaendigkeitsaussage, zu der die Ausgabe nicht berechtigt war - der staerkste denkbare
    Anlass, ihr zu misstrauen.

    Die Zeile hat jetzt die Form score | kind/subtype | titel | pfad | summary, ohne
    Spaltenauffuellung. Titel und Pfad werden nie gekappt; die Summary ist das einzige verlustige
    Feld und steht deshalb am Ende, wo ein | in Prosa beim Trennen mit maxsplit=4 folgenlos
    bleibt (ein | im Titel schliesst die Wikilink-Syntax ohnehin aus). JSON als Default-Ausgabe
    wurde erwogen und verworfen: ein Treffer ist flach, JSON kostet dafuer ein Vielfaches an Tokens,
    und search existiert dafuer, Retrieval billig zu machen - der Fehler war ein fehlendes Feld,
    kein Parse-Problem. Wer Struktur braucht, hat --json, api.search und MCP.

    run_search gibt jetzt ein SearchResult mit Treffern, Gesamtzahl und Limit zurueck. Die
    Tabelle schreibt 50 of 182 result(s) - raise --limit (0 for all) or narrow the query., das
    JSON traegt total/truncated/limit neben count, dessen Bedeutung unveraendert bleibt
    (len(results)), und api.search sowie der MCP-search-Tool tragen dieselben Felder. Das
    Default-Limit steigt von 20 auf 50 und liegt als eine Konstante DEFAULT_LIMIT statt als drei
    Literale in drei Adaptern: gekappt wurden bisher vor allem die strukturellen Sweeps
    (--field '!sources'), die alphabetisch und nicht nach Relevanz sortiert sind, wo die Kappung
    also eine beliebige Scheibe der Antwort wegwirft statt ihres schwaechsten Endes. Sichtbar zu
    sein ist es, was ein endliches Default ueberhaupt erst unbedenklich macht.

    AGENTS.md § Routing traegt die Regel an genau einer Stelle - search ist erschoepfend, ein
    eigener Grep ueber kb/ fuegt nur die generierten Dateien hinzu, die Invariante 1 ohnehin
    verbietet; tools/CONTRACT.md traegt daneben nur den Mechanismus.

    Grenzuebertritt-Frage geprueft und verneint: kein Flag entfernt oder umbenannt, keine
    Umgebungsvariable, keine maschinengelesene Datei in ihrer Form veraendert, JSON rein additiv.
    Die Tabelle liest ein Agent, kein Skript, und ihre Aenderung verlangt keiner Instanz Handarbeit
    ab.

    Verifiziert: docs verify/instructions verify gruen, 1272 Tests gruen (9 neu: Pfad vorhanden;
    Titel und Pfad ungekappt bei langem Titel; eine Trefferzeile zerfaellt trotz | in der Prosa in
    ihre fuenf Felder; ein gekapptes Ergebnis nennt die Gesamtzahl, ein ungekapptes behauptet
    nichts; --limit 0 gilt nie als gekappt; die Gesamtzahl ueberlebt das Limit in run_search;
    api.search meldet dasselbe; alle drei Adapter teilen ein Default-Limit - der MCP-Golden-Test
    haelt die neuen Felder zwischen CLI und Server zusammen).


    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
  • v5.1.0 1b0158fc8d

    v5.1.0
    CI / verify (push) Successful in 50s
    Release / release (push) Successful in 38s
    Stable

    torben released this 2026-09-12 16:27:52 +00:00 | 231 commits to main since this release

    5.1.0 - 2026-09-12 - changelog: Kandidaten-Eintrag nach Impact gruppiert, version regrade zur Nachkorrektur, version release verlangt eine Zusammenfassung

    Author: Torben Nehmer

    High impact

    • changelog: Kandidaten-Eintrag nach Impact gruppiert, version regrade zur Nachkorrektur, version release verlangt eine Zusammenfassung

    Seit 4.4.0 sammelt ein laufender Kandidat alle Bumps in einem Eintrag; bei 5.0.0 wurde das
    mit 20 Bumps und ~1440 Zeilen unlesbar, weil die Liste chronologisch und ungewichtet war und die
    Release-Seite genau diesen Eintrag 1:1 uebernimmt (version notes, release.yml). Der Eintrag
    ist jetzt geschichtet statt einer einzigen Wand Text: version bump --impact high|medium|low
    (Default medium) graduiert jeden Bump, die Liste rendert nach High/Medium/Low gruppiert - ausser
    wenn alles medium ist, dann bleibt sie flach wie bisher, damit jeder alte Eintrag und jeder
    einfache Patch unveraendert bleibt. version regrade korrigiert eine Note im Nachhinein, gegen
    einen einzelnen Lesevorgang der ganzen Liste, bevor der Kandidat geschlossen wird. Direkt unter
    der Liste steht jetzt eine kurze Zusammenfassung, darunter je Bump ein eigener
    ### <Bump-Titel>-Changeset-Absatz; version release verweigert das Schliessen eines Kandidaten
    mit zwei oder mehr Bumps, solange diese Zusammenfassung fehlt (ein Kandidat mit genau einem Bump
    ist ausgenommen - sein Changeset ist bereits die Zusammenfassung, wie hier). Geschlossene
    Eintraege wie der zu 5.0.0 bleiben in der alten Form stehen: die Release-Seiten sind laut
    eigenem Footer unveraenderliche Snapshots, und instructions/dev/version-parts.md sowie
    docs/version-model.md zitieren den 2.0.0-Eintrag mit Abschnittsnamen.

    --breaking/**Migration:** sitzen jetzt oberhalb der Bump-Liste statt darunter, damit die fuer
    einen Operator wichtigste Zeile nicht unter einer moeglicherweise langen Liste verschwindet.


    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