instructions sync kopiert Skills in eine andere Verzeichnistiefe: 52 von 58 relativen Links brechen #98

Closed
opened 2026-09-12 16:42:11 +00:00 by torben · 5 comments
Owner

tools/wikitool instructions sync kopierte jede SKILL.md unverändert (shutil.copytree) in ein Verzeichnis anderer Tiefe und ohne ihre Nachbarn. Jeder relative Link, der für den Quellort korrekt geschrieben war, zeigte in der publizierten Kopie ins Leere.

Gemessen am 2026-09-12, vor der Reparatur:

Baum relative Links lösten auf tot
instructions/**/SKILL.md (Quelle, 7 Dateien) 58 58 0
.claude/skills/**/SKILL.md (publiziert) 58 6 52

Keiner der 52 war ein Tippfehler — für jeden existierte die Zieldatei im Repo. Die sechs Überlebenden waren zwei Zufälle: Verweise auf ein anderes publiziertes Skill (../stack-dev/SKILL.md) und ../../../docs/model-and-effort-selection.md aus den Dev-Skills, die in Quelle und Ziel zufällig gleich tief lagen.

Zwei unabhängige Ursachen mit verschiedener Reparatur:

Fälle Beispiel Durch Tiefenkorrektur reparabel?
A 38 ../session-setup.md, ../gates.md, ../issue-tracking.md Neininstructions/ wurde gar nicht mitpubliziert, das Ziel fehlte unter .claude/skills/ in jeder Tiefe
B 14 ../../kb/CONTRACT.md, ../../raw/CONTRACT.md Ja — ein ../ zu wenig

In der ausgelieferten Instanz nathan (5.0.0): 76 von 386 relativen Links tot, alle 76 in publizierten Skills; der Rest der Instanz war sauber. Die auslösende Meldung kam von dort und war Klasse A — der session-setup.md-Verweis, den jedes Wiki-Skill vor seinem ersten wikitool-Aufruf ausspricht.

Der Schaden war nicht der fehlgeschlagene Read, sondern dass die Sitzung danach weiterarbeitete: ohne Budget-Skalierung, ohne gelesene Gate-Prozedur, ohne die Konventionen der Instanz. Ein toter Link in einer Instruction ist ein still übersprungener Schritt.

Wurzel: Nichts im Stack löste je ein Linkziel auf. docs verify registrierte zehn Checks, keiner las ein Linkziel; instructions verify prüfte, ob eine Instruction referenziert wird, nie ob die Referenz auflöst. Deshalb konnte der Befund 52-fach und unbemerkt wachsen.

Umgesetzt

Regel: repo-root-relative Klartextpfade in SKILL.md. Alle 58 Verweise in den 7 SKILL.md stehen jetzt als Klartextpfad statt als relativer Markdown-Link — instructions/session-setup.md statt [session-setup.md](../session-setup.md), kb/CONVENTIONS.md § Tone statt eines Anker-Links. Ein solcher Pfad überlebt die Kopie unverändert, weil er nicht von der Position der lesenden Datei abhängt: das Arbeitsverzeichnis einer Sitzung ist die Instanzwurzel, belegt durch die auslösende Fehlermeldung selbst. Damit fielen Klasse A und B zugleich weg, ohne dass sync etwas Neues tut — die Kopie bleibt byteidentisch, drift() vergleicht weiter mit filecmp.dircmp.

Bewusst in Kauf genommen: aus der Quelle heraus ist ein solcher Verweis nicht mehr klickbar. Betrifft nur die 7 SKILL.md; alle übrigen Instructions werden nicht kopiert und behalten klickbare relative Links.

Verworfen, mit Begründung: sync die Links umschreiben zu lassen (macht die Kopie nicht-byteidentisch, drift() müsste die Transformation kennen); instructions/ mit unter .claude/skills/ zu publizieren (löst nur Klasse A, verdoppelt den Instruction-Baum, vervielfacht die Drift-Fläche); führende /-Pfade (lösen gegen die Dateisystemwurzel auf).

