Upgrade-Lauf 5.0.0 -> 6.0.0 auf ausgelieferter Instanz: Laufbericht, Telemetrie, sieben Befunde #107
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Zweck
Vollstaendig getracete Durchfuehrung des dokumentierten Upgrade-Pfads (INSTALL.md § "Eine Instanz
aktualisieren", Weg Tarball) auf einer echten ausgelieferten Instanz - nicht im Ursprungs-Repo
und nicht im CI-Replay. Ziel ist eine Validierungsgrundlage, gegen die derselbe Lauf auf einer
Dev-Instanz nachgestellt werden kann.
Die Telemetrie des Laufs steht verbatim im ersten Kommentar. Sieben Befunde unten; keiner hat den
Lauf zum Scheitern gebracht, vier davon kosten jede Instanz Handarbeit, die der dokumentierte Weg
nicht vorsieht.
Ausgangslage: Instanz aus
dist export-Tarball,VERSION5.0.0,kb_version5.0.0,63 Seiten,
language: de, Harness Claude Code, sauberer Arbeitsbaum, ein Remote.Herkunft der Befunde. 1 bis 4 stammen aus dem Lauf selbst (2026-09-15). 5 bis 7 und die
Ursachenanalyse unter Befund 1 stammen aus der Review-Sitzung vom 2026-09-16, die das
Sitzungstranskript, die drei Ergebnis-Commits und den Endzustand der Instanz gegengelesen hat.
Stand. Erledigt sind Befund 7 (in #108 abgeschlossen,
504149c,6.1.0-beta.1: derUpgrade-Pfad hat mit
instructions/upgrade-instance.mdeine agentengerichtete Prozedur), derAnleitungsteil von Befund 1 (
instructions/session-setup.mdtraegt die Inline-Form) und Befund 5(in der Instanz repariert,
b5014d9). Offen bleiben die Werkzeug- und Doku-Aenderungen zu 1, 2,3, 4 und 6.
Lauf-Zusammenfassung
version checkmigrate statusversion notesdist upgrade --dry-rundist upgradedist upgrade --dry-rungit commitder Handreparaturdist upgrade --dry-rundist upgrademigrate statusinstructions syncdoctorsession-id)docs verifytypes/concept.md,types/source.mddocs toc --applydocs verify/instructions verify/lintpublish96e2563ff596publish --confirmdcc17df, gepusht6.0.0-type-guidance-splitmigrate done 6.0.0 --pages 0publishc8c9f9b, 5 Dateien, unter der Gate-Schwelle33
wikitool.call-Events insgesamt, ein einziger unerwarteter Exit-Code (types describe source,Exit 1 um 20:06:09 - das war SIGPIPE durch ein
| headdes Aufrufers, kein Werkzeugfehler; sieheAnmerkung unter Befund 1 und die Ursachenverkettung in Befund 6).
Nicht in der Tabelle, weil nie gelaufen:
migrate verify --from <commit vor dem Tausch>,INSTALL.md Schritt 6, erster Pruefschritt. Siehe Befund 7.
Befund 1: Session-Id-Fallback zersplittert den Lauf - Join-Key tot, Iteration-Budget-Gate faktisch abgeschaltet
kind/defect, der schwerwiegendste der sieben. Verwandt mit #82, aber nicht davon abgedeckt.Beobachtung
Der Lauf ist eine Sitzung. Die Telemetrie kennt ihn als 21 Sitzungen:
Aufgeschluesselt nach Quelle:
claude-code(Hook)session.start, 5prompt.submittedwikitool(Emitter)session.start, 33wikitool.call, 1gate.refused, 1gate.cleared, 2publish.commitWIKITOOL_SESSION_IDwar nicht gesetzt, der Fallback ist die Parent-PID(
chemenu/session.py). Der Harness startet pro Tool-Call eine neue Shell - also pro Aufrufeine neue PID und damit eine neue "Sitzung".
Folge 1: EVALS.md' Join-Key haelt nicht
EVALS.md§ Architecture: "Everything joins onWIKITOOL_SESSION_ID." In diesem Lauf jointnichts: die Hook-Events tragen die UUID, die wikitool-Events tragen 20 PIDs. Es gibt keinen
gemeinsamen Schluessel.
Das ist im Scorer direkt sichtbar.
eval score --session 3835548(die Sitzung mit derGate-Verweigerung) meldet:
Der Harness hat
prompt.submittedgemeldet - 5 mal, nur unter der UUID. Ausgerechnet dieL2-Regel, die Gate-Befolgung prueft, kann auf dem Hauptharness nie ein Urteil faellen. Das ist
kein fehlender Hook (#82), sondern ein toter Schluessel: #82 wuerde
tool.pre/tool.postergaenzen, die dann ebenfalls unter der UUID landen und weiterhin nicht zu den
wikitool.call-Events joinen. Die beiden Issues muessen zusammen gedacht werden, sonstverdrahtet #82 Hooks, deren Events immer noch niemand zuordnen kann.
Ausserdem scort
eval scorejeweils 1 bis 3 Calls statt 33, waehrend die L1-Strukturpruefung inallen 21 Buckets identisch neu berechnet wird. Ein Lauf ist so nicht bewertbar.
Folge 2: das Iteration-Budget-Gate erreicht seine Schwelle nie
Gravierender, weil es eine der vier in Code gegossenen Sicherungen ist (
AGENTS.md§ Gates:60 Calls pro Sitzung, Loop-Breaker bei 3 identischen in Folge).
tools/.wikitool_session/budget.json, Stand nach dem Lauf:Der Hoechststand ist 9 - und der stammt aus
wiki-setup-nathan, einem Bucket, in demWIKITOOL_SESSION_IDgesetzt war. Jeder PID-Bucket kommt ueber 3 nicht hinaus. Bei 33Calls in einem Lauf hat der Zaehler also nie mehr als 3 von 60 gesehen.
Damit ist das Gate unter diesem Harness nicht "grosszuegig", sondern strukturell
unerreichbar - und der Loop-Breaker gleich mit: drei identische Calls in Folge landen in drei
verschiedenen Buckets. Eine Sicherung, die ausdruecklich deshalb in Code sitzt, weil ein Agent
sich an einer Prompt-Regel vorbeireden kann (
docs/why-gates-are-code.md), ist hier still aus.doctorsagt das Noetige bereits - nur als WARN und ohne die Folge zu nennen:Ursache eine Ebene tiefer:
instructions/session-setup.mdwar auf diesem Harness wirkungslosNachgetragen aus der Review-Sitzung.
doctorverweist aufinstructions/session-setup.md, unddort stand als Schritt, woertlich:
"Run this once per working session" - genau das funktioniert auf Claude Code nicht. Der
Harness fuehrt jeden Bash-Tool-Call in einer frisch initialisierten Shell aus; das
Arbeitsverzeichnis wird uebernommen, Shell-State (Umgebungsvariablen, Funktionen) nicht. Ein
exportin Aufruf N ist in Aufruf N+1 verschwunden. Die 20 verschiedenen Parent-PIDs oben sinddieselbe Tatsache von der anderen Seite gemessen.
Das aendert die Reichweite des Befunds: eine bessere Fallback-Kette repariert den Messwert, aber
die Anleitung, die das Problem eigentlich verhindern soll, war auf dem Hauptharness ein No-op.
Erledigt mit
504149c(6.1.0-beta.1, aus #108):instructions/session-setup.mdnennt jetztdie Inline-Form pro Aufruf, sagt warum ein
exportnur traegt solange die Shell traegt, und gibtden Einzeiler an, mit dem sich beantworten laesst, welcher Fall vorliegt. Der Rest dieses Befunds -
Fallback-Kette, Join-Key, WARN-Haerte - ist davon unberuehrt und weiter offen.
Nebenbefund zur Trace-Treue
types describe sourcesteht mitexit_code: 1in der Trace (20:06:09). Der Aufruf warerfolgreich; der Exit-Code entstand durch SIGPIPE, weil der Aufrufer die Ausgabe durch
| headgeschickt hat. Der unmittelbar folgende identische Aufruf ohne Pipe steht mit
exit_code: 0da.Wer die Trace als Fehlerquelle auswertet, zaehlt hier einen Werkzeugfehler, den es nicht gab.
Dasselbe
| headist die Ursache von Befund 5 - siehe Befund 6.Loesungsrichtung
Nicht ausgearbeitet - das ist eine Betreiberentscheidung. Denkbare Achsen: eine stabilere
Fallback-Kette vor der PID (Git-Branch + Arbeitsbaum, eine Sitzungsdatei im Checkout, die
CLAUDE_SESSION_ID-artige Umgebungsvariable des jeweiligen Harness), oderdoctor/publishdiefehlende
WIKITOOL_SESSION_IDhaerter melden lassen als mit einem WARN. Was davon traegt, gehoertgegen #82 zusammen entschieden.
Befund 2:
version notesscheitert auf jeder ausgelieferten Instanz, obwohl INSTALL.md Schritt 4 darauf verweistkind/defect- Doku und Realitaet widersprechen sich.INSTALL.md § "Eine Instanz aktualisieren", Schritt 4, verbatim (Stand des Laufs):
Der Aufruf auf der Instanz:
Ursache
version notesliest die lokaleCHANGES.md. Eine ausgelieferte Instanz bekommt dafuer denStub aus
tools/chemenu/dist_templates/CHANGES.md- 9 Zeilen, Vorwort, null Versionseintraege:CHANGES.mdsteht ausserdem inchemenu.ownership.is_upgrade_preserved, wird vondist upgradealso bewusst nie ueberschrieben. Der Stub bleibt der Stub - dauerhaft.
version noteskannauf einer Instanz nicht nur heute nicht funktionieren, sondern nie.
Das trifft genau den Moment, fuer den der Schritt existiert: den Grenzuebertritt, an dem der
Betreiber wissen muss, was aufhoert zu funktionieren. Der Lauf hier kam nur weiter, weil die
Release-Notes ueber die Gitea-API gelesen wurden - ein Weg, den INSTALL.md an dieser Stelle nicht
nannte, und den eine Instanz ohne erreichbaren MCP-Server gar nicht hat.
Stand
Der widersprechende Schritt 4 existiert nicht mehr: INSTALL.md verweist fuer die Durchfuehrung
seit
504149caufinstructions/upgrade-instance.md, deren Schritt 2 die Release-Seite ausrelease_urlliest und ausdruecklich sagt, dassversion notesauf einer Instanz nicht antwortet.INSTALL.md § "Version und Updates" sagt dasselbe jetzt beim Befehl dazu. Der Defekt selbst ist
damit nicht behoben, nur nicht mehr falsch dokumentiert.
Loesungsvorschlag
Entweder
version notesfaellt auf den Release-Feed zurueck, wenn die lokaleCHANGES.mddenEintrag nicht hat (die URL steht bereits in
.wikitool-release.jsonalsupdate_url/release_url,und
version checkfragt sie ohnehin ab) - oder es bleibt bei der Doku-Antwort und der Befehl sagtim Fehlerfall selbst, wo die Notes stattdessen stehen. Ersteres ist freundlicher, Letzteres
billiger.
Befund 3:
dist upgradekennt keinen Weg, die Release-Fassung einer lokal geaenderten Datei zu uebernehmenkind/defect/ fehlende Faehigkeit.Beobachtung
Der Dry-Run meldete genau eine lokal geaenderte Datei:
Der Unterschied war reine Whitespace-Formatierung einer Markdown-Tabelle (Spaltenauffuellung,
vermutlich ein Format-on-Save), inhaltlich identisch.
kb/CONTRACT.mdist dabei stackeigen:instructions/private-instance.mdfuehrt<stage>/CONTRACT.mdausdruecklich als Maschinerie, ander "an instance never edits it".
Der Lauf ohne Flag:
Beide angebotenen Wege sind hier falsch:
--keep-localbehaelt die Drift. Lauttools/CONTRACT.mdschreibt der neue Stamp trotzdemdie Release-Digest - die Datei divergiert also bei jedem kuenftigen
dist upgradeerneut undwird jedes Mal wieder gemeldet. Fuer eine Datei, die der Instanz gar nicht gehoert, ist das der
dauerhaft falsche Zustand.
tun musste:
Drei Schritte, zwei davon ausserhalb des Werkzeugs, plus ein Extra-Commit (
7fe8353) nur um dieVorbedingung des naechsten Kommandos herzustellen. Die Sauberkeits-Vorbedingung und die
Handreparatur stehen sich dabei gegenseitig im Weg: die Reparatur macht den Baum unsauber, den das
Kommando sauber verlangt.
Der Preis war eine Invariantenverletzung
Nachgetragen aus der Review-Sitzung, und das schaerfste Argument fuer eine Werkzeugloesung: der
Commit
7fe8353ist ein rohesgit add+git commit.AGENTS.mdInvariante 5 sagt "Nevercall raw
git commit/git push. Publish throughtools/wikitool publish" und kennt keineAusnahme fuer "ist ja nur eine Vorbedingung". Der richtige Weg haette
tools/wikitool publish --no-pushgeheissen.Bemerkenswert ist weniger der Fehlgriff als die Richtung: eine fehlende Werkzeugfaehigkeit hat den
Lauf an einer in Code gegossenen Regel vorbeigefuehrt, und nichts hat es gemeldet - kein Gate, kein
Check, kein Scorer. Solange der Fall Handarbeit bleibt, bleibt auch dieser Zug naheliegend.
instructions/upgrade-instance.mdSchritt 6 schreibt seit504149causdruecklichpublish --no-pushvor; das ist eine Anleitung, keine Sicherung.Erwartungshaltung, nachgetragen aus dem Transkript
Der Agent kuendigte um 19:46:28, vor dem Lauf ohne Flag, woertlich an: "I'll let the upgrade
take the release's version rather than pinning the local formatting" - und rief
dist upgradedann ohne Flag auf. Das Mentalmodell war also "Default = Release-Fassung nehmen"; der Default ist
Abbruch. Die Fehlermeldung korrigiert das nicht: sie nennt
--keep-localund "reconcile by hand",sagt aber nicht, dass es zu
--keep-localkein Gegenstueck gibt. Es fehlt damit nicht nur einFlag, sondern auch der Satz, der die falsche Erwartung abfaengt.
Loesungsvorschlag
Ein Gegenstueck zu
--keep-local, das die andere Antwort erlaubt - etwa--take-release [<pfad>...]: nimm fuer diese Pfade die Release-Fassung und schreibe sie, statt denLauf abzubrechen. Dann ist der Fall "stackeigene Datei ist versehentlich lokal veraendert worden"
in einem Kommando erledigt, statt in drei Handgriffen - und ohne einen Commit, der die Invariante
streift.
Offen und bewusst nicht mitentschieden: ob die Dirty-Tree-Vorbedingung dafuer gelockert werden
muesste. Mit
--take-releaseentfaellt die Handreparatur, also auch der unsaubere Baum - dieVorbedingung kann bleiben, wie sie ist.
Befund 4:
6.0.0-type-guidance-splitnennt ein Beispiel, das in der Instanz das Gegenteil zeigtkind/defect, Dokumentation. Betrifft das mitgelieferte Migrationsdokument, nicht den Code.4a - das benannte Beispiel ist in der Instanz die unmigrierte Datei
instructions/migrations/6.0.0-type-guidance-split.md, Schritt 4, verbatim:Im Ursprungs-Repo stimmt das: dort ist
types/entity.mddie stackeigene, bereits migrierte Datei.In einer ausgelieferten Instanz ist
types/entity.mddie beim Setup adoptierte Kopie - alsogenau die Datei, die noch die alte, zu entfernende Prosa traegt. Wer dem Satz woertlich folgt,
schreibt den Vorher-Zustand ab.
Das gesuchte Beispiel liegt in der Instanz unter
types/entity.md.template- dort steht derNachher-Zustand (Pointer-Absatz,
guidance:-Feld in der Frontmatter), weildist upgradedieTemplates verbatim mitliefert.
Verschaerfung aus der Review-Sitzung: im Ursprungs-Repo existiert ueberhaupt keine
types/*.md.template-Datei -dist exportre-keyttypes/<name>.mderst beim Export zur.template(dist_cmd._owned_type_stem). Der Satz kann in einer Instanz also nicht blossunguenstig sein, er kann dort strukturell nie stimmen.
Vorschlag: den Verweis auf
types/entity.md.templateumstellen und den Grund danebenschreiben -das ist dieselbe
.mdvs..md.template-Verwechslung, an der auch #106 hing, nur von deranderen Seite.
4b - die Sprachfrage bleibt offen, direkt nachdem 6.0.0 sie verschoben hat
Das Dokument sagt nicht, in welcher Sprache der neue Pointer-Absatz zu schreiben ist. Fuer eine
Instanz mit
language: deist das nicht ableitbar, denn 6.0.0 hat diese Grenze gerade erst neugezogen (Bump "Control-Plane-Sprache universell",
docs/language-boundaries.md): Anleitungsprosaist Control Plane und englisch,
## Template-Body undlayout:-Titel sind Seitentext in derKB-Sprache.
Der Lauf hat daraus abgeleitet - und das sollte im Dokument stehen, nicht abgeleitet werden
muessen:
## Frontmatter-Tabelle## Template-Block + NachsatzGenau so wurde es umgesetzt - mit einer Ausnahme, die erst die Review-Sitzung gefunden hat, und die
zeigt, dass die Luecke im Dokument tatsaechlich Schaden anrichtet: siehe Befund 5.
4c - kleinere Beobachtung zur Schrittfolge
Schritt 6 (
migrate done 6.0.0 --pages 0) tut genau, was es verspricht, und die Ausgabe istunmissverstaendlich:
Danach bleibt
doctorbeikb-version: 5.0.0 (nothing outstanding up to 6.0.0). Das ist korrektund dokumentiert, sieht aber auf den ersten Blick nach einem haengengebliebenen Upgrade aus. Keine
Aenderung noetig - hier nur vermerkt, weil eine Dev-Instanz-Validierung sonst darueber stolpert.
Befund 5: die Migration hat in
types/source.mdeinen Rest-Abschnitt hinterlassen - repariert in der Instanz (b5014d9)kind/defect, Instanzschaden. Gefunden in der Review-Sitzung, live gegengeprueft und dort auchbehoben. Steht hier, weil er die Wirkung von Befund 4b und Befund 6 belegt.
Bei
types/source.mdwurde der Abschnitt## Autorenanweisungennicht geloescht, sondern zu## Authoring guidanceumbenannt, mit einem verbliebenen deutschen Bullet:Zwei Fehler in drei Zeilen:
Normalzustand und kein Befund:
types describesetzt selbst einen## Authoring guidance-Kopf und inlined darunter die Guidance-Datei, die ihren eigenen gleichnamigenAbschnitt mitbringt - so sieht es bei allen vier Typen aus.
sourcehatte danach einendritten aus dem Type-Spec selbst.
Grenze, die 6.0.0 neu gezogen hat. Ein Abschnitt, den die Instanz behaelt, ist ihrer, also
traegt er die KB-Sprache; englisch ist nur, was die Migration neu als Control-Plane-Prosa
einsetzt (H1 und Pointer-Absatz, Befund 4b).
entity,conceptundcomparisonwaren sauber - betroffen war nursource, der einzige dervier Typen, dessen Prosa umfangreich genug war, dass ein Bullet uebrigblieb, den die
Stack-Guidance nicht abdeckt (die Titel-Praefix-Regel; sie steht in der Guidance-Datei nicht).
Inhaltlich war der Bullet redundant zum
title_prefix: "Source - "in der Frontmatter, daswikitool new sourceohnehin erzwingt.Behoben mit
b5014d9: Abschnitt ersatzlos entfernt, geprueft mit dem Muster aus Befund 6 -types describe sourcevor und nach der Aenderung in je eine Datei, danndiff. Der Diffzeigt genau die vier entfernten Zeilen und sonst nichts; alle vier Typen komponieren jetzt mit
zwei Koepfen.
Nebenbeobachtung, kein Befund: dass
types describeeinen## Authoring guidance-Kopf setztund unmittelbar darunter eine Guidance-Datei mit eigenem H1 und eigenem gleichnamigem Abschnitt
inlined, ist eine kosmetische Doppelung im Stack selbst - gleich fuer alle vier Typen, ohne
Auswirkung auf Inhalt oder Werkzeuge.
Befund 6: Schritt 5 des Migrationsdokuments ist als Verifikation unfalsifizierbar
kind/defect, Dokumentation. Direkte Ursache von Befund 5.instructions/migrations/6.0.0-type-guidance-split.md, Schritt 5, verlangt:Kein Schritt davor haelt das Vorher fest. Eine Pruefung gegen einen Zustand, den niemand
aufgeschrieben hat, ist keine Pruefung - sie faellt auf das Gedaechtnis des Ausfuehrenden zurueck,
und bei einer Ausgabe von ueber 150 Zeilen je Typ ist das keins.
Der Lauf hat entsprechend geprueft:
types describedurch| head -250und| tail -80, also inAusschnitten, mit dem Urteil "All four compose correctly, structurally identical to before". Der
Rest-Abschnitt aus Befund 5 liegt in der Mitte der
source-Ausgabe und war in keinem der beidenAusschnitte. Dasselbe
| headerzeugte zugleich den SIGPIPE-Exit-1, den der Nebenbefund unterBefund 1 als Trace-Rauschen fuehrt: ein Verhalten, zwei Symptome.
Die Gegenprobe ist gelaufen: die Reparatur in
b5014d9hat das Vorher weggeschrieben undhinterher gediffed, und der Diff hat genau die beabsichtigte Aenderung gezeigt - derselbe
Aufwand, ein belastbares Ergebnis.
Vorschlag: Schritt 5 verlangt,
tools/wikitool types describe <name>vor Schritt 3 in eineDatei zu schreiben und danach zu diffen. Das macht aus der Behauptung eine Pruefung, kostet einen
Befehl, und traegt fuer jede kuenftige
assisted-Migration gleichermassen - also gehoert derGedanke auch in
instructions/migrate-corpus.md§ "Writing the migration document", nicht nur indieses eine Dokument. Als generisches Muster steht er seit
504149cbereits ininstructions/upgrade-instance.mdSchritt 12; das ersetzt die beiden Stellen nicht, an denen dasMuster eigentlich hingehoert.
Befund 7: der Upgrade-Pfad hatte keine agentengerichtete Prozedur - erledigt in #108
kind/defect, Prozess. Umgesetzt mit504149c(6.1.0-beta.1); hier bleibt die Evidenz aus demLauf stehen, weil sie die Begruendung der Loesung traegt.
Die Schrittfolge stand nur in INSTALL.md - einem Dokument fuer Menschen (
AGENTS.md§ Filenaming: README-foermige Wurzeldateien werden "never by an agent as instruction" geladen).
Ausgefuehrt wird sie von einem Agenten. Der erste Tool-Call des Laufs listete
instructions/mit - der Agent suchte also zuerst eine Instruktion, fand keine, oeffnete
instructions/private-instance.md(der falsche Weg: Clone mit gemeinsamer History stattTarball-Instanz), verwarf sie und griff auf INSTALL.md zurueck.
Was im selben Lauf daraus folgte:
migrate verify --from <commit vor dem Tausch>wurde nie ausgefuehrt, obwohl es inINSTALL.md Schritt 6 der erste Pruefschritt war. Die Lauf-Tabelle oben belegt es lueckenlos.
Der Grund ist praezise benennbar: der Lauf folgte nicht INSTALL.md, sondern dem
Abschlussbericht von
dist upgrade- und in dessen Liste kammigrate verifynicht vor.Ende von Schritt 6, die andere am Ende des Abschlussberichts. Die optionale Migration lief
anschliessend unter dem 5.0.0-Kontrollplan, obwohl
AGENTS.mdim selben Commit +44/-3 bekommenhatte - und genau dort fielen Befund 4b (Sprachgrenze, neu in 6.0.0) und Befund 5 an.
tatsaechlich gelaufene. Dass der Lauf der zweiten folgte, machte die erste zu toter Doku -
genau der Zustand, den Invariante 8 verbietet.
Umgesetzt:
instructions/upgrade-instance.md(manual: true) ist die eine Fassung, dreizehnSchritte, mit dem Sitzungsneustart zwischen Maschinerie-Publish und Migrationskette statt am Ende
und
migrate statusals Wiedereinstiegspunkt. Der Abschlussbericht vondist upgradenennt jetztdie Datei und das Wiedereinstiegskommando statt einer eigenen Liste, INSTALL.md nur noch die
Entscheidung davor. Details und Abgrenzung: #108.
Was der Lauf bestaetigt hat
Ausdruecklich keine Befunde - das hat gehalten:
voraus, dass
docs verifynach dem Update auf adoptierten Page-Type-Specs ohne TOC-Regionfaellt, und nannten
docs toc --applyals Reparatur. Genau das trat ein(
types/concept.md,types/source.md), und genau das reparierte es - ein Werkzeuglauf, keineInhaltsmigration. Nicht identisch mit #106: dort ging es um
kb/CONVENTIONS.md.templateaufeiner frischen Instanz; hier um adoptierte
types/*.mdauf dem Upgrade-Pfad. Der in kb/CONVENTIONS.md.template traegt keine TOC-Region: frische Instanz und CI scheitern an docs verify (#106)umgesetzte Fix (Templates in
toc.target_files()) deckt diesen Fall nicht ab, weil diebetroffenen Dateien bereits im Dateisatz stehen - ihnen fehlte die Region nur, weil sie vor der
Scope-Erweiterung adoptiert wurden.
dist upgradeklassifiziert korrekt - 202 unveraendert / 8 neu / 0 lokal geaendert /0 entfallen, und die 8 neuen Dateien waren exakt die des Bumps (4
*.guidance.md,types/type-guidance.md(.schema.yaml),docs/language-boundaries.md, das Migrationsdokument).migrate statushat richtig nicht blockiert. "Migration: none required" aus denRelease-Notes und "Nothing outstanding" aus dem Werkzeug stimmten ueberein.
Inhalt gebunden, Freigabe mit demselben Token akzeptiert,
gate.refused/gate.clearedbeide inder Trace. Als Datenpunkt fuer #53: 69 Dateien bei Schwelle 10, und der zweite Publish desselben
Laufs lag mit 5 Dateien darunter.
Korrigiert durch Befund 5:types describekomponiert nach der Migration unveraendert.fuer
entity,conceptundcomparisonstimmte es; fuersourcenicht - dort stand bisb5014d9ein dritter## Authoring guidance-Kopf in der komponierten Ausgabe. Was fuer allevier haelt: Frontmatter-Felder und
## Template-Block sind byte-gleich, nur die Herkunft derAnleitungsprosa hat gewechselt.
Reproduktion auf einer Dev-Instanz
Erwartetes Ergebnis von Schritt 5 gegen diesen Lauf: Bucket-Zahl in der Groessenordnung der
abgesetzten Kommandos,
max countdeutlich unter 60. WirdWIKITOOL_SESSION_IDdagegen gesetzt,muss genau ein Bucket entstehen und der Zaehler bis zur Zahl der Aufrufe hochlaufen - das ist
der Gegentest, der Befund 1 bestaetigt oder widerlegt. Auf Claude Code traegt dafuer nur die
Inline-Form pro Aufruf, nicht ein
export.Akzeptanzkriterien
an einer echten Trace - oder es ist in
EVALS.mdbegruendet, warum die Zersplitterunghinnehmbar ist und was stattdessen der Join-Key ist.
Aufrufe aus je eigener Shell absetzt, muss die Verweigerung sehen; heute waere er gruen und
damit blind.
gemeinsamen Schluessel loesen die L2-Blindheit nicht.
instructions/session-setup.mdnennt eine Form, die auf einem Harness mitShell-pro-Tool-Call wirkt - nicht nur
exporteinmal pro Sitzung. Erledigt in #108(
504149c): Inline-Form pro Aufruf, mit dem Einzeiler zum Feststellen, welcher Fallvorliegt.
tools/wikitool version notesliefert auf einer frisch ausgelieferten Instanzdie Notes des installierten Release - oder der Befehl sagt im Fehlerfall selbst, wo sie
stattdessen stehen. (Die widersprechende INSTALL.md-Stelle ist bereits weg, der Defekt
nicht.)
die Release-Fassung zuruecksetzen;
tools/CONTRACT.mdsdist upgrade-Zeile nennt den Weg.welche nicht - so, dass "Default = Release nehmen" nicht als Erwartung stehenbleibt.
types/entity.md.templateund sagt, inwelcher Sprache der Pointer-Absatz zu schreiben ist.
tools/wikitool types describe sourcegibt in der Instanznathanso viele## Authoring guidance-Koepfe aus wie bei den anderen drei Typen (zwei), und kein Abschnittdort traegt eine englische Ueberschrift ueber deutschem Inhalt. Erledigt mit
b5014d9,geprueft per Vorher/Nachher-Diff.
und einen Diff;
instructions/migrate-corpus.mdfuehrt dasselbe Muster fuer kuenftigeassisted-Migrationen.instructions/upgrade-instance.md(manual: true)existiert,
dist upgrades Abschlussbericht nennt sie, INSTALL.md traegt die Schrittfolgenicht mehr doppelt.
pytest,docs verify,instructions verifyohne neue Befunde. (Fuer den Anteil aus #108erfuellt: 1276 Tests, beide Verifier gruen.)
Herkunft und Artefakte
Lauf vom 2026-09-15, Instanz
5.0.0 -> 6.0.0, Harness Claude Code, Sitzung671c1b9a.Ergebnis-Commits in der Instanz:
7fe8353(Handreparatur aus Befund 3),dcc17df(Maschinerie),c8c9f9b(optionale Migration).Review-Sitzung vom 2026-09-16: hat Transkript, die drei Commits und den Endzustand gegengelesen
und Befund 5, 6, 7 sowie die Ursachenabschnitte unter Befund 1 und 3 ergaenzt. Befund 5 ist dabei
live gegen die Instanz geprueft, nicht aus dem Transkript abgeleitet, und in derselben Sitzung
repariert (
b5014d9intorben/nathan). Aus derselben Sitzung stammt #108, das Befund 7abgeschlossen hat.
Erster Kommentar traegt die vollstaendige Telemetrie des Laufs verbatim - 63 Events, aus 21
Bucket-Dateien nach
tszusammengefuehrt. Einzige Aenderung: die drei identischen 69-Pfad-Arraysin
gate.refused/gate.cleared/publish.commitsind elidiert und die Liste steht einmal darunter.Das rohe Sitzungstranskript ist bewusst nicht angehaengt: die Instanz ist privat, das
Transkript traegt Seitentitel, Infrastrukturthemen und Kontaktdaten aus
kb/, und dieses Repo istoeffentlich (
instructions/private-instance.md: "the cost of a mistaken push is disclosure ratherthan inconvenience"). Die Telemetrie unten ist dagegen geprueft frei davon - sie enthaelt nur
Stack-Pfade, Kommandonamen und Exit-Codes. Wer das Transkript fuer die Dev-Instanz-Validierung
braucht, bekommt es auf Anfrage redigiert (ANSI entfernt, Instanzinhalte maskiert).
Nebenbefund aus genau dieser Redaktion, weil er
chemenu.telemetry.scrubbetrifft: eineMaskierung per Regex ueber Terminalausgabe greift nicht, solange die ANSI-Sequenzen drinstehen -
ssh://git@host:PORT/...undVorname Nachname <mail@host>waren durch eingestreuteFarbcodes aufgetrennt und ueberlebten den ersten Durchgang unmaskiert. ANSI muss vor der
Maskierung entfernt werden, nicht danach.
Telemetrie des Laufs - verbatim
63 Events, zusammengefuehrt aus den 21 Bucket-Dateien unter
reports/telemetry/<session>/trace.jsonl(Filter:
-newermt "2026-09-15 21:40"lokal = 19:40 UTC), sortiert nachts. Unveraendert bis aufeine Sache: die drei identischen 69-Pfad-Arrays in
gate.refused,gate.clearedund dem erstenpublish.commitsind durch<<69 Pfade - elidiert, Liste einmal unten>>ersetzt; die Liste stehtdarunter. Ausserdem sind bei
prompt.submitteddie Feldertranscript_pathundcwdentfernt(lokale Pfade, kein Informationswert hier) -
prompt,prompt_sha256undprompt_lengthstehenunveraendert da.
Dass dieselbe Datei 21
session_id-Werte traegt, ist Befund 1 und kein Artefakt der Zusammenfuehrung.Die elidierte 69-Pfad-Liste
Identisch in
gate.refused,gate.clearedund dem erstenpublish.commit- das ist derCommit
dcc17df:Abgeleitete Kennzahlen
Event-Histogramm ueber die 63 Zeilen:
Laufzeiten, soweit auffaellig:
docs verifykalt 1644.6 ms, danach 403-415 ms (dreimal gemessen).publish --confirm1181.8 ms inklusive Push, der zweite Publish 970.4 ms. Alles andere unter300 ms.
budget.statetaucht in der ganzen Trace nicht auf, obwohl das Event imcompleteness-Feld jedessession.startals meldbar gefuehrt wird - passt zu Befund 1, Folge 2:ein Zaehler, der nie in die Naehe seiner Schwelle kommt, hat auch nichts zu melden.
Upgrade-Lauf 5.0.0 -> 6.0.0 auf ausgelieferter Instanz: Laufbericht, Telemetrie, vier Befundeto Upgrade-Lauf 5.0.0 -> 6.0.0 auf ausgelieferter Instanz: Laufbericht, Telemetrie, sieben BefundeChangelog: Review-Sitzung vom 2026-09-16 gegen Transkript, die drei Ergebnis-Commits und den Endzustand der Instanz. Neu: Befund 5 (Rest-Abschnitt
## Authoring guidanceintypes/source.md, doppelter Kopf intypes describe source- live gegengeprueft), Befund 6 (Schritt 5 des Migrationsdokuments prueft gegen ein Vorher, das niemand festhaelt - direkte Ursache von Befund 5), Befund 7 (Upgrade-Pfad ohne agentengerichtete Prozedur;migrate verifynie gelaufen, Session nie neu gestartet, drei konkurrierende Reihenfolgen). Befund 1 hat einen Ursachenabschnitt bekommen:instructions/session-setup.mdschreibtexport ...einmal pro Sitzung, was auf einem Harness mit Shell-pro-Tool-Call wirkungslos ist. Befund 3 hat die Erwartungshaltung aus dem Transkript, Befund 4a die Verschaerfung, dass es im Ursprungs-Repo gar keinetypes/*.md.templategibt.Korrigiert: die Zeile unter "Was der Lauf bestaetigt hat",
types describekomponiere unveraendert - das gilt fuer drei der vier Typen, nicht fuersource. Akzeptanzkriterien um vier Punkte erweitert, Reproduktionsabschnitt um Schritt 6 (Diff-Gegentest). Befund 7 ist als Bauauftrag nach #108 ausgelagert. Titel undsize/nachgezogen: vier -> sieben Befunde,size/M->size/L, weil daraus jetzt mehrere Arbeitspakete werden statt eines.Changelog: Befund 5 ist repariert (
b5014d9intorben/nathan) und das Kriterium abgehakt. Dabei eine Zahl in Befund 5 korrigiert: zwei## Authoring guidance-Koepfe sind der Normalzustand -types describesetzt selbst einen und inlined darunter die Guidance-Datei mit ihrem eigenen gleichnamigen Abschnitt, bei allen vier Typen.sourcehatte einen dritten aus dem Type-Spec. Der Reproduktionsabschnitt nennt jetzt 3 statt 2 als Erwartungswert und die Gegenprobe an den anderen drei Typen. Befund 6 traegt die Gegenprobe: die Reparatur lief mit Vorher-Datei und Diff, und genau deshalb war das Ergebnis belastbar. "Stand"-Absatz oben auf drei erledigte Punkte aktualisiert.