Upgrade-Lauf 5.0.0 -> 6.0.0 auf ausgelieferter Instanz: Laufbericht, Telemetrie, sieben Befunde #107

Open
opened 2026-09-16 06:08:51 +00:00 by torben · 3 comments
Owner

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, VERSION 5.0.0, kb_version 5.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: der
Upgrade-Pfad hat mit instructions/upgrade-instance.md eine agentengerichtete Prozedur), der
Anleitungsteil von Befund 1 (instructions/session-setup.md traegt 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

Zeit (UTC) Schritt Ergebnis
19:45:07 version check Update 5.0.0 -> 6.0.0, Grenzuebertritt gemeldet
19:45:18 migrate status nichts offen
19:45:18 version notes Exit 1 - Befund 2
19:46:03 dist upgrade --dry-run 201 unveraendert, 8 neu, 1 lokal geaendert, 0 entfallen
19:46:31 dist upgrade Exit 1 - Befund 3
19:46:59 dist upgrade --dry-run Exit 1, Arbeitsbaum unsauber (nach Handreparatur)
~19:47 git commit der Handreparatur ausserhalb des Werkzeugs noetig - und ausserhalb von Invariante 5, siehe Befund 3
19:47:17 dist upgrade --dry-run 202 / 8 / 0 / 0
19:47:22 dist upgrade OK, 210 Dateien geschrieben
19:47:28 migrate status 1 optionales Upgrade, nichts blockiert
19:47:29 instructions sync 5 Skills publiziert
19:47:44 doctor alles OK, ein WARN (session-id)
19:47:46 docs verify Exit 1 - TOC fehlt auf types/concept.md, types/source.md
19:47:53 docs toc --apply 2 Dateien repariert - wie in den Release-Notes angekuendigt
19:47:58 docs verify / instructions verify / lint gruen
19:48:28 publish Exit 42, Mass-Update-Gate, 69 Dateien, Token 96e2563ff596
19:58:22 publish --confirm OK, Commit dcc17df, gepusht
20:02-20:06 optionale Migration 6.0.0-type-guidance-split angenommen - Befund 4, 5, 6
20:06:33 migrate done 6.0.0 --pages 0 Angebot als genommen vermerkt
20:06:43 publish OK, Commit c8c9f9b, 5 Dateien, unter der Gate-Schwelle

33 wikitool.call-Events insgesamt, ein einziger unerwarteter Exit-Code (types describe source,
Exit 1 um 20:06:09 - das war SIGPIPE durch ein | head des Aufrufers, kein Werkzeugfehler; siehe
Anmerkung 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:

21 session_ids: 671c1b9a-92dd-484b-b29a-bf6d29c006ff
                3835015 3835056 3835179 3835232 3835285 3835339 3835353 3835371
                3835425 3835460 3835471 3835548 3836791 3837235 3837668 3837691
                3837722 3837739 3837778 3837804

Aufgeschluesselt nach Quelle:

Quelle Session-Id-Form Events
claude-code (Hook) UUID der echten Sitzung 1 session.start, 5 prompt.submitted
wikitool (Emitter) 20 verschiedene Parent-PIDs 20 session.start, 33 wikitool.call, 1 gate.refused, 1 gate.cleared, 2 publish.commit

WIKITOOL_SESSION_ID war nicht gesetzt, der Fallback ist die Parent-PID
(chemenu/session.py). Der Harness startet pro Tool-Call eine neue Shell - also pro Aufruf
eine neue PID und damit eine neue "Sitzung".

Folge 1: EVALS.md' Join-Key haelt nicht

EVALS.md § Architecture: "Everything joins on WIKITOOL_SESSION_ID." In diesem Lauf joint
nichts: 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 der
Gate-Verweigerung) meldet:

- `skip` **clearance-ended-the-turn** - No wikitool.call between a clearance request (exit 42) and the next prompt.submitted.
    - this harness cannot report prompt.submitted - cannot say

Der Harness hat prompt.submitted gemeldet - 5 mal, nur unter der UUID. Ausgerechnet die
L2-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.post
ergaenzen, die dann ebenfalls unter der UUID landen und weiterhin nicht zu den
wikitool.call-Events joinen. Die beiden Issues muessen zusammen gedacht werden, sonst
verdrahtet #82 Hooks, deren Events immer noch niemand zuordnen kann.

Ausserdem scort eval score jeweils 1 bis 3 Calls statt 33, waehrend die L1-Strukturpruefung in
allen 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:

46 Session-Buckets; Counts absteigend: [9, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, ...]

Der Hoechststand ist 9 - und der stammt aus wiki-setup-nathan, einem Bucket, in dem
WIKITOOL_SESSION_ID gesetzt war. Jeder PID-Bucket kommt ueber 3 nicht hinaus. Bei 33
Calls 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.

doctor sagt das Noetige bereits - nur als WARN und ohne die Folge zu nennen:

WARN session-id: WIKITOOL_SESSION_ID is not set - budget falls back to the parent PID
  fix: See instructions/session-setup.md

Ursache eine Ebene tiefer: instructions/session-setup.md war auf diesem Harness wirkungslos

Nachgetragen aus der Review-Sitzung. doctor verweist auf instructions/session-setup.md, und
dort stand als Schritt, woertlich:

export WIKITOOL_SESSION_ID="wiki-$(date +%s)"
tools/wikitool sync

"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
export in Aufruf N ist in Aufruf N+1 verschwunden. Die 20 verschiedenen Parent-PIDs oben sind
dieselbe 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.md nennt jetzt
die Inline-Form pro Aufruf, sagt warum ein export nur traegt solange die Shell traegt, und gibt
den 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 source steht mit exit_code: 1 in der Trace (20:06:09). Der Aufruf war
erfolgreich; der Exit-Code entstand durch SIGPIPE, weil der Aufrufer die Ausgabe durch | head
geschickt hat. Der unmittelbar folgende identische Aufruf ohne Pipe steht mit exit_code: 0 da.
Wer die Trace als Fehlerquelle auswertet, zaehlt hier einen Werkzeugfehler, den es nicht gab.
Dasselbe | head ist 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), oder doctor/publish die
fehlende WIKITOOL_SESSION_ID haerter melden lassen als mit einem WARN. Was davon traegt, gehoert
gegen #82 zusammen entschieden.


Befund 2: version notes scheitert auf jeder ausgelieferten Instanz, obwohl INSTALL.md Schritt 4 darauf verweist

kind/defect - Doku und Realitaet widersprechen sich.

INSTALL.md § "Eine Instanz aktualisieren", Schritt 4, verbatim (Stand des Laufs):

  1. Bei einer Kompatibilitätsgrenze (dist upgrade meldet sie laut) die Release-Notes vor dem
    nächsten Schritt lesen: Breaking Change: und Migration: im Eintrag von
    tools/wikitool version notes sagen, was aufhört zu funktionieren und ob der Korpus
    umgeschrieben werden muss.

Der Aufruf auf der Instanz:

$ tools/wikitool version notes
ERROR CHANGES.md has no entry for 5.0.0 - run `wikitool version bump` before
releasing, or write the entry

Ursache

version notes liest die lokale CHANGES.md. Eine ausgelieferte Instanz bekommt dafuer den
Stub aus tools/chemenu/dist_templates/CHANGES.md - 9 Zeilen, Vorwort, null Versionseintraege:

# Changelog

This file tracks changes to the **wiki stack itself** - `AGENTS.md`, the
`instructions/` layer, `tools/wikitool`, and the contracts. [...]

CHANGES.md steht ausserdem in chemenu.ownership.is_upgrade_preserved, wird von dist upgrade
also bewusst nie ueberschrieben. Der Stub bleibt der Stub - dauerhaft. version notes kann
auf 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 504149c auf instructions/upgrade-instance.md, deren Schritt 2 die Release-Seite aus
release_url liest und ausdruecklich sagt, dass version notes auf 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 notes faellt auf den Release-Feed zurueck, wenn die lokale CHANGES.md den
Eintrag nicht hat (die URL steht bereits in .wikitool-release.json als update_url/release_url,
und version check fragt sie ohnehin ab) - oder es bleibt bei der Doku-Antwort und der Befehl sagt
im Fehlerfall selbst, wo die Notes stattdessen stehen. Ersteres ist freundlicher, Letzteres
billiger.


Befund 3: dist upgrade kennt keinen Weg, die Release-Fassung einer lokal geaenderten Datei zu uebernehmen

kind/defect / fehlende Faehigkeit.

Beobachtung

Der Dry-Run meldete genau eine lokal geaenderte Datei:

201 unchanged, 8 new, 1 locally changed, 0 removed from the release.
Locally modified (1):
  - kb/CONTRACT.md

Der Unterschied war reine Whitespace-Formatierung einer Markdown-Tabelle (Spaltenauffuellung,
vermutlich ein Format-on-Save), inhaltlich identisch. kb/CONTRACT.md ist dabei stackeigen:
instructions/private-instance.md fuehrt <stage>/CONTRACT.md ausdruecklich als Maschinerie, an
der "an instance never edits it".

Der Lauf ohne Flag:

ERROR 1 locally changed file(s) (listed above) would be silently overwritten.
Pass --keep-local to upgrade anyway and leave every one of them untouched, or
reconcile them by hand first. Nothing was written.

Beide angebotenen Wege sind hier falsch:

  • --keep-local behaelt die Drift. Laut tools/CONTRACT.md schreibt der neue Stamp trotzdem
    die Release-Digest - die Datei divergiert also bei jedem kuenftigen dist upgrade erneut und
    wird jedes Mal wieder gemeldet. Fuer eine Datei, die der Instanz gar nicht gehoert, ist das der
    dauerhaft falsche Zustand.
  • "reconcile by hand" ist der richtige Weg, hat aber kein Werkzeug. Was die Instanz tatsaechlich
    tun musste:
$ cp <entpackter-tarball>/kb/CONTRACT.md kb/CONTRACT.md   # von Hand aus dem Tarball
$ tools/wikitool dist upgrade <tarball> --dry-run
ERROR Working tree is not clean (`git status --porcelain` printed something).
`dist upgrade` refuses to start on a dirty tree so a refusal never has to guess
which changes were already there. Commit or stash first.
$ git commit ...                                          # zweiter Handgriff
$ tools/wikitool dist upgrade <tarball>                   # jetzt 202 / 8 / 0 / 0

Drei Schritte, zwei davon ausserhalb des Werkzeugs, plus ein Extra-Commit (7fe8353) nur um die
Vorbedingung 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 7fe8353 ist ein rohes git add + git commit. AGENTS.md Invariante 5 sagt "Never
call raw git commit/git push. Publish through tools/wikitool publish"
und kennt keine
Ausnahme fuer "ist ja nur eine Vorbedingung". Der richtige Weg haette
tools/wikitool publish --no-push geheissen.

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.md Schritt 6 schreibt seit 504149c ausdruecklich publish --no-push vor; 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 upgrade
dann ohne Flag auf. Das Mentalmodell war also "Default = Release-Fassung nehmen"; der Default ist
Abbruch. Die Fehlermeldung korrigiert das nicht: sie nennt --keep-local und "reconcile by hand",
sagt aber nicht, dass es zu --keep-local kein Gegenstueck gibt. Es fehlt damit nicht nur ein
Flag, 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 den
Lauf 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-release entfaellt die Handreparatur, also auch der unsaubere Baum - die
Vorbedingung kann bleiben, wie sie ist.


Befund 4: 6.0.0-type-guidance-split nennt ein Beispiel, das in der Instanz das Gegenteil zeigt