Zwei mechanische Checks, aufgeteilt nach Besitzverhältnis — das beantwortet die frühere offene Frage nach dem Prüfort mit beiden, nicht mit einem:

  • instructions verifycheck_skill_reference_paths: verbietet jeden relativen Markdown-Link in einer SKILL.md. Ein Verbot statt einer Tiefenarithmetik, weil ein Markdown-Linkchecker Klartextpfade ohnehin nicht sieht — der Rückfallschutz liegt in der Form, nicht im Ziel. Liegt in instructions_cmd.py, das die Skill/Instruction-Trennung (skill_dirs() vs. instruction_files()) bereits besitzt.
  • docs verifycheck_reference_targets: löst jeden relativen Markdown-Link über den Dateisatz von docs toc auf (AGENTS.md, die Stage-Contracts, kb/CONVENTIONS.md, die COLLECTION.md, alle flachen instructions/**.md) und meldet ein totes Ziel. Anker werden vor dem Auflösen abgeschnitten; Code-Fences und Inline-Code-Spans werden maskiert (markdown_code.strip_code_spans), damit eine Stelle, die Link-Syntax als Beispiel zeigt, nicht als echte Referenz gilt. Ein Ziel, das der Stack nur als <ziel>.template ausliefert, gilt als aufgelöst (siehe Nachbesserung unten). MARKDOWN_LINK_RE und is_external_or_anchor leben einmal in docs_verify und werden von instructions_cmd importiert (Invariante 8).

CHANGES.md bleibt außerhalb des Prüfumfangs — die zweite frühere offene Frage, entschieden wie vorgeschlagen: die beiden toten Links dort (instructions/claude-code-model-selection.md, instructions/enable-dev-extras.md) sind Belege für vergangene Zustände, keine Wegweiser, und dist export ersetzt CHANGES.md beim Export ohnehin vollständig. commonplace/ (Vendor) und raw/ (Daten, Invariante 4) liegen aus denselben Besitz- bzw. Vertrauensgründen außerhalb.

Nebenbefund behoben: instructions/dev/doc-pull-through.md:36,45 trug ../tools/CONTRACT.md statt ../../tools/CONTRACT.md — ein reiner Autorenfehler in der Quelle, unabhängig vom Kopierproblem, und der Fall, an dem check_reference_targets nachweislich greift.

Dokumentation nachgezogen: instructions/CONTRACT.md § "A skill's outbound reference is a plain path, not a link" trägt Regel und Begründung samt der Abgrenzung, warum SKILL.md anders behandelt wird als eine flache Instruction; § "Reference depth" benennt jetzt eine Referenz statt eines Links. tools/CONTRACT.md ist in beiden Tabellen (§ Commands, § Error contracts) für beide Checks nachgezogen.

Nachbesserung: der Check feuerte auf einem frischen Export

Unmittelbar nach dem ersten Schließen dieses Issues gegen einen frischen dist export nachgeprüft — was in der ursprünglichen Verifikation gefehlt hatte. check_reference_targets meldete dort 13 tote Links (9× kb/CONTRACT.md, dazu german-terminology.md, kb-profiles.md, link-taxonomy.md), und zwar dafür, dass der Export tut, was er soll: kb/CONVENTIONS.md und die vier COLLECTION.md werden nur als .template ausgeliefert und erst im Personalisierungsschritt von instructions/setup-instance.md übernommen, während die stack-eigenen Dateien sie unter ihrem künftigen Namen verlinken — korrekt, denn so wird sie heißen.

Behoben in c0dc212 (6.0.0-beta.2): ein Linkziel gilt auch dann als aufgelöst, wenn daneben <ziel>.template liegt. Eng gefasst — fehlt beides, bleibt es ein Befund; zwei Tests fixieren beide Richtungen. Damit beschreibt der Check nicht länger "noch nicht personalisiert" als "kaputter Link", einen Zustand, den doctor unter conventions präzise und zuständig meldet.

CI war davon nie rot: der Replay in .gitea/workflows/ci.yml übernimmt die Templates, bevor er docs verify aufruft, und setup-instance.md stellt die Personalisierung (Schritt 5/6) ebenfalls vor die Verifikation (Schritt 13). Getroffen hätte es jeden, der nach dem Export einmal zur Kontrolle docs verify aufruft.

Versionsteil: MAJOR, nachträglich eskaliert

Zuerst als --patch gebumpt (5.1.1-beta.2). In der Schlussphase beim Lesen der eigenen Regel in tools/README.md § Adding a command Schritt 5 aufgefallen, dass das falsch war: check_reference_targets läuft über den Dateisatz von docs toc, und fünf Dateien darin gehören der Instanz, nicht dem Stack — kb/CONVENTIONS.md und die vier kb/<collection>/COLLECTION.md. Ein Drop-in-Copy von tools/, types/, instructions/ und AGENTS.md ersetzt sie nicht. Ein toter relativer Link darin lässt docs verify nach dem Update fehlschlagen, wo es vorher durchlief: genau die MAJOR-Zeile jener Regel ("a stricter check that newly fails on shipped content an instance already had"), und instructions/dev/version-parts.md entscheidet den Zweifelsfall zugunsten des Grenzübertritts.

Gemessen bricht heute nichts — nathan trägt 25 relative Links in diesen fünf Dateien, davon null tote; dieses Repo ebenso. Die Einstufung folgt der Reichweite des Checks, nicht einem beobachteten Schaden. Der Kandidat wurde nach ausdrücklicher Freigabe des Betreibers auf 6.0.0-beta.1 eskaliert, mit --breaking (was aufhört zu funktionieren und wie eine Instanz es repariert) und --no-migration (keine kb/-Seite ändert ihre Form).

Dass der Fehlgriff von einem Menschen beim Lesen des Diffs gefunden wurde und von keinem Check, ist genau das, was docs/version-model.md über diese Stelle sagt — die Seite ist dadurch bestätigt, nicht veraltet.

Akzeptanzkriterien

  • Keine der 7 instructions/**/SKILL.md enthält noch einen relativen Markdown-Link; alle 58 Verweise stehen als repo-root-relative Pfade.
  • Jeder dieser Pfade löst auf eine existierende Datei auf — nachgemessen im Repo, in beiden publizierten Bäumen (.claude/skills/, .agents/skills/) und gegen einen frischen dist export, sowohl vor als auch nach der Template-Übernahme: jeweils 0 tote.
  • instructions sync erzeugt weiterhin byteidentische Kopien; drift() ist unverändert und meldet nach einem sync nichts (instructions verify: 14 Kopien stimmen mit ihrer Quelle überein).
  • Ein wikitool-Check meldet beide Hälften und läuft in CI (docs verify und instructions verify sind beide Teil von .gitea/workflows/ci.yml).
  • Der Check feuert auf den bekannten Fällen und nicht auf Vendor- und Rohdatenbestand — und, nach der Nachbesserung, auch nicht auf einem noch nicht personalisierten Export.
  • instructions/dev/doc-pull-through.md:36,45 korrigiert.
  • instructions/CONTRACT.md trägt die Regel; tools/CONTRACT.md ist in § Commands und § Error contracts nachgezogen.
  • Tests decken beide Richtungen ab und die Relokation der Kopie selbst — 15 neue Tests, darunter test_a_plain_path_resolves_the_same_regardless_of_which_copy_reads_it (die Eigenschaft, auf der die Reparatur ruht) und die zwei Template-Tests aus der Nachbesserung.

Verifiziert

tools/wikitool docs verify (56 Kommandos, 38 Referenzdateien, "every link resolving"), tools/wikitool instructions verify (22 Instructions, 7 Skills, 14 Kopien), pytest 1244 passed. Außerhalb der Werkzeugkette nachgemessen: .claude/skills/ und .agents/skills/ tragen 0 relative Links, instructions/ 114 relative Links mit 0 toten, die fünf instanz-eigenen Dateien in nathan 25 Links mit 0 toten, und ein frischer dist export 0 Befunde — vor wie nach der Template-Übernahme.

Was die erste Verifikation nicht abdeckte, und die Lehre daraus: sie prüfte den Arbeitsbaum und nicht den exportierten — bei einer Änderung, deren ganzer Gegenstand Kopien in anderer Verzeichnistiefe sind. Genau die Achse, um die es ging, war die ungeprüfte; der Defekt der Nachbesserung stand deshalb kurzzeitig ausgeliefert im Repo. pytest/docs verify/instructions verify liefen dabei durchgehend grün, was instructions/dev/stack-dev.mds Vorbehalt bestätigt: abgedeckt ist, was die Tests abdecken, nicht was sie abdecken sollten.

Commits: 0fb8fd6 (Reparatur, Checks, Tests, Doku), f140e26 (Versionseskalation auf 6.0.0-beta.1), c0dc212 (Template-Ausnahme, 6.0.0-beta.2).

Verwandt

#83 (instructions verify gleicht "wikitool commands used" gegen den Skill-Body ab) — dieselbe Prüfstelle und dieselbe Lücke: am publizierten Skill wird inhaltlich nichts geprüft. Kein Duplikat; check_skill_reference_paths schließt nur die Link-Hälfte davon.

`tools/wikitool instructions sync` kopierte jede `SKILL.md` unverändert (`shutil.copytree`) in ein Verzeichnis anderer Tiefe und ohne ihre Nachbarn. Jeder relative Link, der für den Quellort korrekt geschrieben war, zeigte in der publizierten Kopie ins Leere. Gemessen am 2026-09-12, vor der Reparatur: | Baum | relative Links | lösten auf | tot | |---|---|---|---| | `instructions/**/SKILL.md` (Quelle, 7 Dateien) | 58 | 58 | 0 | | `.claude/skills/**/SKILL.md` (publiziert) | 58 | 6 | **52** | Keiner der 52 war ein Tippfehler — für jeden existierte die Zieldatei im Repo. Die sechs Überlebenden waren zwei Zufälle: Verweise auf ein *anderes publiziertes Skill* (`../stack-dev/SKILL.md`) und `../../../docs/model-and-effort-selection.md` aus den Dev-Skills, die in Quelle und Ziel zufällig gleich tief lagen. Zwei unabhängige Ursachen mit verschiedener Reparatur: | | Fälle | Beispiel | Durch Tiefenkorrektur reparabel? | |---|---|---|---| | A | 38 | `../session-setup.md`, `../gates.md`, `../issue-tracking.md` | **Nein** — `instructions/` wurde gar nicht mitpubliziert, das Ziel fehlte unter `.claude/skills/` in jeder Tiefe | | B | 14 | `../../kb/CONTRACT.md`, `../../raw/CONTRACT.md` | Ja — ein `../` zu wenig | In der ausgelieferten Instanz `nathan` (5.0.0): 76 von 386 relativen Links tot, **alle 76 in publizierten Skills**; der Rest der Instanz war sauber. Die auslösende Meldung kam von dort und war Klasse A — der `session-setup.md`-Verweis, den jedes Wiki-Skill vor seinem ersten `wikitool`-Aufruf ausspricht. Der Schaden war nicht der fehlgeschlagene Read, sondern dass die Sitzung danach weiterarbeitete: ohne Budget-Skalierung, ohne gelesene Gate-Prozedur, ohne die Konventionen der Instanz. Ein toter Link in einer Instruction ist ein still übersprungener Schritt. **Wurzel:** Nichts im Stack löste je ein Linkziel auf. `docs verify` registrierte zehn Checks, keiner las ein Linkziel; `instructions verify` prüfte, *ob* eine Instruction referenziert wird, nie ob die Referenz auflöst. Deshalb konnte der Befund 52-fach und unbemerkt wachsen. ## Umgesetzt **Regel: repo-root-relative Klartextpfade in `SKILL.md`.** Alle 58 Verweise in den 7 `SKILL.md` stehen jetzt als Klartextpfad statt als relativer Markdown-Link — `instructions/session-setup.md` statt `[session-setup.md](../session-setup.md)`, `kb/CONVENTIONS.md` § Tone statt eines Anker-Links. Ein solcher Pfad überlebt die Kopie unverändert, weil er nicht von der Position der lesenden Datei abhängt: das Arbeitsverzeichnis einer Sitzung ist die Instanzwurzel, belegt durch die auslösende Fehlermeldung selbst. Damit fielen Klasse A und B zugleich weg, ohne dass `sync` etwas Neues tut — die Kopie bleibt byteidentisch, `drift()` vergleicht weiter mit `filecmp.dircmp`. Bewusst in Kauf genommen: aus der Quelle heraus ist ein solcher Verweis nicht mehr klickbar. Betrifft nur die 7 `SKILL.md`; alle übrigen Instructions werden nicht kopiert und behalten klickbare relative Links. Verworfen, mit Begründung: `sync` die Links umschreiben zu lassen (macht die Kopie nicht-byteidentisch, `drift()` müsste die Transformation kennen); `instructions/` mit unter `.claude/skills/` zu publizieren (löst nur Klasse A, verdoppelt den Instruction-Baum, vervielfacht die Drift-Fläche); führende `/`-Pfade (lösen gegen die Dateisystemwurzel auf). **Zwei mechanische Checks, aufgeteilt nach Besitzverhältnis** — das beantwortet die frühere offene Frage nach dem Prüfort mit *beiden*, nicht mit einem: - `instructions verify` → `check_skill_reference_paths`: verbietet jeden relativen Markdown-Link in einer `SKILL.md`. Ein Verbot statt einer Tiefenarithmetik, weil ein Markdown-Linkchecker Klartextpfade ohnehin nicht sieht — der Rückfallschutz liegt in der Form, nicht im Ziel. Liegt in `instructions_cmd.py`, das die Skill/Instruction-Trennung (`skill_dirs()` vs. `instruction_files()`) bereits besitzt. - `docs verify` → `check_reference_targets`: löst jeden relativen Markdown-Link über den Dateisatz von `docs toc` auf (AGENTS.md, die Stage-Contracts, `kb/CONVENTIONS.md`, die `COLLECTION.md`, alle flachen `instructions/**.md`) und meldet ein totes Ziel. Anker werden vor dem Auflösen abgeschnitten; Code-Fences und Inline-Code-Spans werden maskiert (`markdown_code.strip_code_spans`), damit eine Stelle, die Link-Syntax als Beispiel zeigt, nicht als echte Referenz gilt. Ein Ziel, das der Stack nur als `<ziel>.template` ausliefert, gilt als aufgelöst (siehe Nachbesserung unten). `MARKDOWN_LINK_RE` und `is_external_or_anchor` leben einmal in `docs_verify` und werden von `instructions_cmd` importiert (Invariante 8). **`CHANGES.md` bleibt außerhalb des Prüfumfangs** — die zweite frühere offene Frage, entschieden wie vorgeschlagen: die beiden toten Links dort (`instructions/claude-code-model-selection.md`, `instructions/enable-dev-extras.md`) sind Belege für vergangene Zustände, keine Wegweiser, und `dist export` ersetzt `CHANGES.md` beim Export ohnehin vollständig. `commonplace/` (Vendor) und `raw/` (Daten, Invariante 4) liegen aus denselben Besitz- bzw. Vertrauensgründen außerhalb. **Nebenbefund behoben:** `instructions/dev/doc-pull-through.md:36,45` trug `../tools/CONTRACT.md` statt `../../tools/CONTRACT.md` — ein reiner Autorenfehler in der Quelle, unabhängig vom Kopierproblem, und der Fall, an dem `check_reference_targets` nachweislich greift. **Dokumentation nachgezogen:** `instructions/CONTRACT.md` § "A skill's outbound reference is a plain path, not a link" trägt Regel und Begründung samt der Abgrenzung, warum `SKILL.md` anders behandelt wird als eine flache Instruction; § "Reference depth" benennt jetzt eine *Referenz* statt eines *Links*. `tools/CONTRACT.md` ist in beiden Tabellen (§ Commands, § Error contracts) für beide Checks nachgezogen. ## Nachbesserung: der Check feuerte auf einem frischen Export Unmittelbar nach dem ersten Schließen dieses Issues gegen einen frischen `dist export` nachgeprüft — was in der ursprünglichen Verifikation gefehlt hatte. `check_reference_targets` meldete dort **13 tote Links** (9× `kb/CONTRACT.md`, dazu `german-terminology.md`, `kb-profiles.md`, `link-taxonomy.md`), und zwar dafür, dass der Export tut, was er soll: `kb/CONVENTIONS.md` und die vier `COLLECTION.md` werden nur als `.template` ausgeliefert und erst im Personalisierungsschritt von `instructions/setup-instance.md` übernommen, während die stack-eigenen Dateien sie unter ihrem künftigen Namen verlinken — korrekt, denn so wird sie heißen. Behoben in `c0dc212` (`6.0.0-beta.2`): ein Linkziel gilt auch dann als aufgelöst, wenn daneben `<ziel>.template` liegt. Eng gefasst — fehlt beides, bleibt es ein Befund; zwei Tests fixieren beide Richtungen. Damit beschreibt der Check nicht länger "noch nicht personalisiert" als "kaputter Link", einen Zustand, den `doctor` unter `conventions` präzise und zuständig meldet. CI war davon nie rot: der Replay in `.gitea/workflows/ci.yml` übernimmt die Templates, bevor er `docs verify` aufruft, und `setup-instance.md` stellt die Personalisierung (Schritt 5/6) ebenfalls vor die Verifikation (Schritt 13). Getroffen hätte es jeden, der nach dem Export einmal zur Kontrolle `docs verify` aufruft. ## Versionsteil: MAJOR, nachträglich eskaliert Zuerst als `--patch` gebumpt (`5.1.1-beta.2`). In der Schlussphase beim Lesen der eigenen Regel in `tools/README.md` § Adding a command Schritt 5 aufgefallen, dass das falsch war: `check_reference_targets` läuft über den Dateisatz von `docs toc`, und fünf Dateien darin gehören der **Instanz**, nicht dem Stack — `kb/CONVENTIONS.md` und die vier `kb/<collection>/COLLECTION.md`. Ein Drop-in-Copy von `tools/`, `types/`, `instructions/` und `AGENTS.md` ersetzt sie nicht. Ein toter relativer Link darin lässt `docs verify` nach dem Update fehlschlagen, wo es vorher durchlief: genau die MAJOR-Zeile jener Regel ("a stricter check that newly fails on shipped content an instance already had"), und `instructions/dev/version-parts.md` entscheidet den Zweifelsfall zugunsten des Grenzübertritts. Gemessen bricht heute nichts — `nathan` trägt 25 relative Links in diesen fünf Dateien, davon null tote; dieses Repo ebenso. Die Einstufung folgt der **Reichweite** des Checks, nicht einem beobachteten Schaden. Der Kandidat wurde nach ausdrücklicher Freigabe des Betreibers auf `6.0.0-beta.1` eskaliert, mit `--breaking` (was aufhört zu funktionieren und wie eine Instanz es repariert) und `--no-migration` (keine `kb/`-Seite ändert ihre Form). Dass der Fehlgriff von einem Menschen beim Lesen des Diffs gefunden wurde und von keinem Check, ist genau das, was `docs/version-model.md` über diese Stelle sagt — die Seite ist dadurch bestätigt, nicht veraltet. ## Akzeptanzkriterien - [x] Keine der 7 `instructions/**/SKILL.md` enthält noch einen relativen Markdown-Link; alle 58 Verweise stehen als repo-root-relative Pfade. - [x] Jeder dieser Pfade löst auf eine existierende Datei auf — nachgemessen im Repo, in beiden publizierten Bäumen (`.claude/skills/`, `.agents/skills/`) und gegen einen frischen `dist export`, sowohl vor als auch nach der Template-Übernahme: jeweils 0 tote. - [x] `instructions sync` erzeugt weiterhin byteidentische Kopien; `drift()` ist unverändert und meldet nach einem `sync` nichts (`instructions verify`: 14 Kopien stimmen mit ihrer Quelle überein). - [x] Ein `wikitool`-Check meldet beide Hälften und läuft in CI (`docs verify` und `instructions verify` sind beide Teil von `.gitea/workflows/ci.yml`). - [x] Der Check feuert auf den bekannten Fällen und **nicht** auf Vendor- und Rohdatenbestand — und, nach der Nachbesserung, auch nicht auf einem noch nicht personalisierten Export. - [x] `instructions/dev/doc-pull-through.md:36,45` korrigiert. - [x] `instructions/CONTRACT.md` trägt die Regel; `tools/CONTRACT.md` ist in § Commands und § Error contracts nachgezogen. - [x] Tests decken beide Richtungen ab und die Relokation der Kopie selbst — 15 neue Tests, darunter `test_a_plain_path_resolves_the_same_regardless_of_which_copy_reads_it` (die Eigenschaft, auf der die Reparatur ruht) und die zwei Template-Tests aus der Nachbesserung. ## Verifiziert `tools/wikitool docs verify` (56 Kommandos, 38 Referenzdateien, "every link resolving"), `tools/wikitool instructions verify` (22 Instructions, 7 Skills, 14 Kopien), `pytest` 1244 passed. Außerhalb der Werkzeugkette nachgemessen: `.claude/skills/` und `.agents/skills/` tragen 0 relative Links, `instructions/` 114 relative Links mit 0 toten, die fünf instanz-eigenen Dateien in `nathan` 25 Links mit 0 toten, und ein frischer `dist export` 0 Befunde — vor wie nach der Template-Übernahme. **Was die erste Verifikation nicht abdeckte, und die Lehre daraus:** sie prüfte den Arbeitsbaum und nicht den exportierten — bei einer Änderung, deren ganzer Gegenstand Kopien in anderer Verzeichnistiefe sind. Genau die Achse, um die es ging, war die ungeprüfte; der Defekt der Nachbesserung stand deshalb kurzzeitig ausgeliefert im Repo. `pytest`/`docs verify`/`instructions verify` liefen dabei durchgehend grün, was `instructions/dev/stack-dev.md`s Vorbehalt bestätigt: abgedeckt ist, was die Tests abdecken, nicht was sie abdecken sollten. Commits: `0fb8fd6` (Reparatur, Checks, Tests, Doku), `f140e26` (Versionseskalation auf `6.0.0-beta.1`), `c0dc212` (Template-Ausnahme, `6.0.0-beta.2`). ## Verwandt #83 (`instructions verify` gleicht "wikitool commands used" gegen den Skill-Body ab) — dieselbe Prüfstelle und dieselbe Lücke: am publizierten Skill wird inhaltlich nichts geprüft. Kein Duplikat; `check_skill_reference_paths` schließt nur die Link-Hälfte davon.
torben added the status/unconfirmedstatus/incoming labels 2026-09-12 16:42:11 +00:00
Author
Owner

Ausgearbeitet aus dem status/incoming-Stub. Der Stub im Wortlaut, weil die Rumpfumschreibung unten die einzige Aufzeichnung der ursprünglichen Anfrage überschreibt:

Relative Pfade werden aus Skills nicht zuverlässig gefunden

Lesen fehlgeschlagen
session-setup.md
File does not exist. Note: your current working directory is /home/torben/src/nathan.
file_path: /home/torben/src/nathan/.claude/skills/session-setup.md

Changelog: Verdacht bestätigt und vermessen — status/unconfirmed fällt weg. "Nicht zuverlässig" war zu schwach: 52 von 58 relativen Links brechen deterministisch, Titel entsprechend geändert. Zwei unabhängige Ursachen getrennt (fehlendes Ziel vs. Tiefenversatz), Gegenprobe in einer ausgelieferten Instanz (nathan 5.0.0: 76/386 tot, alle in publizierten Skills). Als Wurzel ergänzt, dass der Stack überhaupt keine Linkziel-Prüfung hat, plus zwei weitere Fälle derselben Symptomklasse mit anderer Ursache. Drei Entscheidungen benannt, nicht beantwortet → kind/decision. Vier Pflichtlabel gesetzt, status/incoming entfernt.

Ausgearbeitet aus dem `status/incoming`-Stub. Der Stub im Wortlaut, weil die Rumpfumschreibung unten die einzige Aufzeichnung der ursprünglichen Anfrage überschreibt: > **Relative Pfade werden aus Skills nicht zuverlässig gefunden** > > ``` > Lesen fehlgeschlagen > session-setup.md > File does not exist. Note: your current working directory is /home/torben/src/nathan. > file_path: /home/torben/src/nathan/.claude/skills/session-setup.md > ``` **Changelog:** Verdacht bestätigt und vermessen — `status/unconfirmed` fällt weg. "Nicht zuverlässig" war zu schwach: 52 von 58 relativen Links brechen deterministisch, Titel entsprechend geändert. Zwei unabhängige Ursachen getrennt (fehlendes Ziel vs. Tiefenversatz), Gegenprobe in einer ausgelieferten Instanz (`nathan` 5.0.0: 76/386 tot, alle in publizierten Skills). Als Wurzel ergänzt, dass der Stack überhaupt keine Linkziel-Prüfung hat, plus zwei weitere Fälle derselben Symptomklasse mit anderer Ursache. Drei Entscheidungen benannt, nicht beantwortet → `kind/decision`. Vier Pflichtlabel gesetzt, `status/incoming` entfernt.
torben changed title from Relative Pfade werden aus Skills nicht zuverlässig gefunden to `instructions sync` kopiert Skills in eine andere Verzeichnistiefe: 52 von 58 relativen Links brechen 2026-09-12 19:08:23 +00:00
torben added prio/blockingsize/Marea/processkind/decision and removed status/unconfirmedstatus/incoming labels 2026-09-12 19:08:32 +00:00
torben added kind/build and removed kind/decision labels 2026-09-12 19:11:45 +00:00
Author
Owner

Changelog: Entscheidung 1 getroffen — repo-root-relative Klartextpfade in den 7 SKILL.md statt relativer Markdown-Links; der Abschnitt "Zu entscheiden" ist durch "Entschieden" mit Begründung und den drei verworfenen Alternativen ersetzt. Daraus ergänzt: die Prüfung braucht zwei Hälften, weil ein Markdown-Linkchecker Klartextpfade nicht sieht, und die Quellen zu prüfen genügt, solange die Kopie byteidentisch bleibt. Neue Akzeptanzkriterien für Byteidentität und drift(). Präzisiert, dass nur die 7 SKILL.md betroffen sind — die flachen Instructions werden nicht kopiert und behalten klickbare relative Links. Restfragen (Prüfort, CHANGES.md-Umfang) unter "Noch offen", beide von der Umsetzungssitzung tragbar → kind/decision wird kind/build.

**Changelog:** Entscheidung 1 getroffen — repo-root-relative Klartextpfade in den 7 `SKILL.md` statt relativer Markdown-Links; der Abschnitt "Zu entscheiden" ist durch "Entschieden" mit Begründung und den drei verworfenen Alternativen ersetzt. Daraus ergänzt: die Prüfung braucht zwei Hälften, weil ein Markdown-Linkchecker Klartextpfade nicht sieht, und die Quellen zu prüfen genügt, solange die Kopie byteidentisch bleibt. Neue Akzeptanzkriterien für Byteidentität und `drift()`. Präzisiert, dass nur die 7 `SKILL.md` betroffen sind — die flachen Instructions werden nicht kopiert und behalten klickbare relative Links. Restfragen (Prüfort, `CHANGES.md`-Umfang) unter "Noch offen", beide von der Umsetzungssitzung tragbar → `kind/decision` wird `kind/build`.
Author
Owner

Changelog: Rumpf auf den Endzustand umgeschrieben und geschlossen. Der Defekt steht jetzt durchgehend im Präteritum; aus "Entschieden"/"Noch offen" ist ein "Umgesetzt"-Abschnitt geworden, der beide Restfragen als beantwortet führt — Prüfort: beide Kommandos, aufgeteilt nach Besitzverhältnis (check_skill_reference_paths in instructions verify, check_reference_targets in docs verify); CHANGES.md: außerhalb des Umfangs, wie vorgeschlagen. Neuer Abschnitt zum Versionsteil: zuerst --patch, in der Schlussphase als Grenzübertritt erkannt (der Check erreicht fünf instanz-eigene Dateien, die ein Drop-in-Copy nicht ersetzt) und nach Freigabe auf 6.0.0-beta.1 eskaliert. Alle acht Akzeptanzkriterien abgehakt, jeweils mit dem, was sie belegt. Verifikation benannt statt nur Commit-Hashes: docs verify, instructions verify, 1242 Tests, plus Nachmessung in beiden publizierten Bäumen und in der Instanz nathan.

**Changelog:** Rumpf auf den Endzustand umgeschrieben und geschlossen. Der Defekt steht jetzt durchgehend im Präteritum; aus "Entschieden"/"Noch offen" ist ein "Umgesetzt"-Abschnitt geworden, der beide Restfragen als beantwortet führt — Prüfort: *beide* Kommandos, aufgeteilt nach Besitzverhältnis (`check_skill_reference_paths` in `instructions verify`, `check_reference_targets` in `docs verify`); `CHANGES.md`: außerhalb des Umfangs, wie vorgeschlagen. Neuer Abschnitt zum Versionsteil: zuerst `--patch`, in der Schlussphase als Grenzübertritt erkannt (der Check erreicht fünf instanz-eigene Dateien, die ein Drop-in-Copy nicht ersetzt) und nach Freigabe auf `6.0.0-beta.1` eskaliert. Alle acht Akzeptanzkriterien abgehakt, jeweils mit dem, was sie belegt. Verifikation benannt statt nur Commit-Hashes: `docs verify`, `instructions verify`, 1242 Tests, plus Nachmessung in beiden publizierten Bäumen und in der Instanz `nathan`.
Author
Owner

Changelog: Abschnitt "Verifiziert" korrigiert - er war unvollständig, und ein Defekt daraus ist inzwischen behoben (c0dc212, 6.0.0-beta.2).

Direkt nach dem Schließen gegen einen frischen dist export nachgeprüft, was hier vorher nicht geschehen war: check_reference_targets meldete dort 13 tote Links (9× kb/CONTRACT.md, dazu german-terminology.md, kb-profiles.md, link-taxonomy.md) - und zwar dafür, dass der Export tut, was er soll. kb/CONVENTIONS.md und die vier COLLECTION.md werden nur als .template ausgeliefert und erst im Personalisierungsschritt übernommen; die stack-eigenen Dateien verlinken sie unter ihrem künftigen Namen, korrekt.

Behoben: ein Linkziel gilt auch dann als aufgelöst, wenn daneben <ziel>.template liegt. Eng gefasst - fehlt beides, bleibt es ein Befund. Zwei Tests fixieren beide Richtungen.

CI war nie rot (der Replay übernimmt die Templates vor docs verify, und setup-instance.md stellt die Personalisierung in Schritt 5/6 vor die Verifikation in Schritt 13); getroffen hätte es jeden, der nach dem Export einmal zur Kontrolle docs verify aufruft.

Die Lehre gehört zum Paket: die Verifikation hatte den Arbeitsbaum geprüft und nicht den exportierten - bei einer Änderung, deren ganzer Gegenstand Kopien in anderer Verzeichnistiefe sind. Genau die Achse, um die es ging, war die ungeprüfte.

**Changelog:** Abschnitt "Verifiziert" korrigiert - er war unvollständig, und ein Defekt daraus ist inzwischen behoben (`c0dc212`, `6.0.0-beta.2`). Direkt nach dem Schließen gegen einen frischen `dist export` nachgeprüft, was hier vorher nicht geschehen war: `check_reference_targets` meldete dort **13 tote Links** (9× `kb/CONTRACT.md`, dazu `german-terminology.md`, `kb-profiles.md`, `link-taxonomy.md`) - und zwar dafür, dass der Export tut, was er soll. `kb/CONVENTIONS.md` und die vier `COLLECTION.md` werden nur als `.template` ausgeliefert und erst im Personalisierungsschritt übernommen; die stack-eigenen Dateien verlinken sie unter ihrem künftigen Namen, korrekt. Behoben: ein Linkziel gilt auch dann als aufgelöst, wenn daneben `<ziel>.template` liegt. Eng gefasst - fehlt beides, bleibt es ein Befund. Zwei Tests fixieren beide Richtungen. CI war nie rot (der Replay übernimmt die Templates vor `docs verify`, und `setup-instance.md` stellt die Personalisierung in Schritt 5/6 vor die Verifikation in Schritt 13); getroffen hätte es jeden, der nach dem Export einmal zur Kontrolle `docs verify` aufruft. Die Lehre gehört zum Paket: die Verifikation hatte den Arbeitsbaum geprüft und nicht den exportierten - bei einer Änderung, deren ganzer Gegenstand Kopien in anderer Verzeichnistiefe sind. Genau die Achse, um die es ging, war die ungeprüfte.
Author
Owner

Korrektur zum Rumpf: Der Abschnitt "Verifiziert" nennt den Vorbehalt "abgedeckt ist, was die Tests abdecken" als aus instructions/dev/stack-dev.md stammend. Diese Datei gibt es nicht — der Vorbehalt steht in instructions/dev/stack-dev/SKILL.md, Schritt 3. Eine falsche Pfadangabe in einem Issue über falsche Pfadangaben; hier als Korrektur statt als weitere Rumpfumschreibung, weil sonst nichts am Zustand falsch ist.

**Korrektur zum Rumpf:** Der Abschnitt "Verifiziert" nennt den Vorbehalt "abgedeckt ist, was die Tests abdecken" als aus `instructions/dev/stack-dev.md` stammend. Diese Datei gibt es nicht — der Vorbehalt steht in `instructions/dev/stack-dev/SKILL.md`, Schritt 3. Eine falsche Pfadangabe in einem Issue über falsche Pfadangaben; hier als Korrektur statt als weitere Rumpfumschreibung, weil sonst nichts am Zustand falsch ist.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: torben/chemenu#98