Inhaltsverzeichnisse werden erzeugt, nicht von Hand gepflegt. Statt zwoelf handgeschriebener TOC-Bloecke gibt es eine dritte generierte Region neben denen von xref und cite:
25 Dateien tragen jetzt eine TOC-Region, laengstes Verzeichnis 13 Eintraege.
Warum generiert statt geschrieben
Vom Operator eingewandt und uebernommen: ein handgepflegtes TOC ist genau die Driftquelle, vor der das urspruengliche Akzeptanzkriterium 2 warnte — und das Kernprinzip dieses Repos sagt "anything mechanical is done by tools/wikitool, never by hand". Erzeugt man es, sind Existenz und Konsistenz zugleich sichergestellt, ohne dass jemand eine Liste pflegt; die Region faellt unter Invariante 1 und wird nie von Hand angefasst.
Der Praezedenzfall stand schon im Repo: die bumps-Region in CHANGES.md (version.py:75-86) nutzt dieselbe Marker-Konvention aus blocks.py, ohne in blocks.BLOCKS zu stehen — jene Tupel-Konstante speist xref, cite und den unbalanced_markers-Lint ueber kb-Seiten, und keine der Zieldateien hier ist eine. toc folgt demselben Muster.
Damit ist auch die urspruengliche Offene Frage entschieden: ja, mechanisch geprueft — aber ohne den Einwand zu verletzen, der dagegen sprach. Eine Empfehlung wird nicht dadurch zur Vorschrift, dass ein Generator sie erfuellt; niemand muss etwas schreiben, was er nicht will, und docs verify prueft nur, dass die erzeugte Region aktuell ist.
Umfang: berechnet, nicht hartkodiert
toc.target_files() laeuft ueber die Kategorien, die AGENTS.md § File naming selbst als agentengeladenes Referenzmaterial fuehrt:
AGENTS.md
jeden Stage-Contract (raw/, kb/, types/type-spec.md, reports/, work/, tools/, instructions/)
kb/CONVENTIONS.md und jedes kb/<collection>/COLLECTION.md
jede flache instructions/**.md-Datei
Die Schwelle wird auf dem Body ohne TOC-Region gemessen, sodass das Einfuegen selbst nie eine Datei ueber 100 Zeilen schiebt.
Zwei bewusste Ausnahmen, beide begruendet:
Draussen
Grund
SKILL.md (3 Dateien)
Der Harness laedt sie ganz — sie sind Einstiegspunkt, nicht die partiell vorgelesene Zweit-Hop-Datei, um die es geht. instructions/CONTRACT.md § "When a skill carries a copy-in checklist" hat dort bereits eine Position: "A checklist read once is the table of contents it replaced."
Werden ueber wikitool types describe gelesen, das den Inhalt neu rendert statt die Datei roh auszugeben (types_cmd.py:50-90) — ein head -100 auf die Rohdatei ist dort nicht der Lesepfad. types/type-spec.md bleibt drin: es ist der Stage-Contract, nicht ein Einzelspec.
Die Zwoelf waren unvollstaendig
Die vom Akzeptanzkriterium geforderte Neumessung unmittelbar vor der Umsetzung hat den Befund vergroessert: die transitive Kettenmessung ab den fuenf Content-Skills ergab 27 erreichbare Dateien ueber 100 Zeilen, davon 19 Agentendateien; die strukturelle Messung nach der Datei-Namenstabelle ergab 25. Uebersehen hatte die urspruengliche Messung sieben flache Instruktionen (setup-instance.md, private-instance.md, claude-code-model-selection.md, migrate-corpus.md, german-terminology.md, evolve-subtypes.md, mcp-read-server.md) sowie capture-session.md, die beiden Migrationsdokumente und drei Dateien unter instructions/dev/.
instructions/dev/ ist mit drin, obwohl dist export es entfernt: strukturell sind das gewoehnliche flache Instruktionen (so sagt es instructions/CONTRACT.md ueber den orthogonalen dev/-Split), und issue-tracking.md ist mit 401 Zeilen die laengste Instruktion im Repo, gelesen in jeder Issue-Sitzung. Nicht ausgeliefert zu werden aendert die Lesemechanik nicht.
Template-Frage: beantwortet sich aus dem Code
Das urspruengliche Akzeptanzkriterium fragte, ob die .template-Variante mitgeaendert wird. Es gibt nichts zu entscheiden:
kb/concepts/COLLECTION.md hat keine separate .template. dist_cmd.py:388-399 benennt die Live-Datei beim Export um — ausdruecklich gegen die zweite Kopie, die Invariante 8 verbietet. Ein TOC dort wird automatisch mit ausgeliefert.
kb/CONVENTIONS.md.template existiert separat, hat aber 89 Zeilen und liegt damit unter der Schwelle. Es bekommt keine Region, und das ist konsistent: die Regel ist ein Zeilenschwellenwert.
Keine Doppelpflege in beiden Faellen.
Zwei Nebenfunde, mitbehoben
Beide waren latente Schwaechen, die erst der generierte Inhalt ausgeloest hat — vor dem Bump behoben, mit je einem Regressionstest:
docs_verify.ISSUE_REFERENCE_RE (#\d+) hielt nummerierte-Schritt-Anker fuer Issue-Zitate: [2. Fix the fidelity](#2-fix-the-fidelity-before-writing-a-word) in capture-session.md las sich als Zitat von #2. Der Kommentar ueber der Regex behauptete "Markdown anchors are word characters, so a link never matches" — richtig, solange kein Anker mit einer Ziffer beginnt. Behoben durch einen Lookbehind, der genau die ](#...-Linkfragment-Form ausschliesst; ein echtes (#66) wird weiterhin gefunden.
instructions_cmd.dev_only_forbidden_references prueft mit blankem name in text. Der Anker #where-stack-development-happens (aus private-instance.mds eigener Ueberschrift) enthaelt stack-dev als reine Teilzeichenkette und meldete eine Grenzverletzung, die es nicht gab. Behoben durch wortgrenzengebundene Regex-Suche — \b greift nicht zwischen "v" und "e", also faellt "stack-development" heraus, waehrend eine echte Nennung weiter faellt.
Akzeptanzkriterien
Jede betroffene Datei traegt einen Inhaltsverzeichnis-Block vor der ersten inhaltlichen Ueberschrift — 25 Dateien, plus die drei begruendeten Ausnahmekategorien oben. (Umformuliert von "jede der zwoelf": die Neumessung ergab 25.)
Kein TOC listet einen Abschnitt, den die Datei nicht hat, und keiner laesst einen ##-Abschnitt aus. Konstruktiv sichergestellt statt geprueft: die Region wird aus den Ueberschriften erzeugt, docs verify faellt auf jede Abweichung.
Fuer kb/CONVENTIONS.md und kb/concepts/COLLECTION.md ist entschieden, ob die .template-Variante mitgeaendert wird — siehe oben, in beiden Faellen ohne Doppelpflege.
Die Zeilenzahlen sind unmittelbar vor der Umsetzung erneut gemessen. Sie waren erneut verfallen (kb/CONTRACT.md 311→312, instructions/CONTRACT.md 276→304, raw/CONTRACT.md 196→198) — und die Messung hat den Umfang von zwoelf auf 25 korrigiert.
tools/wikitool docs verify und tools/wikitool instructions verify laufen ohne neue Findings.
Die Versionsteil-Frage ist nach instructions/dev/version-parts.md beantwortet. Nicht --patch wie erwartet, sondern --major — siehe unten.
Versionsteil: --major, nicht --patch
Die Erwartung im urspruenglichen Issue ("reine Ergaenzung ohne Interface-Aenderung") hielt dem Drop-in-Test nicht stand. check_toc_regions ist eine neue Pflichtpruefung ueber bestehenden Inhalt: eine Instanz mit einer eigenen instructions/*.md-Datei ueber 100 Zeilen sieht docs verify nach reinem Tool-Update neu fehlschlagen, ohne dass sie irgendetwas geaendert haette. Das ist derselbe Bruchtyp wie der Katalogeintrag "ein Type-Spec-Pflichtfeld aendert sich → bestehende Seiten validieren nicht mehr", und version-parts.md Schritt 1 ist woertlich streng: "Any step beyond the copy, however small, fails this half."
Dem Operator nach Schritt 4 vorgelegt (was bricht, was eine Instanz tun muss, Alternativen) und freigegeben: --major mit --no-migration — kein kb/-Inhalt betroffen, der volle Reparaturweg ist ein einmaliges wikitool docs toc --apply.
Verifikation
tools/wikitool docs verify, tools/wikitool instructions verify und pytest (1101 Tests, davon 15 neue in test_toc.py plus vier Regressionstests fuer die beiden Nebenfunde) — gruen, zusaetzlich im gehaerteten Leerumgebungs-Lauf nach testing-conventions.md Schritt 6 mit identischem Ergebnis.
Nachgezogen in 53e3527, weil docs verify die eigene Dokumentationstreue nur fuer die Existenz einer Kommandozeile prueft, nicht fuer deren Inhalt: docs toc fehlte in der Fehlerkontrakt-Tabelle, die docs verify-Zeile nannte die neue Pruefung nicht, und tools/README.md § Adding a command Schritt 5 nannte ein --major-Kriterium, das version-parts.md verneint.
Herkunft
Analyse aus #65 (Fund 5), Sitzung 2026-09-09. Primaerquelle im Volltext geprueft, Zeilenzahlen per wc -l gemessen. #65 nannte drei Dateien, die erste Kettenmessung zwoelf, die Messung vor der Umsetzung 25. Wartete auf #77 (a51d7a3), da instructions/kb-profiles.md und instructions/CONTRACT.md von beiden Paketen angefasst wurden.
## Ergebnis
Inhaltsverzeichnisse werden **erzeugt, nicht von Hand gepflegt**. Statt zwoelf handgeschriebener TOC-Bloecke gibt es eine dritte generierte Region neben denen von `xref` und `cite`:
```
<!-- wikitool:toc -->
## Contents
- [Abschnitt](#abschnitt)
- [Unterabschnitt](#unterabschnitt)
<!-- /wikitool:toc -->
```
`tools/chemenu/toc.py` rechnet sie, `wikitool docs toc [--apply]` schreibt sie, `docs verify` prueft sie. Geliefert in `2c4c2b1` / `53e3527`, Stackversion `5.0.0-beta.2`.
**25 Dateien** tragen jetzt eine TOC-Region, laengstes Verzeichnis 13 Eintraege.
## Warum generiert statt geschrieben
Vom Operator eingewandt und uebernommen: ein handgepflegtes TOC ist genau die Driftquelle, vor der das urspruengliche Akzeptanzkriterium 2 warnte — und das Kernprinzip dieses Repos sagt "anything mechanical is done by `tools/wikitool`, never by hand". Erzeugt man es, sind Existenz *und* Konsistenz zugleich sichergestellt, ohne dass jemand eine Liste pflegt; die Region faellt unter Invariante 1 und wird nie von Hand angefasst.
Der Praezedenzfall stand schon im Repo: die `bumps`-Region in `CHANGES.md` (`version.py:75-86`) nutzt dieselbe Marker-Konvention aus `blocks.py`, ohne in `blocks.BLOCKS` zu stehen — jene Tupel-Konstante speist `xref`, `cite` und den `unbalanced_markers`-Lint ueber *kb-Seiten*, und keine der Zieldateien hier ist eine. `toc` folgt demselben Muster.
Damit ist auch die urspruengliche **Offene Frage** entschieden: ja, mechanisch geprueft — aber ohne den Einwand zu verletzen, der dagegen sprach. Eine Empfehlung wird nicht dadurch zur Vorschrift, dass ein Generator sie erfuellt; niemand muss etwas schreiben, was er nicht will, und `docs verify` prueft nur, dass die erzeugte Region aktuell ist.
## Umfang: berechnet, nicht hartkodiert
`toc.target_files()` laeuft ueber die Kategorien, die AGENTS.md § File naming selbst als agentengeladenes Referenzmaterial fuehrt:
- `AGENTS.md`
- jeden Stage-Contract (`raw/`, `kb/`, `types/type-spec.md`, `reports/`, `work/`, `tools/`, `instructions/`)
- `kb/CONVENTIONS.md` und jedes `kb/<collection>/COLLECTION.md`
- jede flache `instructions/**.md`-Datei
Die Schwelle wird auf dem Body **ohne** TOC-Region gemessen, sodass das Einfuegen selbst nie eine Datei ueber 100 Zeilen schiebt.
Zwei bewusste Ausnahmen, beide begruendet:
| Draussen | Grund |
|---|---|
| `SKILL.md` (3 Dateien) | Der Harness laedt sie ganz — sie sind Einstiegspunkt, nicht die partiell vorgelesene Zweit-Hop-Datei, um die es geht. `instructions/CONTRACT.md` § "When a skill carries a copy-in checklist" hat dort bereits eine Position: "A checklist read once is the table of contents it replaced." |
| Menschendoku (`README.md`, `CHANGES.md`, `EVALS.md`, `INSTALL.md`, `tools/README.md`), `docs/` | Laut Datei-Namenstabelle nie von einem Agenten als Instruktion geladen. Die Vorschau-Mechanik, gegen die ein TOC wirkt, greift dort nicht. |
| `types/<name>.md`-Einzelspecs (`source.md`, `concept.md`) | Werden ueber `wikitool types describe` gelesen, das den Inhalt **neu rendert** statt die Datei roh auszugeben (`types_cmd.py:50-90`) — ein `head -100` auf die Rohdatei ist dort nicht der Lesepfad. `types/type-spec.md` bleibt drin: es ist der Stage-Contract, nicht ein Einzelspec. |
## Die Zwoelf waren unvollstaendig
Die vom Akzeptanzkriterium geforderte Neumessung unmittelbar vor der Umsetzung hat den Befund **vergroessert**: die transitive Kettenmessung ab den fuenf Content-Skills ergab 27 erreichbare Dateien ueber 100 Zeilen, davon 19 Agentendateien; die strukturelle Messung nach der Datei-Namenstabelle ergab 25. Uebersehen hatte die urspruengliche Messung sieben flache Instruktionen (`setup-instance.md`, `private-instance.md`, `claude-code-model-selection.md`, `migrate-corpus.md`, `german-terminology.md`, `evolve-subtypes.md`, `mcp-read-server.md`) sowie `capture-session.md`, die beiden Migrationsdokumente und drei Dateien unter `instructions/dev/`.
`instructions/dev/` ist mit drin, obwohl `dist export` es entfernt: strukturell sind das gewoehnliche flache Instruktionen (so sagt es `instructions/CONTRACT.md` ueber den orthogonalen `dev/`-Split), und `issue-tracking.md` ist mit 401 Zeilen die laengste Instruktion im Repo, gelesen in jeder Issue-Sitzung. Nicht ausgeliefert zu werden aendert die Lesemechanik nicht.
## Template-Frage: beantwortet sich aus dem Code
Das urspruengliche Akzeptanzkriterium fragte, ob die `.template`-Variante mitgeaendert wird. Es gibt nichts zu entscheiden:
- **`kb/concepts/COLLECTION.md`** hat keine separate `.template`. `dist_cmd.py:388-399` benennt die Live-Datei beim Export um — ausdruecklich gegen die zweite Kopie, die Invariante 8 verbietet. Ein TOC dort wird automatisch mit ausgeliefert.
- **`kb/CONVENTIONS.md.template`** existiert separat, hat aber 89 Zeilen und liegt damit unter der Schwelle. Es bekommt keine Region, und das ist konsistent: die Regel ist ein Zeilenschwellenwert.
Keine Doppelpflege in beiden Faellen.
## Zwei Nebenfunde, mitbehoben
Beide waren latente Schwaechen, die erst der generierte Inhalt ausgeloest hat — vor dem Bump behoben, mit je einem Regressionstest:
1. **`docs_verify.ISSUE_REFERENCE_RE`** (`#\d+`) hielt nummerierte-Schritt-Anker fuer Issue-Zitate: `[2. Fix the fidelity](#2-fix-the-fidelity-before-writing-a-word)` in `capture-session.md` las sich als Zitat von `#2`. Der Kommentar ueber der Regex behauptete "Markdown anchors are word characters, so a link never matches" — richtig, solange kein Anker mit einer Ziffer beginnt. Behoben durch einen Lookbehind, der genau die `](#...`-Linkfragment-Form ausschliesst; ein echtes `(#66)` wird weiterhin gefunden.
2. **`instructions_cmd.dev_only_forbidden_references`** prueft mit blankem `name in text`. Der Anker `#where-stack-development-happens` (aus `private-instance.md`s eigener Ueberschrift) enthaelt `stack-dev` als reine Teilzeichenkette und meldete eine Grenzverletzung, die es nicht gab. Behoben durch wortgrenzengebundene Regex-Suche — `\b` greift nicht zwischen "v" und "e", also faellt "stack-development" heraus, waehrend eine echte Nennung weiter faellt.
## Akzeptanzkriterien
- [x] Jede betroffene Datei traegt einen Inhaltsverzeichnis-Block vor der ersten inhaltlichen Ueberschrift — 25 Dateien, plus die drei begruendeten Ausnahmekategorien oben. *(Umformuliert von "jede der zwoelf": die Neumessung ergab 25.)*
- [x] Kein TOC listet einen Abschnitt, den die Datei nicht hat, und keiner laesst einen `##`-Abschnitt aus. **Konstruktiv sichergestellt** statt geprueft: die Region wird aus den Ueberschriften erzeugt, `docs verify` faellt auf jede Abweichung.
- [x] Fuer `kb/CONVENTIONS.md` und `kb/concepts/COLLECTION.md` ist entschieden, ob die `.template`-Variante mitgeaendert wird — siehe oben, in beiden Faellen ohne Doppelpflege.
- [x] Die Zeilenzahlen sind unmittelbar vor der Umsetzung erneut gemessen. Sie waren erneut verfallen (`kb/CONTRACT.md` 311→312, `instructions/CONTRACT.md` 276→304, `raw/CONTRACT.md` 196→198) — und die Messung hat den Umfang von zwoelf auf 25 korrigiert.
- [x] `tools/wikitool docs verify` und `tools/wikitool instructions verify` laufen ohne neue Findings.
- [x] Die Versionsteil-Frage ist nach `instructions/dev/version-parts.md` beantwortet. **Nicht `--patch` wie erwartet, sondern `--major`** — siehe unten.
## Versionsteil: `--major`, nicht `--patch`
Die Erwartung im urspruenglichen Issue ("reine Ergaenzung ohne Interface-Aenderung") hielt dem Drop-in-Test nicht stand. `check_toc_regions` ist eine **neue Pflichtpruefung ueber bestehenden Inhalt**: eine Instanz mit einer eigenen `instructions/*.md`-Datei ueber 100 Zeilen sieht `docs verify` nach reinem Tool-Update neu fehlschlagen, ohne dass sie irgendetwas geaendert haette. Das ist derselbe Bruchtyp wie der Katalogeintrag "ein Type-Spec-Pflichtfeld aendert sich → bestehende Seiten validieren nicht mehr", und `version-parts.md` Schritt 1 ist woertlich streng: "Any step beyond the copy, however small, fails this half."
Dem Operator nach Schritt 4 vorgelegt (was bricht, was eine Instanz tun muss, Alternativen) und freigegeben: `--major` mit `--no-migration` — kein `kb/`-Inhalt betroffen, der volle Reparaturweg ist ein einmaliges `wikitool docs toc --apply`.
## Verifikation
`tools/wikitool docs verify`, `tools/wikitool instructions verify` und `pytest` (1101 Tests, davon 15 neue in `test_toc.py` plus vier Regressionstests fuer die beiden Nebenfunde) — gruen, zusaetzlich im gehaerteten Leerumgebungs-Lauf nach `testing-conventions.md` Schritt 6 mit identischem Ergebnis.
Nachgezogen in `53e3527`, weil `docs verify` die eigene Dokumentationstreue nur fuer die *Existenz* einer Kommandozeile prueft, nicht fuer deren Inhalt: `docs toc` fehlte in der Fehlerkontrakt-Tabelle, die `docs verify`-Zeile nannte die neue Pruefung nicht, und `tools/README.md` § Adding a command Schritt 5 nannte ein `--major`-Kriterium, das `version-parts.md` verneint.
## Herkunft
Analyse aus #65 (Fund 5), Sitzung 2026-09-09. Primaerquelle im Volltext geprueft, Zeilenzahlen per `wc -l` gemessen. #65 nannte drei Dateien, die erste Kettenmessung zwoelf, die Messung vor der Umsetzung 25. Wartete auf #77 (`a51d7a3`), da `instructions/kb-profiles.md` und `instructions/CONTRACT.md` von beiden Paketen angefasst wurden.
Changelog: Nach 663b1c0 (#71/#72/#79) nachgezogen. Zeilenzahl instructions/CONTRACT.md 187 → 276, Tabelle neu sortiert. § Reihenfolge: die Blockade durch #71/#72/#79 ist weg, nur #77 bleibt - und ist um instructions/CONTRACT.md gewachsen, das seit 663b1c0 selbst einen Gitea-Verweis traegt. Neu in § "Warum das zaehlt": der Beleg aus codex-skill-creator/SKILL.md:221-222, der TOC und Referenztiefe als zwei Bullets derselben Liste fuehrt - das TOC ist dort die Minderungsmassnahme fuer dieselbe Mechanik, was dieses Issue nach der #72-Entscheidung aufwertet. Ein Akzeptanzkriterium ergaenzt: Zeilenzahlen unmittelbar vor der Umsetzung neu messen.
**Changelog:** Nach `663b1c0` (#71/#72/#79) nachgezogen. Zeilenzahl `instructions/CONTRACT.md` 187 → 276, Tabelle neu sortiert. § Reihenfolge: die Blockade durch #71/#72/#79 ist weg, nur #77 bleibt - und ist um `instructions/CONTRACT.md` gewachsen, das seit `663b1c0` selbst einen Gitea-Verweis traegt. Neu in § "Warum das zaehlt": der Beleg aus `codex-skill-creator/SKILL.md:221-222`, der TOC und Referenztiefe als zwei Bullets derselben Liste fuehrt - das TOC ist dort die Minderungsmassnahme fuer dieselbe Mechanik, was dieses Issue nach der #72-Entscheidung aufwertet. Ein Akzeptanzkriterium ergaenzt: Zeilenzahlen unmittelbar vor der Umsetzung neu messen.
torben
changed title from Zwoelf Referenzdateien ueber 100 Zeilen haben kein Inhaltsverzeichnis to Referenzdateien ueber 100 Zeilen brauchen ein Inhaltsverzeichnis - generiert, nicht handgepflegt2026-09-09 18:44:33 +00:00
Changelog: Body auf den Endstand umgeschrieben, Titel korrigiert ("Zwoelf" stimmte nicht mehr). Gegen den Stand vom 2026-09-09 14:33 haben sich vier Dinge geaendert: der Umfang von zwoelf auf 25 Dateien (die geforderte Neumessung vor der Umsetzung hat den Befund vergroessert, nicht nur aktualisiert); der Ansatz von handgeschrieben auf generiert (Einwand des Operators — toc.py plus docs toc, dieselbe Marker-Konvention wie xref/cite), womit die Offene Frage nach der mechanischen Pruefbarkeit ohne den Einwand entschieden ist, der dagegen sprach; der Versionsteil von der Erwartung --patch auf --major --no-migration, nach Vorlage gemaess version-parts.md Schritt 4; und die Template-Frage, die sich aus dist_cmd.py selbst beantwortet, statt entschieden werden zu muessen. Neu dokumentiert: zwei latente Pruefungs-Schwaechen (ISSUE_REFERENCE_RE, dev_only_forbidden_references), die erst der generierte Inhalt ausgeloest hat, beide mit Regressionstest behoben.
**Changelog:** Body auf den Endstand umgeschrieben, Titel korrigiert ("Zwoelf" stimmte nicht mehr). Gegen den Stand vom 2026-09-09 14:33 haben sich vier Dinge geaendert: der Umfang von zwoelf auf **25** Dateien (die geforderte Neumessung vor der Umsetzung hat den Befund vergroessert, nicht nur aktualisiert); der Ansatz von handgeschrieben auf **generiert** (Einwand des Operators — `toc.py` plus `docs toc`, dieselbe Marker-Konvention wie `xref`/`cite`), womit die Offene Frage nach der mechanischen Pruefbarkeit ohne den Einwand entschieden ist, der dagegen sprach; der Versionsteil von der Erwartung `--patch` auf **`--major --no-migration`**, nach Vorlage gemaess `version-parts.md` Schritt 4; und die Template-Frage, die sich aus `dist_cmd.py` selbst beantwortet, statt entschieden werden zu muessen. Neu dokumentiert: zwei latente Pruefungs-Schwaechen (`ISSUE_REFERENCE_RE`, `dev_only_forbidden_references`), die erst der generierte Inhalt ausgeloest hat, beide mit Regressionstest behoben.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Ergebnis
Inhaltsverzeichnisse werden erzeugt, nicht von Hand gepflegt. Statt zwoelf handgeschriebener TOC-Bloecke gibt es eine dritte generierte Region neben denen von
xrefundcite:tools/chemenu/toc.pyrechnet sie,wikitool docs toc [--apply]schreibt sie,docs verifyprueft sie. Geliefert in2c4c2b1/53e3527, Stackversion5.0.0-beta.2.25 Dateien tragen jetzt eine TOC-Region, laengstes Verzeichnis 13 Eintraege.
Warum generiert statt geschrieben
Vom Operator eingewandt und uebernommen: ein handgepflegtes TOC ist genau die Driftquelle, vor der das urspruengliche Akzeptanzkriterium 2 warnte — und das Kernprinzip dieses Repos sagt "anything mechanical is done by
tools/wikitool, never by hand". Erzeugt man es, sind Existenz und Konsistenz zugleich sichergestellt, ohne dass jemand eine Liste pflegt; die Region faellt unter Invariante 1 und wird nie von Hand angefasst.Der Praezedenzfall stand schon im Repo: die
bumps-Region inCHANGES.md(version.py:75-86) nutzt dieselbe Marker-Konvention ausblocks.py, ohne inblocks.BLOCKSzu stehen — jene Tupel-Konstante speistxref,citeund denunbalanced_markers-Lint ueber kb-Seiten, und keine der Zieldateien hier ist eine.tocfolgt demselben Muster.Damit ist auch die urspruengliche Offene Frage entschieden: ja, mechanisch geprueft — aber ohne den Einwand zu verletzen, der dagegen sprach. Eine Empfehlung wird nicht dadurch zur Vorschrift, dass ein Generator sie erfuellt; niemand muss etwas schreiben, was er nicht will, und
docs verifyprueft nur, dass die erzeugte Region aktuell ist.Umfang: berechnet, nicht hartkodiert
toc.target_files()laeuft ueber die Kategorien, die AGENTS.md § File naming selbst als agentengeladenes Referenzmaterial fuehrt:AGENTS.mdraw/,kb/,types/type-spec.md,reports/,work/,tools/,instructions/)kb/CONVENTIONS.mdund jedeskb/<collection>/COLLECTION.mdinstructions/**.md-DateiDie Schwelle wird auf dem Body ohne TOC-Region gemessen, sodass das Einfuegen selbst nie eine Datei ueber 100 Zeilen schiebt.
Zwei bewusste Ausnahmen, beide begruendet:
SKILL.md(3 Dateien)instructions/CONTRACT.md§ "When a skill carries a copy-in checklist" hat dort bereits eine Position: "A checklist read once is the table of contents it replaced."README.md,CHANGES.md,EVALS.md,INSTALL.md,tools/README.md),docs/types/<name>.md-Einzelspecs (source.md,concept.md)wikitool types describegelesen, das den Inhalt neu rendert statt die Datei roh auszugeben (types_cmd.py:50-90) — einhead -100auf die Rohdatei ist dort nicht der Lesepfad.types/type-spec.mdbleibt drin: es ist der Stage-Contract, nicht ein Einzelspec.Die Zwoelf waren unvollstaendig
Die vom Akzeptanzkriterium geforderte Neumessung unmittelbar vor der Umsetzung hat den Befund vergroessert: die transitive Kettenmessung ab den fuenf Content-Skills ergab 27 erreichbare Dateien ueber 100 Zeilen, davon 19 Agentendateien; die strukturelle Messung nach der Datei-Namenstabelle ergab 25. Uebersehen hatte die urspruengliche Messung sieben flache Instruktionen (
setup-instance.md,private-instance.md,claude-code-model-selection.md,migrate-corpus.md,german-terminology.md,evolve-subtypes.md,mcp-read-server.md) sowiecapture-session.md, die beiden Migrationsdokumente und drei Dateien unterinstructions/dev/.instructions/dev/ist mit drin, obwohldist exportes entfernt: strukturell sind das gewoehnliche flache Instruktionen (so sagt esinstructions/CONTRACT.mdueber den orthogonalendev/-Split), undissue-tracking.mdist mit 401 Zeilen die laengste Instruktion im Repo, gelesen in jeder Issue-Sitzung. Nicht ausgeliefert zu werden aendert die Lesemechanik nicht.Template-Frage: beantwortet sich aus dem Code
Das urspruengliche Akzeptanzkriterium fragte, ob die
.template-Variante mitgeaendert wird. Es gibt nichts zu entscheiden:kb/concepts/COLLECTION.mdhat keine separate.template.dist_cmd.py:388-399benennt die Live-Datei beim Export um — ausdruecklich gegen die zweite Kopie, die Invariante 8 verbietet. Ein TOC dort wird automatisch mit ausgeliefert.kb/CONVENTIONS.md.templateexistiert separat, hat aber 89 Zeilen und liegt damit unter der Schwelle. Es bekommt keine Region, und das ist konsistent: die Regel ist ein Zeilenschwellenwert.Keine Doppelpflege in beiden Faellen.
Zwei Nebenfunde, mitbehoben
Beide waren latente Schwaechen, die erst der generierte Inhalt ausgeloest hat — vor dem Bump behoben, mit je einem Regressionstest:
docs_verify.ISSUE_REFERENCE_RE(#\d+) hielt nummerierte-Schritt-Anker fuer Issue-Zitate:[2. Fix the fidelity](#2-fix-the-fidelity-before-writing-a-word)incapture-session.mdlas sich als Zitat von#2. Der Kommentar ueber der Regex behauptete "Markdown anchors are word characters, so a link never matches" — richtig, solange kein Anker mit einer Ziffer beginnt. Behoben durch einen Lookbehind, der genau die](#...-Linkfragment-Form ausschliesst; ein echtes(#66)wird weiterhin gefunden.instructions_cmd.dev_only_forbidden_referencesprueft mit blankemname in text. Der Anker#where-stack-development-happens(ausprivate-instance.mds eigener Ueberschrift) enthaeltstack-devals reine Teilzeichenkette und meldete eine Grenzverletzung, die es nicht gab. Behoben durch wortgrenzengebundene Regex-Suche —\bgreift nicht zwischen "v" und "e", also faellt "stack-development" heraus, waehrend eine echte Nennung weiter faellt.Akzeptanzkriterien
##-Abschnitt aus. Konstruktiv sichergestellt statt geprueft: die Region wird aus den Ueberschriften erzeugt,docs verifyfaellt auf jede Abweichung.kb/CONVENTIONS.mdundkb/concepts/COLLECTION.mdist entschieden, ob die.template-Variante mitgeaendert wird — siehe oben, in beiden Faellen ohne Doppelpflege.kb/CONTRACT.md311→312,instructions/CONTRACT.md276→304,raw/CONTRACT.md196→198) — und die Messung hat den Umfang von zwoelf auf 25 korrigiert.tools/wikitool docs verifyundtools/wikitool instructions verifylaufen ohne neue Findings.instructions/dev/version-parts.mdbeantwortet. Nicht--patchwie erwartet, sondern--major— siehe unten.Versionsteil:
--major, nicht--patchDie Erwartung im urspruenglichen Issue ("reine Ergaenzung ohne Interface-Aenderung") hielt dem Drop-in-Test nicht stand.
check_toc_regionsist eine neue Pflichtpruefung ueber bestehenden Inhalt: eine Instanz mit einer eigeneninstructions/*.md-Datei ueber 100 Zeilen siehtdocs verifynach reinem Tool-Update neu fehlschlagen, ohne dass sie irgendetwas geaendert haette. Das ist derselbe Bruchtyp wie der Katalogeintrag "ein Type-Spec-Pflichtfeld aendert sich → bestehende Seiten validieren nicht mehr", undversion-parts.mdSchritt 1 ist woertlich streng: "Any step beyond the copy, however small, fails this half."Dem Operator nach Schritt 4 vorgelegt (was bricht, was eine Instanz tun muss, Alternativen) und freigegeben:
--majormit--no-migration— keinkb/-Inhalt betroffen, der volle Reparaturweg ist ein einmaligeswikitool docs toc --apply.Verifikation
tools/wikitool docs verify,tools/wikitool instructions verifyundpytest(1101 Tests, davon 15 neue intest_toc.pyplus vier Regressionstests fuer die beiden Nebenfunde) — gruen, zusaetzlich im gehaerteten Leerumgebungs-Lauf nachtesting-conventions.mdSchritt 6 mit identischem Ergebnis.Nachgezogen in
53e3527, weildocs verifydie eigene Dokumentationstreue nur fuer die Existenz einer Kommandozeile prueft, nicht fuer deren Inhalt:docs tocfehlte in der Fehlerkontrakt-Tabelle, diedocs verify-Zeile nannte die neue Pruefung nicht, undtools/README.md§ Adding a command Schritt 5 nannte ein--major-Kriterium, dasversion-parts.mdverneint.Herkunft
Analyse aus #65 (Fund 5), Sitzung 2026-09-09. Primaerquelle im Volltext geprueft, Zeilenzahlen per
wc -lgemessen. #65 nannte drei Dateien, die erste Kettenmessung zwoelf, die Messung vor der Umsetzung 25. Wartete auf #77 (a51d7a3), dainstructions/kb-profiles.mdundinstructions/CONTRACT.mdvon beiden Paketen angefasst wurden.Changelog: Nach
663b1c0(#71/#72/#79) nachgezogen. Zeilenzahlinstructions/CONTRACT.md187 → 276, Tabelle neu sortiert. § Reihenfolge: die Blockade durch #71/#72/#79 ist weg, nur #77 bleibt - und ist uminstructions/CONTRACT.mdgewachsen, das seit663b1c0selbst einen Gitea-Verweis traegt. Neu in § "Warum das zaehlt": der Beleg auscodex-skill-creator/SKILL.md:221-222, der TOC und Referenztiefe als zwei Bullets derselben Liste fuehrt - das TOC ist dort die Minderungsmassnahme fuer dieselbe Mechanik, was dieses Issue nach der #72-Entscheidung aufwertet. Ein Akzeptanzkriterium ergaenzt: Zeilenzahlen unmittelbar vor der Umsetzung neu messen.Zwoelf Referenzdateien ueber 100 Zeilen haben kein Inhaltsverzeichnisto Referenzdateien ueber 100 Zeilen brauchen ein Inhaltsverzeichnis - generiert, nicht handgepflegtChangelog: Body auf den Endstand umgeschrieben, Titel korrigiert ("Zwoelf" stimmte nicht mehr). Gegen den Stand vom 2026-09-09 14:33 haben sich vier Dinge geaendert: der Umfang von zwoelf auf 25 Dateien (die geforderte Neumessung vor der Umsetzung hat den Befund vergroessert, nicht nur aktualisiert); der Ansatz von handgeschrieben auf generiert (Einwand des Operators —
toc.pyplusdocs toc, dieselbe Marker-Konvention wiexref/cite), womit die Offene Frage nach der mechanischen Pruefbarkeit ohne den Einwand entschieden ist, der dagegen sprach; der Versionsteil von der Erwartung--patchauf--major --no-migration, nach Vorlage gemaessversion-parts.mdSchritt 4; und die Template-Frage, die sich ausdist_cmd.pyselbst beantwortet, statt entschieden werden zu muessen. Neu dokumentiert: zwei latente Pruefungs-Schwaechen (ISSUE_REFERENCE_RE,dev_only_forbidden_references), die erst der generierte Inhalt ausgeloest hat, beide mit Regressionstest behoben.torben referenced this issue2026-09-30 04:48:11 +00:00