raw/notes/Conversation Transcript - Versioning, CI-CD and Content Migration Session 2026-08-30.md
en
2026-08-30
versioning
ci-cd
migration
gitea
wikitool
release
wikitool
Chemenu
Act Runner
Gitea Actions
Gitea
Gitea MCP Server
Claude Code
KB Stack Versioning
KB Migration
Mass-Update Gate
CI Integration
Sitzung, die Stack-Versionierung mit CI und Release-Artefakten baut, sie um eine getrennte KB-Versionierung mit Migrationskette ergaenzt und die Gitea-Actions-Pipeline in Betrieb nimmt
verbatim
reporting
Source: Conversation - Versioning CI-CD and Content Migration Session 2026-08-30
Autor: Claude Code (claude-opus-5) Datum: 2026-08-30 Raw-Dateien: raw/notes/Conversation Transcript - Versioning, CI-CD and Content Migration Session 2026-08-30.md Typ: Notes
Zusammenfassung
Das Transkript ist eine vom Assistenten am Sitzungsende rekonstruierte Zusammenfassung, kein
wörtliches Protokoll; Befehlsausgaben darin sind echt, Torbens Fragen und Entscheidungen sind
eng wiedergegeben, die Begründungen des Assistenten verdichtet. Die Sitzung lief vom 2026-08-29
bis 2026-08-30 und deckt drei Arbeitspakete ab, die sich als dieselbe Mechanik von verschiedenen
Seiten erwiesen: Versionierung des Stacks mit CI und Release-Artefakten (ausgeliefert als
0.1.0, dann 1.0.0), eine darauf aufsetzende Content-Migrationsstrategie und schließlich das
Inbetriebnehmen der Pipeline. Resultierende Commits: 2508f7a, 7d63d61, c3034ab, db03b08,
aace3e7, 401d700, b94166b.
Der erste Entwurf versionierte nur den Stack. Torben verwarf ihn mit der Frage, wo die aktuelle
Version einer KB gespeichert wird und wie eine KB über mehrere Versionen hinweg aktualisiert
wird. Das legte einen Fehler offen: Stack- und Content-Version waren zusammengeworfen, obwohl
eine Instanz Maschinerie 1.4.0 tragen kann, während ihr Inhalt noch in 1.2.0-Form vorliegt -
genau der Zustand, den jedes Upgrade durchläuft. Der zweite Entwurf trennt drei Fakten in drei
Dateien und baut die Migrationskette als geordnetes Intervall. Er wurde freigegeben und
umgesetzt.
Parallel wurde die Gitea-Actions-Pipeline gegen den Runner auf ci-runner.example.net gebracht.
Die Diagnose über den neu verfügbaren Gitea-MCP-Server ergab das Gegenteil der Annahme: Die
Runner hatten die Workflows die ganze Zeit angenommen und scheiterten am Checkout, weil
actions/checkout eine JavaScript-Action ist, die act_runner mit node im Job-Container
ausführt - und das gepinnte debian:trixie-slim bringt keins mit. Der erste Lauf, der bis
pytest kam, fand einen echten Fehler in zwei Tests, die auf jeder Entwicklermaschine
monatelang grün gewesen waren.
Kernaussagen
Die Version beschreibt den Stack; der Content hat seine eigene Version. Drei Fakten, drei
Dateien: VERSION (welche Maschinerie installiert ist, geschrieben von version bump),
.wikitool-release.json (woher sie kam, erzeugt von dist export) und .wikitool-kb.json
(in welcher Form der Inhalt vorliegt, geschrieben von migrate done). Getrennte Dateien, weil
der Release-Stempel erzeugt ist und nie von Hand geändert werden darf, der KB-Zustand dagegen
veränderlicher Instanzzustand ist.
Kompatibilität ist die linkeste Nicht-Null-Komponente - dieselbe Regel, die Cargos
Caret-Ranges verwenden. Sie gilt einheitlich für 0.x und 1.x; ab 1.0.0 liest sie sich als
gewöhnliches Semver. Keine Pre-Release-Suffixe, weil eine zweite Ordnungsregel vom Release-Feed,
von der Migrationskette und von der Kompatibilitätsprüfung gleichermaßen befolgt werden müsste.
Die Migrationskette ist ein Intervall, keine Fallunterscheidung.migrate status bildet
(kb_version, VERSION] aus den Migrationsdokumenten und ordnet aufsteigend; von 1.3.1 nach
2.0.0 laufen 1.4.0, 1.7.0, 2.0.0 nacheinander. Dass keine Migration auf 1.3.x zielt,
ist kein Sonderfall, sondern schlicht nicht im Intervall. migrate done verweigert jede
Version, die nicht das nächste Glied ist - damit ist ein Sprung unmöglich und ein
unterbrochenes mehrstufiges Upgrade fortsetzbar.
Zählen, nicht Mengen vergleichen.kb_scan.extract_wikilinks() liefert ein Set. Das ist
richtig für lint (löst der Verweis auf?) und falsch für eine Migrationsprüfung (ist einer
verschwunden?). Drei der vier Defekte, die die frühere Übersetzung fand, hatten unveränderte
Link-Mengen und nur veränderte Zählungen.
Der Runner nahm die Workflows immer an.actions/checkout ist eine JavaScript-Action, die
act_runner mit nodeim Job-Container ausführt; das gepinnte debian:trixie-slim hat
keins, daher exec: "node": executable file not found in $PATH und exitcode '127'. Die
Lösung war eine Zeile in einer apt-Liste: nodejsvor dem Checkout installieren, plus
actions/checkout@v7. runs-on: linux-docker blieb, weil die Läufe 46-51 bewiesen, dass das
Label routet und den Container startet.
Ein CI-Lauf ist Evidenz, ein lokaler Lauf ist Gewohnheit. Lauf 52 kam als erster bis
pytest und ließ zwei von 630 Tests fallen: config.default_author() ruft git config user.name mit cwd=config.ROOT, das Fixture-Root ist kein Repository, also antwortete die
globale git-Konfiguration dessen, der die Suite ausführte. Im Container als root gibt es keine.
Behoben in den Tests, nicht durch eine git-Identität für CI: Das hätte den Lauf grün gemacht
und den Fehler stehen gelassen.
Das Origin-Repository ist privat, und Gitea antwortet anonym identisch mit 404 für ein
unsichtbares und für ein nicht existierendes Repository. curl beweist damit nichts über den
CI-Zustand; Läufe werden über den Gitea-MCP-Server gelesen. WIKITOOL_UPDATE_TOKEN ist
dadurch Voraussetzung statt Ausnahme.
${{ gitea.token }} genügt für Releases, Tags und Asset-Uploads. Kein Actions-Secret mit
write:repository nötig. Belegt dadurch, dass release.yml beim Versionssprung auf 1.0.1
von selbst feuerte und llm-wiki-stack-1.0.1.tar.gz samt .sha256 hochlud.
paths-ignore scheitert bewusst offen. Die Liste steht zweimal statt einmal über einen
YAML-Anker, weil GitHubs Parser Anker ablehnt und Gitea sie nicht dokumentiert akzeptiert; es
gibt keine !**/CONTRACT.md-Negation, weil Gitea negierte Filtermuster nicht dokumentiert; und
kb/CONTRACT.md ist absichtlich nicht ausgenommen, weil es unter einem Content-Verzeichnis
liegt, aber zum Stack gehört. Alles Unvorhergesehene löst weiterhin CI aus.
Die verworfene Methodik lag im git-Verlauf. Der geschlossene Workshop translate-kb-de
wurde aus de0862f zurückgeholt und trug eine vollständige Arbeitsweise: Einheiten nach dem
Iterationsbudget geschnitten, Batches getrennt davon nach dem Mass-Update Gate, Frontmatter/H1/
Wikilink-Ziele/Cite-IDs vor allem anderen gegen HEAD geprüft, lint über jede Einheit
vollständig gelesen, und Zusammenfassungen von der orchestrierenden Sitzung geschrieben statt
von einem Subagenten übernommen.
Aufgaben
Gitea-Issue #7 - dist upgrade bauen (in dieser Sitzung bewusst zurückgestellt)
Gitea-Issue #8 - Testsuite gegen stille Umgebungsabhängigkeiten härten
Gitea-Issue #11 - bestätigen, dass Gitea die paths-ignore-Muster wie erwartet auswertet;
ausdrücklich als Beobachtung geführt, nicht als Bauaufgabe - der Beleg kommt beim nächsten
reinen Content-Publish von selbst
Nicht übernommen
Die turn-für-turn-Struktur des Transkripts. Der Verlauf der Sitzung ist Chronologie, keine
dauerhafte Aussage; die Entscheidungen wurden auf die Concept- und Entity-Seiten gehoben, die
Reihenfolge blieb hier.
Die Commit-Hashes einzelner Zwischenschritte (2508f7a, 7d63d61, db03b08) über die
Zusammenfassung hinaus. Der git-Verlauf und CHANGES.md führen sie bereits; eine zweite Kopie
in kb/ wäre der driftende Doppeleintrag, den der Stack sonst überall vermeidet.
Die Modul- und Dateiliste der Implementierung (corpus_diff.py, kb_state.py,
migrate_cmd.py) unterhalb dessen, was die Concept-Seiten zum Verständnis brauchen. Die
Codestruktur ist im Repository nachlesbar und veraltet in kb/ schneller als dort.
Die Zahlen der Verifikationsläufe (248 verglichene Seiten, 2,2 s, 630 Tests, 29 gezählte
Dateien am Mass-Update Gate). Sie belegen einen Stichtag, nicht eine Eigenschaft; nur die
Negativkontrolle 'Docker' 2->1 bei gleichzeitig stillem lint wurde übernommen, weil sie die
Aussage trägt, auf der die Strategie ruht.
Die Korrektur der Modellzuschreibung in der Kopfzeile des Transkripts (erste Fassung nannte
„Claude Sonnet 5", das Sitzungslog claude-opus-5). Sie betrifft die Quelle selbst und ist
über author: bereits festgehalten.