kind/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:

  1. Delete the now-duplicated prose from the type-spec, keeping the H1, a short pointer to the
    guidance file (types/entity.md's own current text is the worked example), ## Frontmatter
    and ## Template.

Im Ursprungs-Repo stimmt das: dort ist types/entity.md die stackeigene, bereits migrierte Datei.
In einer ausgelieferten Instanz ist types/entity.md die beim Setup adoptierte Kopie - also
genau 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 der
Nachher-Zustand (Pointer-Absatz, guidance:-Feld in der Frontmatter), weil dist upgrade die
Templates verbatim mitliefert.

Verschaerfung aus der Review-Sitzung: im Ursprungs-Repo existiert ueberhaupt keine
types/*.md.template-Datei - dist export re-keyt types/<name>.md erst beim Export zur
.template (dist_cmd._owned_type_stem). Der Satz kann in einer Instanz also nicht bloss
unguenstig sein, er kann dort strukturell nie stimmen.

Vorschlag: den Verweis auf types/entity.md.template umstellen und den Grund danebenschreiben -
das ist dieselbe .md vs. .md.template-Verwechslung, an der auch #106 hing, nur von der
anderen 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: de ist das nicht ableitbar, denn 6.0.0 hat diese Grenze gerade erst neu
gezogen (Bump "Control-Plane-Sprache universell", docs/language-boundaries.md): Anleitungsprosa
ist Control Plane und englisch, ## Template-Body und layout:-Titel sind Seitentext in der
KB-Sprache.

Der Lauf hat daraus abgeleitet - und das sollte im Dokument stehen, nicht abgeleitet werden
muessen:

Teil des Type-Specs Sprache Begruendung
H1, Pointer-Absatz Englisch Anleitungsprosa an einen Agenten = Control Plane
## Frontmatter-Tabelle unveraendert lassen die Migration fasst Frontmatter ausdruecklich nicht an
## Template-Block + Nachsatz unveraendert lassen (hier: deutsch) Seitentext in der KB-Sprache

Genau 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 ist
unmissverstaendlich:

OK Recorded the optional 6.0.0-type-guidance-split. Content stays at 5.0.0 - an
offer changes a file you own, not the shape of your content.

Danach bleibt doctor bei kb-version: 5.0.0 (nothing outstanding up to 6.0.0). Das ist korrekt
und 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.md einen Rest-Abschnitt hinterlassen - repariert in der Instanz (b5014d9)

kind/defect, Instanzschaden. Gefunden in der Review-Sitzung, live gegengeprueft und dort auch
behoben. Steht hier, weil er die Wirkung von Befund 4b und Befund 6 belegt.

Bei types/source.md wurde der Abschnitt ## Autorenanweisungen nicht geloescht, sondern zu
## Authoring guidance umbenannt, mit einem verbliebenen deutschen Bullet:

## Authoring guidance

- Der Titel beginnt mit "Source - ", gefolgt vom Namen der Quelle

Zwei Fehler in drei Zeilen:

  1. Ein dritter Kopf desselben Namens in der komponierten Ausgabe. Zwei sind der
    Normalzustand und kein Befund: types describe setzt selbst einen ## Authoring guidance-Kopf und inlined darunter die Guidance-Datei, die ihren eigenen gleichnamigen
    Abschnitt mitbringt - so sieht es bei allen vier Typen aus. source hatte danach einen
    dritten aus dem Type-Spec selbst.
  2. Englische Ueberschrift ueber deutschem Inhalt in einer instanzeigenen Datei - genau die
    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, concept und comparison waren sauber - betroffen war nur source, der einzige der
vier 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, das
wikitool new source ohnehin erzwingt.

Behoben mit b5014d9: Abschnitt ersatzlos entfernt, geprueft mit dem Muster aus Befund 6 -
types describe source vor und nach der Aenderung in je eine Datei, dann diff. Der Diff
zeigt genau die vier entfernten Zeilen und sonst nichts; alle vier Typen komponieren jetzt mit
zwei Koepfen.

Nebenbeobachtung, kein Befund: dass types describe einen ## Authoring guidance-Kopf setzt
und 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:

The output must read the same as it did before this migration [...] the structure (frontmatter
fields, template block) must be byte-identical.

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 describe durch | head -250 und | tail -80, also in
Ausschnitten, 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 beiden
Ausschnitte. Dasselbe | head erzeugte zugleich den SIGPIPE-Exit-1, den der Nebenbefund unter
Befund 1 als Trace-Rauschen fuehrt: ein Verhalten, zwei Symptome.

Die Gegenprobe ist gelaufen: die Reparatur in b5014d9 hat das Vorher weggeschrieben und
hinterher 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 eine
Datei 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 der
Gedanke auch in instructions/migrate-corpus.md § "Writing the migration document", nicht nur in
dieses eine Dokument. Als generisches Muster steht er seit 504149c bereits in
instructions/upgrade-instance.md Schritt 12; das ersetzt die beiden Stellen nicht, an denen das
Muster eigentlich hingehoert.


Befund 7: der Upgrade-Pfad hatte keine agentengerichtete Prozedur - erledigt in #108

kind/defect, Prozess. Umgesetzt mit 504149c (6.1.0-beta.1); hier bleibt die Evidenz aus dem
Lauf stehen, weil sie die Begruendung der Loesung traegt.

Die Schrittfolge stand nur in INSTALL.md - einem Dokument fuer Menschen (AGENTS.md § File
naming: 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 statt
Tarball-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 in
    INSTALL.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 kam migrate verify nicht vor.
  • Die Agent-Session wurde nie neu gestartet. Beide Reihenfolgen verlangten das, die eine am
    Ende von Schritt 6, die andere am Ende des Abschlussberichts. Die optionale Migration lief
    anschliessend unter dem 5.0.0-Kontrollplan, obwohl AGENTS.md im selben Commit +44/-3 bekommen
    hatte - und genau dort fielen Befund 4b (Sprachgrenze, neu in 6.0.0) und Befund 5 an.
  • Drei Reihenfolgen waren im Umlauf: INSTALL.md Schritt 6, der Abschlussbericht, und die
    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, dreizehn
Schritte, mit dem Sitzungsneustart zwischen Maschinerie-Publish und Migrationskette statt am Ende
und migrate status als Wiedereinstiegspunkt. Der Abschlussbericht von dist upgrade nennt jetzt
die 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:

  • Der angekuendigte Grenzuebertritt kam exakt wie beschrieben. Die Release-Notes sagten
    voraus, dass docs verify nach dem Update auf adoptierten Page-Type-Specs ohne TOC-Region
    faellt, und nannten docs toc --apply als Reparatur. Genau das trat ein
    (types/concept.md, types/source.md), und genau das reparierte es - ein Werkzeuglauf, keine
    Inhaltsmigration. Nicht identisch mit #106: dort ging es um kb/CONVENTIONS.md.template auf
    einer frischen Instanz; hier um adoptierte types/*.md auf 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 die
    betroffenen Dateien bereits im Dateisatz stehen - ihnen fehlte die Region nur, weil sie vor der
    Scope-Erweiterung adoptiert wurden.
  • dist upgrade klassifiziert 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 status hat richtig nicht blockiert. "Migration: none required" aus den
    Release-Notes und "Nothing outstanding" aus dem Werkzeug stimmten ueberein.
  • Das Mass-Update-Gate hat sauber gearbeitet: Exit 42 bei 69 Dateien, Token an Dateiliste und
    Inhalt gebunden, Freigabe mit demselben Token akzeptiert, gate.refused/gate.cleared beide in
    der Trace. Als Datenpunkt fuer #53: 69 Dateien bei Schwelle 10, und der zweite Publish desselben
    Laufs lag mit 5 Dateien darunter.
  • types describe komponiert nach der Migration unveraendert. Korrigiert durch Befund 5:
    fuer entity, concept und comparison stimmte es; fuer source nicht - dort stand bis
    b5014d9 ein dritter ## Authoring guidance-Kopf in der komponierten Ausgabe. Was fuer alle
    vier haelt: Frontmatter-Felder und ## Template-Block sind byte-gleich, nur die Herkunft der
    Anleitungsprosa hat gewechselt.

Reproduktion auf einer Dev-Instanz

# 1. Instanz auf 5.0.0 herstellen (aus einem 5.0.0-Checkout)
tools/wikitool dist export /tmp/inst-5.0.0
cd /tmp/inst-5.0.0 && git init -q -b main
git config user.name Dev && git config user.email dev@example.invalid
# Templates adoptieren wie instructions/setup-instance.md Schritt 5/6
python3 -m venv tools/.venv && tools/.venv/bin/pip install -q -r tools/requirements.txt
tools/wikitool instructions sync && tools/wikitool index rebuild
git add -A && git commit -qm baseline

# 2. Die Drift dieses Laufs nachstellen (Befund 3)
#    kb/CONTRACT.md durch einen Markdown-Formatter schicken - Whitespace-only,
#    inhaltlich identisch - und committen.

# 3. Nicht setzen, um Befund 1 zu reproduzieren: WIKITOOL_SESSION_ID
#    Jeden wikitool-Aufruf aus einer eigenen Shell absetzen (wie ein Agent-Harness es tut).

# 4. Upgrade fahren
tools/wikitool version check                       # meldet Grenzuebertritt
tools/wikitool version notes                       # ERWARTET Exit 1  -> Befund 2
tools/wikitool dist upgrade <6.0.0-tarball> --dry-run
tools/wikitool dist upgrade <6.0.0-tarball>        # ERWARTET Exit 1  -> Befund 3
#   -> Handreparatur + Commit, dann erneut
tools/wikitool migrate status && tools/wikitool instructions sync
tools/wikitool doctor
tools/wikitool docs verify                         # ERWARTET Exit 1 auf types/*.md
tools/wikitool docs toc --apply && tools/wikitool docs verify
tools/wikitool instructions verify && tools/wikitool lint

# 5. Befund 1 messen
python3 -c "import json;d=json.load(open('tools/.wikitool_session/budget.json'));\
print(len(d),'Buckets; max count:',max(e.get('count',0) for e in d.values()))"
tools/wikitool eval sessions                       # ERWARTET: viele Buckets, je 1-3 Events

# 6. Befund 5/6 reproduzieren: die optionale Migration fahren und vorher/nachher diffen
tools/wikitool types describe source > /tmp/source-vorher.txt
#   ... Schritte 3 und 4 des Migrationsdokuments ausfuehren ...
tools/wikitool types describe source > /tmp/source-nachher.txt
diff /tmp/source-vorher.txt /tmp/source-nachher.txt
#   ERWARTET ohne Gegenmassnahme: ein dritter "## Authoring guidance"-Kopf im Nachher
grep -c '^## Authoring guidance' /tmp/source-nachher.txt   # ERWARTET 3, korrekt sind 2
#   Gegenprobe: bei entity/concept/comparison sind es vorher wie nachher 2

Erwartetes Ergebnis von Schritt 5 gegen diesen Lauf: Bucket-Zahl in der Groessenordnung der
abgesetzten Kommandos, max count deutlich unter 60. Wird WIKITOOL_SESSION_ID dagegen 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

  • Befund 1: Ein Lauf auf Claude Code landet in genau einem Telemetrie-Bucket, nachgewiesen
    an einer echten Trace - oder es ist in EVALS.md begruendet, warum die Zersplitterung
    hinnehmbar ist und was stattdessen der Join-Key ist.
  • Befund 1: Das Iteration-Budget-Gate zaehlt ueber einen ganzen Lauf. Ein Test, der 61
    Aufrufe aus je eigener Shell absetzt, muss die Verweigerung sehen; heute waere er gruen und
    damit blind.
  • Befund 1: Entschieden und dokumentiert, wie sich das zu #82 verhaelt - Hooks ohne
    gemeinsamen Schluessel loesen die L2-Blindheit nicht.
  • Befund 1: instructions/session-setup.md nennt eine Form, die auf einem Harness mit
    Shell-pro-Tool-Call wirkt - nicht nur export einmal pro Sitzung. Erledigt in #108
    (504149c): Inline-Form pro Aufruf, mit dem Einzeiler zum Feststellen, welcher Fall
    vorliegt.
  • Befund 2: tools/wikitool version notes liefert auf einer frisch ausgelieferten Instanz
    die 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.)
  • Befund 3: Eine lokal geaenderte stackeigene Datei laesst sich in einem Kommando auf
    die Release-Fassung zuruecksetzen; tools/CONTRACT.mds dist upgrade-Zeile nennt den Weg.
  • Befund 3: Die Fehlermeldung des Abbruchs sagt, welche Antwortmoeglichkeiten es gibt und
    welche nicht - so, dass "Default = Release nehmen" nicht als Erwartung stehenbleibt.
  • Befund 4: Das Migrationsdokument verweist auf types/entity.md.template und sagt, in
    welcher Sprache der Pointer-Absatz zu schreiben ist.
  • Befund 5: tools/wikitool types describe source gibt in der Instanz nathan so viele
    ## Authoring guidance-Koepfe aus wie bei den anderen drei Typen (zwei), und kein Abschnitt
    dort traegt eine englische Ueberschrift ueber deutschem Inhalt. Erledigt mit b5014d9,
    geprueft per Vorher/Nachher-Diff.
  • Befund 6: Schritt 5 des Migrationsdokuments verlangt eine festgehaltene Vorher-Ausgabe
    und einen Diff; instructions/migrate-corpus.md fuehrt dasselbe Muster fuer kuenftige
    assisted-Migrationen.
  • Befund 7: abgehandelt in #108 - instructions/upgrade-instance.md (manual: true)
    existiert, dist upgrades Abschlussbericht nennt sie, INSTALL.md traegt die Schrittfolge
    nicht mehr doppelt.
  • pytest, docs verify, instructions verify ohne neue Befunde. (Fuer den Anteil aus #108
    erfuellt: 1276 Tests, beide Verifier gruen.)

Herkunft und Artefakte

Lauf vom 2026-09-15, Instanz 5.0.0 -> 6.0.0, Harness Claude Code, Sitzung 671c1b9a.
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 (b5014d9 in torben/nathan). Aus derselben Sitzung stammt #108, das Befund 7
abgeschlossen hat.

Erster Kommentar traegt die vollstaendige Telemetrie des Laufs verbatim - 63 Events, aus 21
Bucket-Dateien nach ts zusammengefuehrt. Einzige Aenderung: die drei identischen 69-Pfad-Arrays
in gate.refused/gate.cleared/publish.commit sind 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 ist
oeffentlich (instructions/private-instance.md: "the cost of a mistaken push is disclosure rather
than 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.scrub betrifft: eine
Maskierung per Regex ueber Terminalausgabe greift nicht, solange die ANSI-Sequenzen drinstehen -
ssh://git@host:PORT/... und Vorname Nachname <mail@host> waren durch eingestreute
Farbcodes aufgetrennt und ueberlebten den ersten Durchgang unmaskiert. ANSI muss vor der
Maskierung entfernt werden, nicht danach.

## 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, `VERSION` 5.0.0, `kb_version` 5.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`: der Upgrade-Pfad hat mit `instructions/upgrade-instance.md` eine agentengerichtete Prozedur), der Anleitungsteil von Befund 1 (`instructions/session-setup.md` traegt 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 | Zeit (UTC) | Schritt | Ergebnis | |---|---|---| | 19:45:07 | `version check` | Update 5.0.0 -> 6.0.0, Grenzuebertritt gemeldet | | 19:45:18 | `migrate status` | nichts offen | | 19:45:18 | `version notes` | **Exit 1** - Befund 2 | | 19:46:03 | `dist upgrade --dry-run` | 201 unveraendert, 8 neu, **1 lokal geaendert**, 0 entfallen | | 19:46:31 | `dist upgrade` | **Exit 1** - Befund 3 | | 19:46:59 | `dist upgrade --dry-run` | Exit 1, Arbeitsbaum unsauber (nach Handreparatur) | | ~19:47 | `git commit` der Handreparatur | ausserhalb des Werkzeugs noetig - und ausserhalb von Invariante 5, siehe Befund 3 | | 19:47:17 | `dist upgrade --dry-run` | 202 / 8 / **0** / 0 | | 19:47:22 | `dist upgrade` | OK, 210 Dateien geschrieben | | 19:47:28 | `migrate status` | 1 optionales Upgrade, nichts blockiert | | 19:47:29 | `instructions sync` | 5 Skills publiziert | | 19:47:44 | `doctor` | alles OK, ein WARN (`session-id`) | | 19:47:46 | `docs verify` | **Exit 1** - TOC fehlt auf `types/concept.md`, `types/source.md` | | 19:47:53 | `docs toc --apply` | 2 Dateien repariert - wie in den Release-Notes angekuendigt | | 19:47:58 | `docs verify` / `instructions verify` / `lint` | gruen | | 19:48:28 | `publish` | **Exit 42**, Mass-Update-Gate, 69 Dateien, Token `96e2563ff596` | | 19:58:22 | `publish --confirm` | OK, Commit `dcc17df`, gepusht | | 20:02-20:06 | optionale Migration `6.0.0-type-guidance-split` | angenommen - Befund 4, 5, 6 | | 20:06:33 | `migrate done 6.0.0 --pages 0` | Angebot als genommen vermerkt | | 20:06:43 | `publish` | OK, Commit `c8c9f9b`, 5 Dateien, unter der Gate-Schwelle | 33 `wikitool.call`-Events insgesamt, ein einziger unerwarteter Exit-Code (`types describe source`, Exit 1 um 20:06:09 - das war SIGPIPE durch ein `| head` des Aufrufers, kein Werkzeugfehler; siehe Anmerkung 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**: ``` 21 session_ids: 671c1b9a-92dd-484b-b29a-bf6d29c006ff 3835015 3835056 3835179 3835232 3835285 3835339 3835353 3835371 3835425 3835460 3835471 3835548 3836791 3837235 3837668 3837691 3837722 3837739 3837778 3837804 ``` Aufgeschluesselt nach Quelle: | Quelle | Session-Id-Form | Events | |---|---|---| | `claude-code` (Hook) | UUID der echten Sitzung | 1 `session.start`, 5 `prompt.submitted` | | `wikitool` (Emitter) | **20 verschiedene Parent-PIDs** | 20 `session.start`, 33 `wikitool.call`, 1 `gate.refused`, 1 `gate.cleared`, 2 `publish.commit` | `WIKITOOL_SESSION_ID` war nicht gesetzt, der Fallback ist die Parent-PID (`chemenu/session.py`). Der Harness startet **pro Tool-Call eine neue Shell** - also pro Aufruf eine neue PID und damit eine neue "Sitzung". ### Folge 1: EVALS.md' Join-Key haelt nicht `EVALS.md` § Architecture: *"Everything joins on `WIKITOOL_SESSION_ID`."* In diesem Lauf joint **nichts**: 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 der Gate-Verweigerung) meldet: ``` - `skip` **clearance-ended-the-turn** - No wikitool.call between a clearance request (exit 42) and the next prompt.submitted. - this harness cannot report prompt.submitted - cannot say ``` Der Harness *hat* `prompt.submitted` gemeldet - 5 mal, nur unter der UUID. Ausgerechnet die L2-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.post` ergaenzen, die dann **ebenfalls** unter der UUID landen und weiterhin nicht zu den `wikitool.call`-Events joinen. Die beiden Issues muessen zusammen gedacht werden, sonst verdrahtet #82 Hooks, deren Events immer noch niemand zuordnen kann. Ausserdem scort `eval score` jeweils 1 bis 3 Calls statt 33, waehrend die L1-Strukturpruefung in allen 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: ``` 46 Session-Buckets; Counts absteigend: [9, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, ...] ``` Der Hoechststand ist **9** - und der stammt aus `wiki-setup-nathan`, einem Bucket, in dem `WIKITOOL_SESSION_ID` *gesetzt* war. Jeder PID-Bucket kommt ueber **3** nicht hinaus. Bei 33 Calls 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. `doctor` sagt das Noetige bereits - nur als WARN und ohne die Folge zu nennen: ``` WARN session-id: WIKITOOL_SESSION_ID is not set - budget falls back to the parent PID fix: See instructions/session-setup.md ``` ### Ursache eine Ebene tiefer: `instructions/session-setup.md` war auf diesem Harness wirkungslos Nachgetragen aus der Review-Sitzung. `doctor` verweist auf `instructions/session-setup.md`, und dort stand als Schritt, woertlich: ```bash export WIKITOOL_SESSION_ID="wiki-$(date +%s)" tools/wikitool sync ``` *"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 `export` in Aufruf N ist in Aufruf N+1 verschwunden. Die 20 verschiedenen Parent-PIDs oben sind dieselbe 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.md` nennt jetzt die Inline-Form pro Aufruf, sagt warum ein `export` nur traegt solange die Shell traegt, und gibt den 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 source` steht mit `exit_code: 1` in der Trace (20:06:09). Der Aufruf war erfolgreich; der Exit-Code entstand durch SIGPIPE, weil der Aufrufer die Ausgabe durch `| head` geschickt hat. Der unmittelbar folgende identische Aufruf ohne Pipe steht mit `exit_code: 0` da. Wer die Trace als Fehlerquelle auswertet, zaehlt hier einen Werkzeugfehler, den es nicht gab. Dasselbe `| head` ist 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), oder `doctor`/`publish` die fehlende `WIKITOOL_SESSION_ID` haerter melden lassen als mit einem WARN. Was davon traegt, gehoert gegen #82 zusammen entschieden. --- ## Befund 2: `version notes` scheitert auf jeder ausgelieferten Instanz, obwohl INSTALL.md Schritt 4 darauf verweist `kind/defect` - Doku und Realitaet widersprechen sich. INSTALL.md § "Eine Instanz aktualisieren", Schritt 4, verbatim (Stand des Laufs): > 4. Bei einer Kompatibilitätsgrenze (`dist upgrade` meldet sie laut) die Release-Notes vor dem > nächsten Schritt lesen: **Breaking Change:** und **Migration:** im Eintrag von > `tools/wikitool version notes` sagen, was aufhört zu funktionieren und ob der Korpus > umgeschrieben werden muss. Der Aufruf auf der Instanz: ``` $ tools/wikitool version notes ERROR CHANGES.md has no entry for 5.0.0 - run `wikitool version bump` before releasing, or write the entry ``` ### Ursache `version notes` liest die lokale `CHANGES.md`. Eine ausgelieferte Instanz bekommt dafuer den Stub aus `tools/chemenu/dist_templates/CHANGES.md` - 9 Zeilen, Vorwort, **null Versionseintraege**: ``` # Changelog This file tracks changes to the **wiki stack itself** - `AGENTS.md`, the `instructions/` layer, `tools/wikitool`, and the contracts. [...] ``` `CHANGES.md` steht ausserdem in `chemenu.ownership.is_upgrade_preserved`, wird von `dist upgrade` also bewusst nie ueberschrieben. Der Stub bleibt der Stub - **dauerhaft**. `version notes` kann auf 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 `504149c` auf `instructions/upgrade-instance.md`, deren Schritt 2 die Release-Seite aus `release_url` liest und ausdruecklich sagt, dass `version notes` auf 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 notes` faellt auf den Release-Feed zurueck, wenn die lokale `CHANGES.md` den Eintrag nicht hat (die URL steht bereits in `.wikitool-release.json` als `update_url`/`release_url`, und `version check` fragt sie ohnehin ab) - oder es bleibt bei der Doku-Antwort und der Befehl sagt im Fehlerfall selbst, wo die Notes stattdessen stehen. Ersteres ist freundlicher, Letzteres billiger. --- ## Befund 3: `dist upgrade` kennt keinen Weg, die Release-Fassung einer lokal geaenderten Datei zu uebernehmen `kind/defect` / fehlende Faehigkeit. ### Beobachtung Der Dry-Run meldete genau eine lokal geaenderte Datei: ``` 201 unchanged, 8 new, 1 locally changed, 0 removed from the release. Locally modified (1): - kb/CONTRACT.md ``` Der Unterschied war **reine Whitespace-Formatierung** einer Markdown-Tabelle (Spaltenauffuellung, vermutlich ein Format-on-Save), inhaltlich identisch. `kb/CONTRACT.md` ist dabei stackeigen: `instructions/private-instance.md` fuehrt `<stage>/CONTRACT.md` ausdruecklich als Maschinerie, an der *"an instance never edits it"*. Der Lauf ohne Flag: ``` ERROR 1 locally changed file(s) (listed above) would be silently overwritten. Pass --keep-local to upgrade anyway and leave every one of them untouched, or reconcile them by hand first. Nothing was written. ``` Beide angebotenen Wege sind hier falsch: - `--keep-local` **behaelt** die Drift. Laut `tools/CONTRACT.md` schreibt der neue Stamp trotzdem die Release-Digest - die Datei divergiert also bei **jedem** kuenftigen `dist upgrade` erneut und wird jedes Mal wieder gemeldet. Fuer eine Datei, die der Instanz gar nicht gehoert, ist das der dauerhaft falsche Zustand. - "reconcile by hand" ist der richtige Weg, hat aber kein Werkzeug. Was die Instanz tatsaechlich tun musste: ``` $ cp <entpackter-tarball>/kb/CONTRACT.md kb/CONTRACT.md # von Hand aus dem Tarball $ tools/wikitool dist upgrade <tarball> --dry-run ERROR Working tree is not clean (`git status --porcelain` printed something). `dist upgrade` refuses to start on a dirty tree so a refusal never has to guess which changes were already there. Commit or stash first. $ git commit ... # zweiter Handgriff $ tools/wikitool dist upgrade <tarball> # jetzt 202 / 8 / 0 / 0 ``` Drei Schritte, zwei davon ausserhalb des Werkzeugs, plus ein Extra-Commit (`7fe8353`) nur um die Vorbedingung 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 `7fe8353` ist ein **rohes `git add` + `git commit`**. `AGENTS.md` Invariante 5 sagt *"Never call raw `git commit`/`git push`. Publish through `tools/wikitool publish`"* und kennt keine Ausnahme fuer "ist ja nur eine Vorbedingung". Der richtige Weg haette `tools/wikitool publish --no-push` geheissen. 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.md` Schritt 6 schreibt seit `504149c` ausdruecklich `publish --no-push` vor; 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 upgrade` dann ohne Flag auf. Das Mentalmodell war also "Default = Release-Fassung nehmen"; der Default ist Abbruch. Die Fehlermeldung korrigiert das nicht: sie nennt `--keep-local` und "reconcile by hand", sagt aber nicht, dass es zu `--keep-local` kein Gegenstueck gibt. Es fehlt damit nicht nur ein Flag, 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 den Lauf 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-release` entfaellt die Handreparatur, also auch der unsaubere Baum - die Vorbedingung kann bleiben, wie sie ist. --- ## Befund 4: `6.0.0-type-guidance-split` nennt ein Beispiel, das in der Instanz das Gegenteil zeigt `kind/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: > 4. **Delete the now-duplicated prose from the type-spec**, keeping the H1, a short pointer to the > guidance file (`types/entity.md`'s own current text is the worked example), `## Frontmatter` > and `## Template`. Im Ursprungs-Repo stimmt das: dort ist `types/entity.md` die stackeigene, bereits migrierte Datei. In einer **ausgelieferten Instanz** ist `types/entity.md` die beim Setup adoptierte Kopie - also genau 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 der Nachher-Zustand (Pointer-Absatz, `guidance:`-Feld in der Frontmatter), weil `dist upgrade` die Templates verbatim mitliefert. **Verschaerfung aus der Review-Sitzung:** im Ursprungs-Repo existiert ueberhaupt keine `types/*.md.template`-Datei - `dist export` re-keyt `types/<name>.md` erst beim Export zur `.template` (`dist_cmd._owned_type_stem`). Der Satz kann in einer Instanz also nicht bloss unguenstig sein, er kann dort strukturell nie stimmen. Vorschlag: den Verweis auf `types/entity.md.template` umstellen und den Grund danebenschreiben - das ist dieselbe `.md` vs. `.md.template`-Verwechslung, an der auch #106 hing, nur von der anderen 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: de` ist das nicht ableitbar, denn 6.0.0 hat diese Grenze gerade erst neu gezogen (Bump "Control-Plane-Sprache universell", `docs/language-boundaries.md`): Anleitungsprosa ist Control Plane und englisch, `## Template`-Body und `layout:`-Titel sind Seitentext in der KB-Sprache. Der Lauf hat daraus abgeleitet - und das sollte im Dokument stehen, nicht abgeleitet werden muessen: | Teil des Type-Specs | Sprache | Begruendung | |---|---|---| | H1, Pointer-Absatz | Englisch | Anleitungsprosa an einen Agenten = Control Plane | | `## Frontmatter`-Tabelle | unveraendert lassen | die Migration fasst Frontmatter ausdruecklich nicht an | | `## Template`-Block + Nachsatz | unveraendert lassen (hier: deutsch) | Seitentext in der KB-Sprache | Genau 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 ist unmissverstaendlich: ``` OK Recorded the optional 6.0.0-type-guidance-split. Content stays at 5.0.0 - an offer changes a file you own, not the shape of your content. ``` Danach bleibt `doctor` bei `kb-version: 5.0.0 (nothing outstanding up to 6.0.0)`. Das ist korrekt und 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.md` einen Rest-Abschnitt hinterlassen - **repariert in der Instanz** (`b5014d9`) `kind/defect`, Instanzschaden. Gefunden in der Review-Sitzung, live gegengeprueft und dort auch behoben. Steht hier, weil er die Wirkung von Befund 4b und Befund 6 belegt. Bei `types/source.md` wurde der Abschnitt `## Autorenanweisungen` nicht geloescht, sondern zu `## Authoring guidance` **umbenannt**, mit einem verbliebenen deutschen Bullet: ```markdown ## Authoring guidance - Der Titel beginnt mit "Source - ", gefolgt vom Namen der Quelle ``` Zwei Fehler in drei Zeilen: 1. **Ein dritter Kopf desselben Namens in der komponierten Ausgabe.** Zwei sind der Normalzustand und kein Befund: `types describe` setzt selbst einen `## Authoring guidance`-Kopf und inlined darunter die Guidance-Datei, die ihren eigenen gleichnamigen Abschnitt mitbringt - so sieht es bei allen vier Typen aus. `source` hatte danach einen dritten aus dem Type-Spec selbst. 2. **Englische Ueberschrift ueber deutschem Inhalt** in einer instanzeigenen Datei - genau die 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`, `concept` und `comparison` waren sauber - betroffen war nur `source`, der einzige der vier 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, das `wikitool new source` ohnehin erzwingt. **Behoben mit `b5014d9`:** Abschnitt ersatzlos entfernt, geprueft mit dem Muster aus Befund 6 - `types describe source` vor und nach der Aenderung in je eine Datei, dann `diff`. Der Diff zeigt genau die vier entfernten Zeilen und sonst nichts; alle vier Typen komponieren jetzt mit zwei Koepfen. **Nebenbeobachtung, kein Befund:** dass `types describe` einen `## Authoring guidance`-Kopf setzt und 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: > The output must read the same as it did before this migration [...] the structure (frontmatter > fields, template block) must be byte-identical. 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 describe` durch `| head -250` und `| tail -80`, also in Ausschnitten, 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 beiden Ausschnitte. Dasselbe `| head` erzeugte zugleich den SIGPIPE-Exit-1, den der Nebenbefund unter Befund 1 als Trace-Rauschen fuehrt: ein Verhalten, zwei Symptome. Die Gegenprobe ist gelaufen: die Reparatur in `b5014d9` hat das Vorher weggeschrieben und hinterher 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 eine Datei 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 der Gedanke auch in `instructions/migrate-corpus.md` § "Writing the migration document", nicht nur in dieses eine Dokument. Als generisches Muster steht er seit `504149c` bereits in `instructions/upgrade-instance.md` Schritt 12; das ersetzt die beiden Stellen nicht, an denen das Muster eigentlich hingehoert. --- ## Befund 7: der Upgrade-Pfad hatte keine agentengerichtete Prozedur - **erledigt in #108** `kind/defect`, Prozess. Umgesetzt mit `504149c` (`6.1.0-beta.1`); hier bleibt die Evidenz aus dem Lauf stehen, weil sie die Begruendung der Loesung traegt. Die Schrittfolge stand nur in INSTALL.md - einem Dokument fuer Menschen (`AGENTS.md` § File naming: 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 statt Tarball-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 in INSTALL.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 kam `migrate verify` nicht vor. - **Die Agent-Session wurde nie neu gestartet.** Beide Reihenfolgen verlangten das, die eine am Ende von Schritt 6, die andere am Ende des Abschlussberichts. Die optionale Migration lief anschliessend unter dem 5.0.0-Kontrollplan, obwohl `AGENTS.md` im selben Commit +44/-3 bekommen hatte - und genau dort fielen Befund 4b (Sprachgrenze, neu in 6.0.0) und Befund 5 an. - **Drei Reihenfolgen waren im Umlauf**: INSTALL.md Schritt 6, der Abschlussbericht, und die 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, dreizehn Schritte, mit dem Sitzungsneustart zwischen Maschinerie-Publish und Migrationskette statt am Ende und `migrate status` als Wiedereinstiegspunkt. Der Abschlussbericht von `dist upgrade` nennt jetzt die 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: - **Der angekuendigte Grenzuebertritt kam exakt wie beschrieben.** Die Release-Notes sagten voraus, dass `docs verify` nach dem Update auf adoptierten Page-Type-Specs ohne TOC-Region faellt, und nannten `docs toc --apply` als Reparatur. Genau das trat ein (`types/concept.md`, `types/source.md`), und genau das reparierte es - ein Werkzeuglauf, keine Inhaltsmigration. **Nicht identisch mit #106**: dort ging es um `kb/CONVENTIONS.md.template` auf einer *frischen* Instanz; hier um adoptierte `types/*.md` auf dem *Upgrade*-Pfad. Der in #106 umgesetzte Fix (Templates in `toc.target_files()`) deckt diesen Fall nicht ab, weil die betroffenen Dateien bereits im Dateisatz stehen - ihnen fehlte die Region nur, weil sie vor der Scope-Erweiterung adoptiert wurden. - **`dist upgrade` klassifiziert 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 status` hat richtig nicht blockiert.** "Migration: none required" aus den Release-Notes und "Nothing outstanding" aus dem Werkzeug stimmten ueberein. - **Das Mass-Update-Gate hat sauber gearbeitet**: Exit 42 bei 69 Dateien, Token an Dateiliste *und* Inhalt gebunden, Freigabe mit demselben Token akzeptiert, `gate.refused`/`gate.cleared` beide in der Trace. Als Datenpunkt fuer #53: 69 Dateien bei Schwelle 10, und der zweite Publish desselben Laufs lag mit 5 Dateien darunter. - ~~`types describe` komponiert nach der Migration unveraendert.~~ **Korrigiert durch Befund 5:** fuer `entity`, `concept` und `comparison` stimmte es; fuer `source` nicht - dort stand bis `b5014d9` ein dritter `## Authoring guidance`-Kopf in der komponierten Ausgabe. Was fuer alle vier haelt: Frontmatter-Felder und `## Template`-Block sind byte-gleich, nur die Herkunft der Anleitungsprosa hat gewechselt. ## Reproduktion auf einer Dev-Instanz ```bash # 1. Instanz auf 5.0.0 herstellen (aus einem 5.0.0-Checkout) tools/wikitool dist export /tmp/inst-5.0.0 cd /tmp/inst-5.0.0 && git init -q -b main git config user.name Dev && git config user.email dev@example.invalid # Templates adoptieren wie instructions/setup-instance.md Schritt 5/6 python3 -m venv tools/.venv && tools/.venv/bin/pip install -q -r tools/requirements.txt tools/wikitool instructions sync && tools/wikitool index rebuild git add -A && git commit -qm baseline # 2. Die Drift dieses Laufs nachstellen (Befund 3) # kb/CONTRACT.md durch einen Markdown-Formatter schicken - Whitespace-only, # inhaltlich identisch - und committen. # 3. Nicht setzen, um Befund 1 zu reproduzieren: WIKITOOL_SESSION_ID # Jeden wikitool-Aufruf aus einer eigenen Shell absetzen (wie ein Agent-Harness es tut). # 4. Upgrade fahren tools/wikitool version check # meldet Grenzuebertritt tools/wikitool version notes # ERWARTET Exit 1 -> Befund 2 tools/wikitool dist upgrade <6.0.0-tarball> --dry-run tools/wikitool dist upgrade <6.0.0-tarball> # ERWARTET Exit 1 -> Befund 3 # -> Handreparatur + Commit, dann erneut tools/wikitool migrate status && tools/wikitool instructions sync tools/wikitool doctor tools/wikitool docs verify # ERWARTET Exit 1 auf types/*.md tools/wikitool docs toc --apply && tools/wikitool docs verify tools/wikitool instructions verify && tools/wikitool lint # 5. Befund 1 messen python3 -c "import json;d=json.load(open('tools/.wikitool_session/budget.json'));\ print(len(d),'Buckets; max count:',max(e.get('count',0) for e in d.values()))" tools/wikitool eval sessions # ERWARTET: viele Buckets, je 1-3 Events # 6. Befund 5/6 reproduzieren: die optionale Migration fahren und vorher/nachher diffen tools/wikitool types describe source > /tmp/source-vorher.txt # ... Schritte 3 und 4 des Migrationsdokuments ausfuehren ... tools/wikitool types describe source > /tmp/source-nachher.txt diff /tmp/source-vorher.txt /tmp/source-nachher.txt # ERWARTET ohne Gegenmassnahme: ein dritter "## Authoring guidance"-Kopf im Nachher grep -c '^## Authoring guidance' /tmp/source-nachher.txt # ERWARTET 3, korrekt sind 2 # Gegenprobe: bei entity/concept/comparison sind es vorher wie nachher 2 ``` Erwartetes Ergebnis von Schritt 5 gegen diesen Lauf: Bucket-Zahl in der Groessenordnung der abgesetzten Kommandos, `max count` deutlich unter 60. Wird `WIKITOOL_SESSION_ID` dagegen 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 - [ ] **Befund 1:** Ein Lauf auf Claude Code landet in genau einem Telemetrie-Bucket, nachgewiesen an einer echten Trace - oder es ist in `EVALS.md` begruendet, warum die Zersplitterung hinnehmbar ist und was stattdessen der Join-Key ist. - [ ] **Befund 1:** Das Iteration-Budget-Gate zaehlt ueber einen ganzen Lauf. Ein Test, der 61 Aufrufe aus je eigener Shell absetzt, muss die Verweigerung sehen; heute waere er gruen und damit blind. - [ ] **Befund 1:** Entschieden und dokumentiert, wie sich das zu #82 verhaelt - Hooks ohne gemeinsamen Schluessel loesen die L2-Blindheit nicht. - [x] **Befund 1:** `instructions/session-setup.md` nennt eine Form, die auf einem Harness mit Shell-pro-Tool-Call wirkt - nicht nur `export` einmal pro Sitzung. Erledigt in #108 (`504149c`): Inline-Form pro Aufruf, mit dem Einzeiler zum Feststellen, welcher Fall vorliegt. - [ ] **Befund 2:** `tools/wikitool version notes` liefert auf einer frisch ausgelieferten Instanz die 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.) - [ ] **Befund 3:** Eine lokal geaenderte stackeigene Datei laesst sich in **einem** Kommando auf die Release-Fassung zuruecksetzen; `tools/CONTRACT.md`s `dist upgrade`-Zeile nennt den Weg. - [ ] **Befund 3:** Die Fehlermeldung des Abbruchs sagt, welche Antwortmoeglichkeiten es gibt und welche nicht - so, dass "Default = Release nehmen" nicht als Erwartung stehenbleibt. - [ ] **Befund 4:** Das Migrationsdokument verweist auf `types/entity.md.template` und sagt, in welcher Sprache der Pointer-Absatz zu schreiben ist. - [x] **Befund 5:** `tools/wikitool types describe source` gibt in der Instanz `nathan` so viele `## Authoring guidance`-Koepfe aus wie bei den anderen drei Typen (zwei), und kein Abschnitt dort traegt eine englische Ueberschrift ueber deutschem Inhalt. Erledigt mit `b5014d9`, geprueft per Vorher/Nachher-Diff. - [ ] **Befund 6:** Schritt 5 des Migrationsdokuments verlangt eine festgehaltene Vorher-Ausgabe und einen Diff; `instructions/migrate-corpus.md` fuehrt dasselbe Muster fuer kuenftige `assisted`-Migrationen. - [x] **Befund 7:** abgehandelt in #108 - `instructions/upgrade-instance.md` (`manual: true`) existiert, `dist upgrade`s Abschlussbericht nennt sie, INSTALL.md traegt die Schrittfolge nicht mehr doppelt. - [ ] `pytest`, `docs verify`, `instructions verify` ohne neue Befunde. (Fuer den Anteil aus #108 erfuellt: 1276 Tests, beide Verifier gruen.) ## Herkunft und Artefakte Lauf vom 2026-09-15, Instanz `5.0.0 -> 6.0.0`, Harness Claude Code, Sitzung `671c1b9a`. 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 (`b5014d9` in `torben/nathan`). Aus derselben Sitzung stammt #108, das Befund 7 abgeschlossen hat. **Erster Kommentar traegt die vollstaendige Telemetrie des Laufs verbatim** - 63 Events, aus 21 Bucket-Dateien nach `ts` zusammengefuehrt. Einzige Aenderung: die drei identischen 69-Pfad-Arrays in `gate.refused`/`gate.cleared`/`publish.commit` sind 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 ist oeffentlich (`instructions/private-instance.md`: *"the cost of a mistaken push is disclosure rather than 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.scrub` betrifft: eine Maskierung per Regex ueber **Terminalausgabe** greift nicht, solange die ANSI-Sequenzen drinstehen - `ssh://git@host:PORT/...` und `Vorname Nachname <mail@host>` waren durch eingestreute Farbcodes aufgetrennt und ueberlebten den ersten Durchgang unmaskiert. ANSI muss vor der Maskierung entfernt werden, nicht danach.
torben added the prio/plannedsize/Marea/distributionarea/processkind/defect labels 2026-09-16 06:08:51 +00:00
Author
Owner

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 nach ts. Unveraendert bis auf
eine Sache: die drei identischen 69-Pfad-Arrays in gate.refused, gate.cleared und dem ersten
publish.commit sind durch <<69 Pfade - elidiert, Liste einmal unten>> ersetzt; die Liste steht
darunter. Ausserdem sind bei prompt.submitted die Felder transcript_path und cwd entfernt
(lokale Pfade, kein Informationswert hier) - prompt, prompt_sha256 und prompt_length stehen
unveraendert da.

Dass dieselbe Datei 21 session_id-Werte traegt, ist Befund 1 und kein Artefakt der Zusammenfuehrung.

{"v": 1, "ts": "2026-09-15T19:44:52.158756+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3834977, "seq": 1, "source": "claude-code", "event": "session.start", "attrs": {"harness": "claude-code", "completeness": ["session.start", "session.end", "prompt.submitted", "tool.pre", "tool.post", "tool.error", "turn.end", "instructions.loaded", "subagent.start", "subagent.stop", "compaction"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:44:52.158880+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3834977, "seq": 2, "source": "claude-code", "event": "prompt.submitted", "attrs": {"harness_event": "UserPromptSubmit", "prompt_length": 46, "prompt_sha256": "2ebc776efd9cfeee7a54967b07dafb002bfc5193d2595f282d92850c07907851", "prompt": "aktualisiere den stack auf die letzte version."}}
{"v": 1, "ts": "2026-09-15T19:45:07.753037+00:00", "session_id": "3835015", "pid": 3835017, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:45:07.753149+00:00", "session_id": "3835015", "pid": 3835017, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "version", "args": ["check"], "exit_code": 0, "duration_ms": 104.1}}
{"v": 1, "ts": "2026-09-15T19:45:18.625842+00:00", "session_id": "3835056", "pid": 3835058, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:45:18.625930+00:00", "session_id": "3835056", "pid": 3835058, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "migrate", "args": ["status"], "exit_code": 0, "duration_ms": 255.0}}
{"v": 1, "ts": "2026-09-15T19:45:18.937497+00:00", "session_id": "3835056", "pid": 3835063, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "version", "args": ["notes"], "exit_code": 1, "duration_ms": 33.7}}
{"v": 1, "ts": "2026-09-15T19:46:03.354028+00:00", "session_id": "3835179", "pid": 3835181, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:46:03.354109+00:00", "session_id": "3835179", "pid": 3835181, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "dist", "args": ["upgrade", "/home/torben/.claude/jobs/8af88af0/tmp/chemenu-stack-6.0.0.tar.gz", "--dry-run"], "exit_code": 0, "duration_ms": 129.8}}
{"v": 1, "ts": "2026-09-15T19:46:31.306797+00:00", "session_id": "3835232", "pid": 3835234, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:46:31.306874+00:00", "session_id": "3835232", "pid": 3835234, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "dist", "args": ["upgrade", "/home/torben/.claude/jobs/8af88af0/tmp/chemenu-stack-6.0.0.tar.gz"], "exit_code": 1, "duration_ms": 130.2}}
{"v": 1, "ts": "2026-09-15T19:46:59.478952+00:00", "session_id": "3835285", "pid": 3835287, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:46:59.479019+00:00", "session_id": "3835285", "pid": 3835287, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "dist", "args": ["upgrade", "/home/torben/.claude/jobs/8af88af0/tmp/chemenu-stack-6.0.0.tar.gz", "--dry-run"], "exit_code": 1, "duration_ms": 44.8}}
{"v": 1, "ts": "2026-09-15T19:47:17.147609+00:00", "session_id": "3835339", "pid": 3835341, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:47:17.147690+00:00", "session_id": "3835339", "pid": 3835341, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "dist", "args": ["upgrade", "/home/torben/.claude/jobs/8af88af0/tmp/chemenu-stack-6.0.0.tar.gz", "--dry-run"], "exit_code": 0, "duration_ms": 130.4}}
{"v": 1, "ts": "2026-09-15T19:47:22.989307+00:00", "session_id": "3835353", "pid": 3835355, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:47:22.989389+00:00", "session_id": "3835353", "pid": 3835355, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "dist", "args": ["upgrade", "/home/torben/.claude/jobs/8af88af0/tmp/chemenu-stack-6.0.0.tar.gz"], "exit_code": 0, "duration_ms": 172.5}}
{"v": 1, "ts": "2026-09-15T19:47:28.789436+00:00", "session_id": "3835371", "pid": 3835373, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:47:28.789523+00:00", "session_id": "3835371", "pid": 3835373, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "migrate", "args": ["status"], "exit_code": 0, "duration_ms": 57.1}}
{"v": 1, "ts": "2026-09-15T19:47:29.110458+00:00", "session_id": "3835371", "pid": 3835377, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "instructions", "args": ["sync"], "exit_code": 0, "duration_ms": 39.5}}
{"v": 1, "ts": "2026-09-15T19:47:44.434440+00:00", "session_id": "3835425", "pid": 3835427, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:47:44.434529+00:00", "session_id": "3835425", "pid": 3835427, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "doctor", "args": [], "exit_code": 0, "duration_ms": 92.7}}
{"v": 1, "ts": "2026-09-15T19:47:46.370777+00:00", "session_id": "3835425", "pid": 3835437, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["verify"], "exit_code": 1, "duration_ms": 1644.6}}
{"v": 1, "ts": "2026-09-15T19:47:53.978922+00:00", "session_id": "3835460", "pid": 3835462, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:47:53.979000+00:00", "session_id": "3835460", "pid": 3835462, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["toc", "--apply"], "exit_code": 0, "duration_ms": 86.0}}
{"v": 1, "ts": "2026-09-15T19:47:58.835954+00:00", "session_id": "3835471", "pid": 3835473, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:47:58.836043+00:00", "session_id": "3835471", "pid": 3835473, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["verify"], "exit_code": 0, "duration_ms": 414.3}}
{"v": 1, "ts": "2026-09-15T19:47:59.216332+00:00", "session_id": "3835471", "pid": 3835482, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "instructions", "args": ["verify"], "exit_code": 0, "duration_ms": 97.5}}
{"v": 1, "ts": "2026-09-15T19:48:00.112259+00:00", "session_id": "3835471", "pid": 3835485, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "lint", "args": [], "exit_code": 0, "duration_ms": 614.3}}
{"v": 1, "ts": "2026-09-15T19:48:28.408424+00:00", "session_id": "3835548", "pid": 3835550, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:48:28.408499+00:00", "session_id": "3835548", "pid": 3835550, "seq": 2, "source": "wikitool", "event": "gate.refused", "attrs": {"gate": "mass-update", "reason": "needs-clearance", "token": "96e2563ff596", "presented_token": null, "changed": 69, "counted": 69, "threshold": 10, "files": "<<69 Pfade - elidiert, Liste einmal unten>>"}}
{"v": 1, "ts": "2026-09-15T19:48:28.429958+00:00", "session_id": "3835548", "pid": 3835550, "seq": 3, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "publish", "args": ["--message", "stack: upgrade machinery 5.0.0 -> 6.0.0"], "exit_code": 42, "duration_ms": 416.9}}
{"v": 1, "ts": "2026-09-15T19:58:14.796703+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3836779, "seq": 1, "source": "claude-code", "event": "prompt.submitted", "attrs": {"harness_event": "UserPromptSubmit", "prompt_length": 8, "prompt_sha256": "2687f86ed6784b8a5fca36e6c468e12aa44dc3c7e8137e3160d1a95079bdcd02", "prompt": "approved"}}
{"v": 1, "ts": "2026-09-15T19:58:21.785485+00:00", "session_id": "3836791", "pid": 3836793, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T19:58:21.785560+00:00", "session_id": "3836791", "pid": 3836793, "seq": 2, "source": "wikitool", "event": "gate.cleared", "attrs": {"gate": "mass-update", "token": "96e2563ff596", "counted": 69, "threshold": 10, "files": "<<69 Pfade - elidiert, Liste einmal unten>>"}}
{"v": 1, "ts": "2026-09-15T19:58:22.573729+00:00", "session_id": "3836791", "pid": 3836793, "seq": 3, "source": "wikitool", "event": "publish.commit", "attrs": {"summary": "stack: upgrade machinery 5.0.0 -> 6.0.0", "files": "<<69 Pfade - elidiert, Liste einmal unten>>", "changed": 69, "counted": 69, "paths": [], "pushed": true, "remote": "origin", "branch": "main"}}
{"v": 1, "ts": "2026-09-15T19:58:22.586659+00:00", "session_id": "3836791", "pid": 3836793, "seq": 4, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "publish", "args": ["--confirm", "96e2563ff596", "--message", "stack: upgrade machinery 5.0.0 -> 6.0.0"], "exit_code": 0, "duration_ms": 1181.8}}
{"v": 1, "ts": "2026-09-15T20:01:51.551944+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3837219, "seq": 1, "source": "claude-code", "event": "prompt.submitted", "attrs": {"harness_event": "UserPromptSubmit", "prompt_length": 10, "prompt_sha256": "137b05c8fcd27c223b7682bd736980295e97ce5cc370b27120884115e8a0b887", "prompt": "make it so"}}
{"v": 1, "ts": "2026-09-15T20:02:01.986725+00:00", "session_id": "3837235", "pid": 3837237, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T20:02:01.986800+00:00", "session_id": "3837235", "pid": 3837237, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["list"], "exit_code": 0, "duration_ms": 32.8}}
{"v": 1, "ts": "2026-09-15T20:06:01.055001+00:00", "session_id": "3837668", "pid": 3837671, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T20:06:01.055085+00:00", "session_id": "3837668", "pid": 3837671, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["toc", "--apply"], "exit_code": 0, "duration_ms": 89.2}}
{"v": 1, "ts": "2026-09-15T20:06:01.755430+00:00", "session_id": "3837668", "pid": 3837674, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["verify"], "exit_code": 0, "duration_ms": 415.2}}
{"v": 1, "ts": "2026-09-15T20:06:08.439953+00:00", "session_id": "3837691", "pid": 3837693, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T20:06:08.440078+00:00", "session_id": "3837691", "pid": 3837693, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["describe", "entity"], "exit_code": 0, "duration_ms": 41.1}}
{"v": 1, "ts": "2026-09-15T20:06:08.756049+00:00", "session_id": "3837691", "pid": 3837696, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["describe", "concept"], "exit_code": 0, "duration_ms": 40.3}}
{"v": 1, "ts": "2026-09-15T20:06:09.086658+00:00", "session_id": "3837691", "pid": 3837703, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["describe", "source"], "exit_code": 1, "duration_ms": 41.4}}
{"v": 1, "ts": "2026-09-15T20:06:16.367533+00:00", "session_id": "3837722", "pid": 3837724, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T20:06:16.367641+00:00", "session_id": "3837722", "pid": 3837724, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["describe", "source"], "exit_code": 0, "duration_ms": 42.5}}
{"v": 1, "ts": "2026-09-15T20:06:16.686072+00:00", "session_id": "3837722", "pid": 3837728, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["describe", "comparison"], "exit_code": 0, "duration_ms": 38.6}}
{"v": 1, "ts": "2026-09-15T20:06:24.306079+00:00", "session_id": "3837739", "pid": 3837741, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T20:06:24.306152+00:00", "session_id": "3837739", "pid": 3837741, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["verify"], "exit_code": 0, "duration_ms": 403.3}}
{"v": 1, "ts": "2026-09-15T20:06:24.686788+00:00", "session_id": "3837739", "pid": 3837749, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "instructions", "args": ["verify"], "exit_code": 0, "duration_ms": 93.4}}
{"v": 1, "ts": "2026-09-15T20:06:25.049867+00:00", "session_id": "3837739", "pid": 3837752, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "doctor", "args": [], "exit_code": 0, "duration_ms": 65.5}}
{"v": 1, "ts": "2026-09-15T20:06:25.397424+00:00", "session_id": "3837739", "pid": 3837764, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "migrate", "args": ["status"], "exit_code": 0, "duration_ms": 56.9}}
{"v": 1, "ts": "2026-09-15T20:06:33.119504+00:00", "session_id": "3837778", "pid": 3837780, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T20:06:33.119572+00:00", "session_id": "3837778", "pid": 3837780, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "migrate", "args": ["done", "6.0.0", "--pages", "0"], "exit_code": 0, "duration_ms": 36.2}}
{"v": 1, "ts": "2026-09-15T20:06:33.448615+00:00", "session_id": "3837778", "pid": 3837783, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "migrate", "args": ["status"], "exit_code": 0, "duration_ms": 54.4}}
{"v": 1, "ts": "2026-09-15T20:06:43.228331+00:00", "session_id": "3837804", "pid": 3837806, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}}
{"v": 1, "ts": "2026-09-15T20:06:43.228414+00:00", "session_id": "3837804", "pid": 3837806, "seq": 2, "source": "wikitool", "event": "publish.commit", "attrs": {"summary": "types: take offered 6.0.0-type-guidance-split migration\n\nLink entity/concept/source/comparison to their new stack-owned\ntypes/<name>.guidance.md so they receive future authoring-prose\nimprovements again. Frontmatter and Template blocks untouched.", "files": [".wikitool-kb.json", "types/comparison.md", "types/concept.md", "types/entity.md", "types/source.md"], "changed": 5, "counted": 5, "paths": [], "pushed": true, "remote": "origin", "branch": "main"}}
{"v": 1, "ts": "2026-09-15T20:06:43.234283+00:00", "session_id": "3837804", "pid": 3837806, "seq": 3, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "publish", "args": ["--message", "types: take offered 6.0.0-type-guidance-split migration\n\nLink entity/concept/source/comparison to their new stack-owned\ntypes/<name>.guidance.md so they receive future authoring-prose\nimprovements again. Frontmatter and Template blocks untouched."], "exit_code": 0, "duration_ms": 970.4}}
{"v": 1, "ts": "2026-09-15T20:23:49.966805+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3839739, "seq": 1, "source": "claude-code", "event": "prompt.submitted", "attrs": {"harness_event": "UserPromptSubmit", "prompt_length": 41, "prompt_sha256": "08a258dc7245e17391c89d8c434d03e57ef1211886559173a18957e3d29e7f66", "prompt": "Can you access Torben/chemenu @gitea-mcp?"}}
{"v": 1, "ts": "2026-09-15T20:26:52.076905+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3840230, "seq": 1, "source": "claude-code", "event": "prompt.submitted", "attrs": {"harness_event": "UserPromptSubmit", "prompt_length": 393, "prompt_sha256": "fcf32a5b6942cb94a800ac558ccaafdaa4fd39332e63870ef46075084ba210f4", "prompt": "Do a full analysis and runtime data collection of this upgrade run. Include stack specific tracing and if somehow possible, take the raw session transcript as well. Create an issue in the chemenu repo collecting this telemetry as verbatim as possible, rely on file attachments if possible. \nGoal is to use your analysis to validate the upgrade procedure on a dev instance of the chemenu stack."}}

Die elidierte 69-Pfad-Liste

Identisch in gate.refused, gate.cleared und dem ersten publish.commit - das ist der
Commit dcc17df:

.wikitool-release.json
AGENTS.md
ENVIRONMENT.md.template
README.md
SOUL.md.template
USER.md.template
VERSION
docs/language-boundaries.md
docs/ownership-and-templates.md
docs/version-model.md
instructions/CONTRACT.md
instructions/gates.md
instructions/migrations/6.0.0-type-guidance-split.md
instructions/session-setup.md
instructions/setup-instance.md
instructions/wiki-ingest/SKILL.md
instructions/wiki-lint/SKILL.md
instructions/wiki-manage/SKILL.md
instructions/wiki-query/SKILL.md
instructions/wiki-status/SKILL.md
kb/CONVENTIONS.md.template
kb/concepts/COLLECTION.md.template
kb/sources/COLLECTION.md.template
tools/CONTRACT.md
tools/README.md
tools/chemenu/api.py
tools/chemenu/commands/dist_cmd.py
tools/chemenu/commands/docs_verify.py
tools/chemenu/commands/git_publish.py
tools/chemenu/commands/instructions_cmd.py
tools/chemenu/commands/run_budget.py
tools/chemenu/commands/search.py
tools/chemenu/commands/types_cmd.py
tools/chemenu/commands/version_cmd.py
tools/chemenu/mcp/server.py
tools/chemenu/search/service.py
tools/chemenu/search/types.py
tools/chemenu/tests/test_api.py
tools/chemenu/tests/test_dist_cmd.py
tools/chemenu/tests/test_dist_upgrade.py
tools/chemenu/tests/test_docs_verify.py
tools/chemenu/tests/test_git_publish.py
tools/chemenu/tests/test_instructions_cmd.py
tools/chemenu/tests/test_mcp_server.py
tools/chemenu/tests/test_run_budget.py
tools/chemenu/tests/test_search.py
tools/chemenu/tests/test_toc.py
tools/chemenu/tests/test_type_resolver.py
tools/chemenu/tests/test_types_cmd.py
tools/chemenu/tests/test_version_cmd.py
tools/chemenu/toc.py
tools/chemenu/type_resolver.py
tools/chemenu/types_core.py
tools/chemenu/version.py
types/comparison.guidance.md
types/comparison.md.template
types/concept.guidance.md
types/concept.md
types/concept.md.template
types/entity.guidance.md
types/entity.md.template
types/lint-report.md
types/source.guidance.md
types/source.md
types/source.md.template
types/type-guidance.md
types/type-guidance.schema.yaml
types/type-spec.md
types/type-spec.schema.yaml

Abgeleitete Kennzahlen

Event-Histogramm ueber die 63 Zeilen:

  33  wikitool.call
  21  session.start
   5  prompt.submitted
   2  publish.commit
   1  gate.refused
   1  gate.cleared

Laufzeiten, soweit auffaellig: docs verify kalt 1644.6 ms, danach 403-415 ms (dreimal gemessen).
publish --confirm 1181.8 ms inklusive Push, der zweite Publish 970.4 ms. Alles andere unter
300 ms.

budget.state taucht in der ganzen Trace nicht auf, obwohl das Event im
completeness-Feld jedes session.start als meldbar gefuehrt wird - passt zu Befund 1, Folge 2:
ein Zaehler, der nie in die Naehe seiner Schwelle kommt, hat auch nichts zu melden.

## 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 nach `ts`. Unveraendert bis auf **eine** Sache: die drei identischen 69-Pfad-Arrays in `gate.refused`, `gate.cleared` und dem ersten `publish.commit` sind durch `<<69 Pfade - elidiert, Liste einmal unten>>` ersetzt; die Liste steht darunter. Ausserdem sind bei `prompt.submitted` die Felder `transcript_path` und `cwd` entfernt (lokale Pfade, kein Informationswert hier) - `prompt`, `prompt_sha256` und `prompt_length` stehen unveraendert da. Dass dieselbe Datei 21 `session_id`-Werte traegt, ist Befund 1 und kein Artefakt der Zusammenfuehrung. ```jsonl {"v": 1, "ts": "2026-09-15T19:44:52.158756+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3834977, "seq": 1, "source": "claude-code", "event": "session.start", "attrs": {"harness": "claude-code", "completeness": ["session.start", "session.end", "prompt.submitted", "tool.pre", "tool.post", "tool.error", "turn.end", "instructions.loaded", "subagent.start", "subagent.stop", "compaction"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:44:52.158880+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3834977, "seq": 2, "source": "claude-code", "event": "prompt.submitted", "attrs": {"harness_event": "UserPromptSubmit", "prompt_length": 46, "prompt_sha256": "2ebc776efd9cfeee7a54967b07dafb002bfc5193d2595f282d92850c07907851", "prompt": "aktualisiere den stack auf die letzte version."}} {"v": 1, "ts": "2026-09-15T19:45:07.753037+00:00", "session_id": "3835015", "pid": 3835017, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:45:07.753149+00:00", "session_id": "3835015", "pid": 3835017, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "version", "args": ["check"], "exit_code": 0, "duration_ms": 104.1}} {"v": 1, "ts": "2026-09-15T19:45:18.625842+00:00", "session_id": "3835056", "pid": 3835058, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:45:18.625930+00:00", "session_id": "3835056", "pid": 3835058, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "migrate", "args": ["status"], "exit_code": 0, "duration_ms": 255.0}} {"v": 1, "ts": "2026-09-15T19:45:18.937497+00:00", "session_id": "3835056", "pid": 3835063, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "version", "args": ["notes"], "exit_code": 1, "duration_ms": 33.7}} {"v": 1, "ts": "2026-09-15T19:46:03.354028+00:00", "session_id": "3835179", "pid": 3835181, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:46:03.354109+00:00", "session_id": "3835179", "pid": 3835181, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "dist", "args": ["upgrade", "/home/torben/.claude/jobs/8af88af0/tmp/chemenu-stack-6.0.0.tar.gz", "--dry-run"], "exit_code": 0, "duration_ms": 129.8}} {"v": 1, "ts": "2026-09-15T19:46:31.306797+00:00", "session_id": "3835232", "pid": 3835234, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:46:31.306874+00:00", "session_id": "3835232", "pid": 3835234, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "dist", "args": ["upgrade", "/home/torben/.claude/jobs/8af88af0/tmp/chemenu-stack-6.0.0.tar.gz"], "exit_code": 1, "duration_ms": 130.2}} {"v": 1, "ts": "2026-09-15T19:46:59.478952+00:00", "session_id": "3835285", "pid": 3835287, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:46:59.479019+00:00", "session_id": "3835285", "pid": 3835287, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "dist", "args": ["upgrade", "/home/torben/.claude/jobs/8af88af0/tmp/chemenu-stack-6.0.0.tar.gz", "--dry-run"], "exit_code": 1, "duration_ms": 44.8}} {"v": 1, "ts": "2026-09-15T19:47:17.147609+00:00", "session_id": "3835339", "pid": 3835341, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:47:17.147690+00:00", "session_id": "3835339", "pid": 3835341, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "dist", "args": ["upgrade", "/home/torben/.claude/jobs/8af88af0/tmp/chemenu-stack-6.0.0.tar.gz", "--dry-run"], "exit_code": 0, "duration_ms": 130.4}} {"v": 1, "ts": "2026-09-15T19:47:22.989307+00:00", "session_id": "3835353", "pid": 3835355, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:47:22.989389+00:00", "session_id": "3835353", "pid": 3835355, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "dist", "args": ["upgrade", "/home/torben/.claude/jobs/8af88af0/tmp/chemenu-stack-6.0.0.tar.gz"], "exit_code": 0, "duration_ms": 172.5}} {"v": 1, "ts": "2026-09-15T19:47:28.789436+00:00", "session_id": "3835371", "pid": 3835373, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:47:28.789523+00:00", "session_id": "3835371", "pid": 3835373, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "migrate", "args": ["status"], "exit_code": 0, "duration_ms": 57.1}} {"v": 1, "ts": "2026-09-15T19:47:29.110458+00:00", "session_id": "3835371", "pid": 3835377, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "instructions", "args": ["sync"], "exit_code": 0, "duration_ms": 39.5}} {"v": 1, "ts": "2026-09-15T19:47:44.434440+00:00", "session_id": "3835425", "pid": 3835427, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:47:44.434529+00:00", "session_id": "3835425", "pid": 3835427, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "doctor", "args": [], "exit_code": 0, "duration_ms": 92.7}} {"v": 1, "ts": "2026-09-15T19:47:46.370777+00:00", "session_id": "3835425", "pid": 3835437, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["verify"], "exit_code": 1, "duration_ms": 1644.6}} {"v": 1, "ts": "2026-09-15T19:47:53.978922+00:00", "session_id": "3835460", "pid": 3835462, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:47:53.979000+00:00", "session_id": "3835460", "pid": 3835462, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["toc", "--apply"], "exit_code": 0, "duration_ms": 86.0}} {"v": 1, "ts": "2026-09-15T19:47:58.835954+00:00", "session_id": "3835471", "pid": 3835473, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:47:58.836043+00:00", "session_id": "3835471", "pid": 3835473, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["verify"], "exit_code": 0, "duration_ms": 414.3}} {"v": 1, "ts": "2026-09-15T19:47:59.216332+00:00", "session_id": "3835471", "pid": 3835482, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "instructions", "args": ["verify"], "exit_code": 0, "duration_ms": 97.5}} {"v": 1, "ts": "2026-09-15T19:48:00.112259+00:00", "session_id": "3835471", "pid": 3835485, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "lint", "args": [], "exit_code": 0, "duration_ms": 614.3}} {"v": 1, "ts": "2026-09-15T19:48:28.408424+00:00", "session_id": "3835548", "pid": 3835550, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:48:28.408499+00:00", "session_id": "3835548", "pid": 3835550, "seq": 2, "source": "wikitool", "event": "gate.refused", "attrs": {"gate": "mass-update", "reason": "needs-clearance", "token": "96e2563ff596", "presented_token": null, "changed": 69, "counted": 69, "threshold": 10, "files": "<<69 Pfade - elidiert, Liste einmal unten>>"}} {"v": 1, "ts": "2026-09-15T19:48:28.429958+00:00", "session_id": "3835548", "pid": 3835550, "seq": 3, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "publish", "args": ["--message", "stack: upgrade machinery 5.0.0 -> 6.0.0"], "exit_code": 42, "duration_ms": 416.9}} {"v": 1, "ts": "2026-09-15T19:58:14.796703+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3836779, "seq": 1, "source": "claude-code", "event": "prompt.submitted", "attrs": {"harness_event": "UserPromptSubmit", "prompt_length": 8, "prompt_sha256": "2687f86ed6784b8a5fca36e6c468e12aa44dc3c7e8137e3160d1a95079bdcd02", "prompt": "approved"}} {"v": 1, "ts": "2026-09-15T19:58:21.785485+00:00", "session_id": "3836791", "pid": 3836793, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T19:58:21.785560+00:00", "session_id": "3836791", "pid": 3836793, "seq": 2, "source": "wikitool", "event": "gate.cleared", "attrs": {"gate": "mass-update", "token": "96e2563ff596", "counted": 69, "threshold": 10, "files": "<<69 Pfade - elidiert, Liste einmal unten>>"}} {"v": 1, "ts": "2026-09-15T19:58:22.573729+00:00", "session_id": "3836791", "pid": 3836793, "seq": 3, "source": "wikitool", "event": "publish.commit", "attrs": {"summary": "stack: upgrade machinery 5.0.0 -> 6.0.0", "files": "<<69 Pfade - elidiert, Liste einmal unten>>", "changed": 69, "counted": 69, "paths": [], "pushed": true, "remote": "origin", "branch": "main"}} {"v": 1, "ts": "2026-09-15T19:58:22.586659+00:00", "session_id": "3836791", "pid": 3836793, "seq": 4, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "publish", "args": ["--confirm", "96e2563ff596", "--message", "stack: upgrade machinery 5.0.0 -> 6.0.0"], "exit_code": 0, "duration_ms": 1181.8}} {"v": 1, "ts": "2026-09-15T20:01:51.551944+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3837219, "seq": 1, "source": "claude-code", "event": "prompt.submitted", "attrs": {"harness_event": "UserPromptSubmit", "prompt_length": 10, "prompt_sha256": "137b05c8fcd27c223b7682bd736980295e97ce5cc370b27120884115e8a0b887", "prompt": "make it so"}} {"v": 1, "ts": "2026-09-15T20:02:01.986725+00:00", "session_id": "3837235", "pid": 3837237, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T20:02:01.986800+00:00", "session_id": "3837235", "pid": 3837237, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["list"], "exit_code": 0, "duration_ms": 32.8}} {"v": 1, "ts": "2026-09-15T20:06:01.055001+00:00", "session_id": "3837668", "pid": 3837671, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T20:06:01.055085+00:00", "session_id": "3837668", "pid": 3837671, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["toc", "--apply"], "exit_code": 0, "duration_ms": 89.2}} {"v": 1, "ts": "2026-09-15T20:06:01.755430+00:00", "session_id": "3837668", "pid": 3837674, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["verify"], "exit_code": 0, "duration_ms": 415.2}} {"v": 1, "ts": "2026-09-15T20:06:08.439953+00:00", "session_id": "3837691", "pid": 3837693, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T20:06:08.440078+00:00", "session_id": "3837691", "pid": 3837693, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["describe", "entity"], "exit_code": 0, "duration_ms": 41.1}} {"v": 1, "ts": "2026-09-15T20:06:08.756049+00:00", "session_id": "3837691", "pid": 3837696, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["describe", "concept"], "exit_code": 0, "duration_ms": 40.3}} {"v": 1, "ts": "2026-09-15T20:06:09.086658+00:00", "session_id": "3837691", "pid": 3837703, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["describe", "source"], "exit_code": 1, "duration_ms": 41.4}} {"v": 1, "ts": "2026-09-15T20:06:16.367533+00:00", "session_id": "3837722", "pid": 3837724, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T20:06:16.367641+00:00", "session_id": "3837722", "pid": 3837724, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["describe", "source"], "exit_code": 0, "duration_ms": 42.5}} {"v": 1, "ts": "2026-09-15T20:06:16.686072+00:00", "session_id": "3837722", "pid": 3837728, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "types", "args": ["describe", "comparison"], "exit_code": 0, "duration_ms": 38.6}} {"v": 1, "ts": "2026-09-15T20:06:24.306079+00:00", "session_id": "3837739", "pid": 3837741, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T20:06:24.306152+00:00", "session_id": "3837739", "pid": 3837741, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "docs", "args": ["verify"], "exit_code": 0, "duration_ms": 403.3}} {"v": 1, "ts": "2026-09-15T20:06:24.686788+00:00", "session_id": "3837739", "pid": 3837749, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "instructions", "args": ["verify"], "exit_code": 0, "duration_ms": 93.4}} {"v": 1, "ts": "2026-09-15T20:06:25.049867+00:00", "session_id": "3837739", "pid": 3837752, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "doctor", "args": [], "exit_code": 0, "duration_ms": 65.5}} {"v": 1, "ts": "2026-09-15T20:06:25.397424+00:00", "session_id": "3837739", "pid": 3837764, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "migrate", "args": ["status"], "exit_code": 0, "duration_ms": 56.9}} {"v": 1, "ts": "2026-09-15T20:06:33.119504+00:00", "session_id": "3837778", "pid": 3837780, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T20:06:33.119572+00:00", "session_id": "3837778", "pid": 3837780, "seq": 2, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "migrate", "args": ["done", "6.0.0", "--pages", "0"], "exit_code": 0, "duration_ms": 36.2}} {"v": 1, "ts": "2026-09-15T20:06:33.448615+00:00", "session_id": "3837778", "pid": 3837783, "seq": 1, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "migrate", "args": ["status"], "exit_code": 0, "duration_ms": 54.4}} {"v": 1, "ts": "2026-09-15T20:06:43.228331+00:00", "session_id": "3837804", "pid": 3837806, "seq": 1, "source": "wikitool", "event": "session.start", "attrs": {"harness": "wikitool", "completeness": ["wikitool.call", "gate.refused", "page.written", "publish.commit", "budget.state", "gate.cleared"], "synthesized": true}} {"v": 1, "ts": "2026-09-15T20:06:43.228414+00:00", "session_id": "3837804", "pid": 3837806, "seq": 2, "source": "wikitool", "event": "publish.commit", "attrs": {"summary": "types: take offered 6.0.0-type-guidance-split migration\n\nLink entity/concept/source/comparison to their new stack-owned\ntypes/<name>.guidance.md so they receive future authoring-prose\nimprovements again. Frontmatter and Template blocks untouched.", "files": [".wikitool-kb.json", "types/comparison.md", "types/concept.md", "types/entity.md", "types/source.md"], "changed": 5, "counted": 5, "paths": [], "pushed": true, "remote": "origin", "branch": "main"}} {"v": 1, "ts": "2026-09-15T20:06:43.234283+00:00", "session_id": "3837804", "pid": 3837806, "seq": 3, "source": "wikitool", "event": "wikitool.call", "attrs": {"command": "publish", "args": ["--message", "types: take offered 6.0.0-type-guidance-split migration\n\nLink entity/concept/source/comparison to their new stack-owned\ntypes/<name>.guidance.md so they receive future authoring-prose\nimprovements again. Frontmatter and Template blocks untouched."], "exit_code": 0, "duration_ms": 970.4}} {"v": 1, "ts": "2026-09-15T20:23:49.966805+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3839739, "seq": 1, "source": "claude-code", "event": "prompt.submitted", "attrs": {"harness_event": "UserPromptSubmit", "prompt_length": 41, "prompt_sha256": "08a258dc7245e17391c89d8c434d03e57ef1211886559173a18957e3d29e7f66", "prompt": "Can you access Torben/chemenu @gitea-mcp?"}} {"v": 1, "ts": "2026-09-15T20:26:52.076905+00:00", "session_id": "671c1b9a-92dd-484b-b29a-bf6d29c006ff", "pid": 3840230, "seq": 1, "source": "claude-code", "event": "prompt.submitted", "attrs": {"harness_event": "UserPromptSubmit", "prompt_length": 393, "prompt_sha256": "fcf32a5b6942cb94a800ac558ccaafdaa4fd39332e63870ef46075084ba210f4", "prompt": "Do a full analysis and runtime data collection of this upgrade run. Include stack specific tracing and if somehow possible, take the raw session transcript as well. Create an issue in the chemenu repo collecting this telemetry as verbatim as possible, rely on file attachments if possible. \nGoal is to use your analysis to validate the upgrade procedure on a dev instance of the chemenu stack."}} ``` ### Die elidierte 69-Pfad-Liste Identisch in `gate.refused`, `gate.cleared` und dem ersten `publish.commit` - das ist der Commit `dcc17df`: ``` .wikitool-release.json AGENTS.md ENVIRONMENT.md.template README.md SOUL.md.template USER.md.template VERSION docs/language-boundaries.md docs/ownership-and-templates.md docs/version-model.md instructions/CONTRACT.md instructions/gates.md instructions/migrations/6.0.0-type-guidance-split.md instructions/session-setup.md instructions/setup-instance.md instructions/wiki-ingest/SKILL.md instructions/wiki-lint/SKILL.md instructions/wiki-manage/SKILL.md instructions/wiki-query/SKILL.md instructions/wiki-status/SKILL.md kb/CONVENTIONS.md.template kb/concepts/COLLECTION.md.template kb/sources/COLLECTION.md.template tools/CONTRACT.md tools/README.md tools/chemenu/api.py tools/chemenu/commands/dist_cmd.py tools/chemenu/commands/docs_verify.py tools/chemenu/commands/git_publish.py tools/chemenu/commands/instructions_cmd.py tools/chemenu/commands/run_budget.py tools/chemenu/commands/search.py tools/chemenu/commands/types_cmd.py tools/chemenu/commands/version_cmd.py tools/chemenu/mcp/server.py tools/chemenu/search/service.py tools/chemenu/search/types.py tools/chemenu/tests/test_api.py tools/chemenu/tests/test_dist_cmd.py tools/chemenu/tests/test_dist_upgrade.py tools/chemenu/tests/test_docs_verify.py tools/chemenu/tests/test_git_publish.py tools/chemenu/tests/test_instructions_cmd.py tools/chemenu/tests/test_mcp_server.py tools/chemenu/tests/test_run_budget.py tools/chemenu/tests/test_search.py tools/chemenu/tests/test_toc.py tools/chemenu/tests/test_type_resolver.py tools/chemenu/tests/test_types_cmd.py tools/chemenu/tests/test_version_cmd.py tools/chemenu/toc.py tools/chemenu/type_resolver.py tools/chemenu/types_core.py tools/chemenu/version.py types/comparison.guidance.md types/comparison.md.template types/concept.guidance.md types/concept.md types/concept.md.template types/entity.guidance.md types/entity.md.template types/lint-report.md types/source.guidance.md types/source.md types/source.md.template types/type-guidance.md types/type-guidance.schema.yaml types/type-spec.md types/type-spec.schema.yaml ``` ### Abgeleitete Kennzahlen Event-Histogramm ueber die 63 Zeilen: ``` 33 wikitool.call 21 session.start 5 prompt.submitted 2 publish.commit 1 gate.refused 1 gate.cleared ``` Laufzeiten, soweit auffaellig: `docs verify` kalt 1644.6 ms, danach 403-415 ms (dreimal gemessen). `publish --confirm` 1181.8 ms inklusive Push, der zweite Publish 970.4 ms. Alles andere unter 300 ms. `budget.state` taucht in der ganzen Trace **nicht** auf, obwohl das Event im `completeness`-Feld jedes `session.start` als meldbar gefuehrt wird - passt zu Befund 1, Folge 2: ein Zaehler, der nie in die Naehe seiner Schwelle kommt, hat auch nichts zu melden.
torben changed title from Upgrade-Lauf 5.0.0 -> 6.0.0 auf ausgelieferter Instanz: Laufbericht, Telemetrie, vier Befunde to Upgrade-Lauf 5.0.0 -> 6.0.0 auf ausgelieferter Instanz: Laufbericht, Telemetrie, sieben Befunde 2026-09-16 11:57:15 +00:00
Author
Owner

Changelog: Review-Sitzung vom 2026-09-16 gegen Transkript, die drei Ergebnis-Commits und den Endzustand der Instanz. Neu: Befund 5 (Rest-Abschnitt ## Authoring guidance in types/source.md, doppelter Kopf in types 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 verify nie gelaufen, Session nie neu gestartet, drei konkurrierende Reihenfolgen). Befund 1 hat einen Ursachenabschnitt bekommen: instructions/session-setup.md schreibt export ... 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 keine types/*.md.template gibt.

Korrigiert: die Zeile unter "Was der Lauf bestaetigt hat", types describe komponiere unveraendert - das gilt fuer drei der vier Typen, nicht fuer source. Akzeptanzkriterien um vier Punkte erweitert, Reproduktionsabschnitt um Schritt 6 (Diff-Gegentest). Befund 7 ist als Bauauftrag nach #108 ausgelagert. Titel und size/ nachgezogen: vier -> sieben Befunde, size/M -> size/L, weil daraus jetzt mehrere Arbeitspakete werden statt eines.

**Changelog:** Review-Sitzung vom 2026-09-16 gegen Transkript, die drei Ergebnis-Commits und den Endzustand der Instanz. Neu: Befund 5 (Rest-Abschnitt `## Authoring guidance` in `types/source.md`, doppelter Kopf in `types 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 verify` nie gelaufen, Session nie neu gestartet, drei konkurrierende Reihenfolgen). Befund 1 hat einen Ursachenabschnitt bekommen: `instructions/session-setup.md` schreibt `export ... ` 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 keine `types/*.md.template` gibt. Korrigiert: die Zeile unter "Was der Lauf bestaetigt hat", `types describe` komponiere unveraendert - das gilt fuer drei der vier Typen, nicht fuer `source`. Akzeptanzkriterien um vier Punkte erweitert, Reproduktionsabschnitt um Schritt 6 (Diff-Gegentest). Befund 7 ist als Bauauftrag nach #108 ausgelagert. Titel und `size/` nachgezogen: vier -> sieben Befunde, `size/M` -> `size/L`, weil daraus jetzt mehrere Arbeitspakete werden statt eines.
torben added size/L and removed size/M labels 2026-09-16 11:57:39 +00:00
Author
Owner

Changelog: Befund 5 ist repariert (b5014d9 in torben/nathan) und das Kriterium abgehakt. Dabei eine Zahl in Befund 5 korrigiert: zwei ## Authoring guidance-Koepfe sind der Normalzustand - types describe setzt selbst einen und inlined darunter die Guidance-Datei mit ihrem eigenen gleichnamigen Abschnitt, bei allen vier Typen. source hatte 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.

**Changelog:** Befund 5 ist repariert (`b5014d9` in `torben/nathan`) und das Kriterium abgehakt. Dabei **eine Zahl in Befund 5 korrigiert**: zwei `## Authoring guidance`-Koepfe sind der Normalzustand - `types describe` setzt selbst einen und inlined darunter die Guidance-Datei mit ihrem eigenen gleichnamigen Abschnitt, bei allen vier Typen. `source` hatte 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.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: torben/chemenu#107