feat: Story 2.3 Code-Review-Patches (Rev 2.0) — Pin-Schärfung + Change-Log-Scope

Code-Review (4 Layer) Story 2.3 — 2 Patch-Findings umgesetzt, 7 deferred.

Patch 1 (schema/compiler.md §5.6 → Revision 2.0):
- Form-Check (Formel 2) um Exklusions-Stufe `grep -vE '^\.'` ergänzt —
  Ziele mit `./`-Präfix werden definiert aus dem Pin ausgenommen statt still
  als "interne .md-Form" durchzugehen (Blind-Hunter BH-8 / Edge-Case EH-4).
- Dangling-Check (Formel 3) case-Muster um `./*|/*` erweitert — konsistent
  zu `../*`-Exklusion (kein DANGLING: ./foo.md-Fehlbenennung mehr).
- Byte-identisch in Spec-Verification gespiegelt (5/5 Formeln, verifiziert).

Patch 2 (spec Change Log / bad_spec-Zeile):
- Scope-Klarstellung der raw/-Zählungen: 30 (log.md-exkludiert, gepinnte
  Baseline) vs. 34 (inkl. log.md) vs. 28 (Zeilen-Metrik) — verschiedene
  Metriken, kein Widerspruch mehr.

Review-Findings-Sektion + Spec-Change-Log-Eintrag in spec-2-3-…md;
7 Defer-Findings unter "## Deferred from: code review" in deferred-work.md
(Image-Scope, Multi-Line-, Reference-Style-, Leading-Space-Ziele,
Area-log.md, Cross-Page-Evidenz, log.md-Exklusion — Story-2.4-Kandidat).

Positiv-Kontrolle nach Patch: Bestands 8, Form 0, Dangling leer, raw/ 30≡30.
sprint-status.yaml: 2-3-… -> done; last_updated 08-17-2026 15:40.

Co-Authored-By: Claude <noreply@anthropic.com>
@
This commit is contained in:
Michael Tamse
2026-08-17 16:06:50 +02:00
parent bb7db2d025
commit 66451b6e6c
4 changed files with 65 additions and 10 deletions
+4 -3
View File
@@ -143,15 +143,15 @@ Beziehungen zwischen Concepts werden mit normalen Markdown-Links ausgedrückt
**(2) Form-Check** (erwartet Ausgabe `0`, Exit `0` — jeder interne Link in der gepinnten Form; jede Formverletzung (fehlende `.md`-Endung, Mischform, leeres Ziel) erhöht den Zähler um 1; `|| true` bindet den Exit-Code — grep `-c` liefert Exit `1` bei Ausgabe `0`, der gewünschten SUCCESS-Konfiguration):
```sh
sh -c "grep -rohE ']\([^)]*\)' --include='*.md' --exclude=log.md wiki/ | sed -E 's/^\]\(//; s/\)$//' | sort -u | grep -vE '^(raw/|\.\./|#)' | grep -vE ':' | grep -cvE '^[^#]+\.md$' || true"
sh -c "grep -rohE ']\([^)]*\)' --include='*.md' --exclude=log.md wiki/ | sed -E 's/^\]\(//; s/\)$//' | sort -u | grep -vE '^(raw/|\.\./|#)' | grep -vE '^\.' | grep -vE ':' | grep -cvE '^[^#]+\.md$' || true"
```
Exkludiert: `raw/`-Provenienz (§5.5, andere Schicht), `../schema/`, externe Ziele (alle enthalten `:` — `http://`, `https://`, `mailto:`, protocol-less Hostnamen; interne OKF-Ziele sind Kebab-Case und enthalten nie `:`), Gleichseit-Anker `(#…)`. Cross-Page-Anker `file.md#sec` werden weiterhin gezählt (normative Frage, s. `deferred-work.md`).
Exkludiert: `raw/`-Provenienz (§5.5, andere Schicht), `../schema/`, `./`-Präfix-Ziele (`^\.` — nicht root-relativ/keine Bundle-Pfad-Form), externe Ziele (alle enthalten `:` — `http://`, `https://`, `mailto:`, protocol-less Hostnamen; interne OKF-Ziele sind Kebab-Case und enthalten nie `:`), Gleichseit-Anker `(#…)`. Cross-Page-Anker `file.md#sec` werden weiterhin gezählt (normative Frage, s. `deferred-work.md`).
**(3) Dangling-Check** (erwartet: keine Ausgabe — jedes interne Ziel existiert relativ zum Bundle-Root, bundlerelativ als Auflösungsmodell des Bundles, AD-7b; ein nicht existierendes Ziel liefert `DANGLING: <pfad>`; leere Ziele liefern `DANGLING: (leeres Ziel)`):
```sh
sh -c 'grep -rohE "]\([^)]*\)" --include="*.md" --exclude=log.md wiki/ | sed -E "s/^\]\(//; s/\)$//" | sort -u | while read -r t; do case "$t" in ""|*:*|raw/*|../*) if [ "$t" = "" ]; then echo "DANGLING: (leeres Ziel)"; fi; continue;; esac; case "$t" in "#"*) continue;; esac; p=${t%%#*}; [ -f "wiki/$p" ] || echo "DANGLING: $t"; done'
sh -c 'grep -rohE "]\([^)]*\)" --include="*.md" --exclude=log.md wiki/ | sed -E "s/^\]\(//; s/\)$//" | sort -u | while read -r t; do case "$t" in ""|*:*|raw/*|../*|./*|/*) if [ "$t" = "" ]; then echo "DANGLING: (leeres Ziel)"; fi; continue;; esac; case "$t" in "#"*) continue;; esac; p=${t%%#*}; [ -f "wiki/$p" ] || echo "DANGLING: $t"; done'
```
Das Fragment wird vor dem Existenztest gestripped (`file.md#sec` → `file.md` — kein falscher `DANGLING` für existierende Ziele; die Pin-Form-Frage bleibt beim Form-Check). Exkludiert wie beim Form-Check. (Bekannt-konservativ: Ziele mit `)` werden am ersten `)` abgeschnitten → falsch benannte Ursache, aber keine Stille — dokumentiert in `deferred-work.md`.)
@@ -250,3 +250,4 @@ Diese Instruktion ist auf die **Erzeugung neuer Concepts auf Root-Ebene** begren
- **Revision 1.7 (2026-08-17, bmad-code-review Story 2.2, Patch-Runde 2):** (1) Selbsttest-Grep-Formel behoben — `grep -nE '(raw/|]\(raw/'` war eine ungültige ERE (ungeschlossenes Klammerpaar, `exit 2`); jetzt `grep -nE '\(raw/'` (das Teilmuster `(raw/` erfasst Plain-Form und Markdown-Linkform gleichermaßen), Pkt.1 und Pkt.4, re-executierbar (AD-17h); (2) Komma-Form `(raw/<datei.md>, <stellen-kennung>)` als zulässige zweite Inline-Form in Pkt.1 formal festgelegt (für Stellen-Kennungen ohne Bezeichner-`id` im Rohdokument, z. B. Sektionstitel `§ 1 Vision`), analog zum Link-Form-Präzedenzfall bis Story 2.3 — Worked Example um Komma-Form-Beispiel ergänzt (D1-Entscheidung, Option 1); (3) Multi-Beleg-Serialisierung in Pkt.1 festgelegt (Semikolon + voller Pfad je Beleg; Komma-Gruppierung mehrerer `#`-Kennungen unter einem Pfad zulässig; bei gemischten Formen voller Pfad je Beleg; keine Pfad-Elision über Beleg-Grenzen); (4) Relokations-Sub-Bullets als **1a/1b** nummeriert (Label „Pkt. 1b" in §5.5-Intro, Pkt.5 und `deferred-work.md` existiert damit); (5) Marker-Muster-Zahl korrigiert: „drei" (zwei Grundmuster + Forward-Referenz-Variante), Pkt.2 und Pkt.4; Forward-Referenz-Beispiel-Zitat auf eindeutigen Sektionstitel `Story 3.1: Inkrementellen Datenfluss implementieren` disambiguiert (raw/epics trägt zwei „Epic 3"-Headings); (6) §8-Normreferenzen um AD-4a, AD-9, AD-13, AD-14, AD-16 (Spine), FR-16 (PRD), A0-3, FR-6/12/14, A0-6/7/11/18 (Epics) ergänzt. Keine Änderung an `wiki-compiler.md`/`validator.md`/`raw/`; kein Standalone (D-3); keine Vertragsänderung.
- **Revision 1.8 (2026-08-17, Story 2.3):** Neue Sektion „Concept-Links" als **§5.6** eingefügt (nach §5.5, vor §6): genau-eine-Form-**Pin** bundle-relativ mit `.md`-Endung (AD-7b, A0-9, FR-10; Rationale Null-Migration der 3 Concept-Links, explizite Datei-Ziele, Standard-Markdown-Tools/AD-8), Geltungsbereich (Concept-Bodies + `wiki/index.md`) mit expliziten Ausnahmen (`raw/`-Provenienz-Verweise §5.5, `../schema/`-Links, `http`-Links, Gleichseit-Anker `#…`), **vier** re-executierbare Selbsttest-Formeln (Bestands-, Form-, Dangling-Check + Kontakt-mit-`raw/`-Unverändert-Check mit deterministischer Baseline-Extraktion aus dem `baseline_commit` via `git show`, AD-17h; rekursiv lauffest für künftige Areas, Story 2.4/2.5), NFR-4-Regel (jede Form-Verletzung → Run-FAIL mit textuell benannter Ursache) und Worked Example. Die „bis Story 2.3"-Klauseln in §5.3 Pkt. 3 und §5.5 Pkt. 1 referenzieren jetzt §5.6; §7-Selbstbegrenzung-Bullet entsprechend umformuliert. Demonstrative Umsetzung: zwei inhaltsbegründete Cross-Links in `wiki/wissensarchitektur-trennung-states.md` (→ `llm-wiki-prinzip.md`, → `knowledge-kompilation-inkrementell.md`; keine erzwungene Gegenseitigkeit, AD-8). Keine Änderung an `wiki-compiler.md`/`validator.md`/`raw/` (der Punkt-11-Check akzeptiert bis auf Weiteres beide Schreibweisen — Einschränkung wäre eigene Autorisierung); keine neue §7-Invaliditätsklasse; kein Standalone (D-3); keine Vertragsänderung.
- **Revision 1.9 (2026-08-17, Story 2.3, Step-04-Review Loop 1, Patch-Runde):** §5.6-Formeln geschärft — (1) leere-Ziele-Erfassung (`[^)]*` statt `[^)]+` in Formel 1/2/3), (2) `log.md`-Exklusion in allen vier Formeln (`--exclude=log.md`) + Scan-Scope-Klarstellung in Pkt. 2 (Formeln scannen den `wiki/`-Baum mit Ausnahme von `log.md` — sie zitiert die Formel-Texte selbst), (3) externe-Ziel-Exklusion über `:` statt `http`-Präfix (Formel 2 `grep -vE ':'`; Formel 3 `case *:*`) — `http://`/`https://`/`mailto:`/protocol-less Hostnamen exkludiert, legale `http…`-Dateinamen nicht mehr fälschlich exkludiert, (4) Exit-Code-Bindung `|| true` am Ende des Form-Checks (grep `-c` liefert Exit `1` bei Ausgabe `0` — der gewünschten SUCCESS-Konfiguration), (5) Fragment-Strip im Dangling-Check vor dem Existenztest (`p=${t%%#*}` — `concepts.md#s1` bei existierender Datei liefert keinen falschen `DANGLING`; die Form-Frage bleibt beim Form-Check) und leere Ziele melden `DANGLING: (leeres Ziel)` statt still exkludiert; (6) raw/-Check (Formel 4) auf dynamische Baseline-Extraktion umgestellt (`git ls-tree -r --name-only <baseline_commit> -- wiki/` + `git show` je Datei, `wiki/log.md` gefiltert; einschließende Einzelanführungszeichen, damit `$f` erst in der inneren Shell expandiert) mit erwarteter Zählung **30** (`log.md`-exkludiert) und Voraussetzung „unveränderte `wiki/`-Dateimenge" (bei Datei-Zuwachs in späteren Runs Baseline-Extraktion neu durchführen). Pkt. 4 (NFR-4-Regel) um leere Ziele erweitert; Pkt. 5 (Worked Example) um Negativ-Beispiel (`[Test](ohne-endung)` → Form-Check `1` + `DANGLING: ohne-endung`) und Verweis-Korrektur („Pkt. 3.1" → „Pkt. 3, Formel (1)") ergänzt; §6.6 um §5.6-Referenzzeile (✓ gepinnte Form / ✗ fehlende `.md` → Form-Check > 0, Run-FAIL). Keine Änderung an `wiki-compiler.md`/`validator.md`/`raw/`; kein Standalone (D-3); keine neue §7-Klasse; keine Vertragsänderung.
- **Revision 2.0 (2026-08-17, Story 2.3, bmad-code-review, Review-Runde):** §5.6-Pin-Schärfung aus dem Code-Review (Blind-Hunter + Edge-Case-Hunter): (1) **Formel 2 (Form-Check)** um die Exklusions-Stufe `grep -vE '^\.'` erweitert — Ziele mit `./`-Präfix (und damit nicht-root-relative Pfade) werden definiert aus dem Pin ausgenommen, statt still als „interne `.md`-Form" durchzugehen; die erläuternde Exklusions-Aufzählung in Pkt. 2 entsprechend ergänzt (`./`-Präfix-Ziele: nicht root-relativ/keine Bundle-Pfad-Form); (2) **Formel 3 (Dangling-Check)** `case`-Muster um `./*` und `/*` erweitert — `./`-Präfix-Ziele und absolute Wurzel-Pfade werden konsistent exkludiert (Analog zu `../*`), statt `DANGLING: ./foo.md`-Fehlbenennung zu erzeugen. Beide Formeln bleiben deterministisch re-executierbar (AD-17h) und werden in der Spec-Verification byte-identisch gespiegelt (verifiziert: 5/5 Formel-Strings identisch compiler↔spec). Positiv-Kontrolle nach Patch: Form-Check `0` (Exit `0`), Dangling-Check leere Ausgabe, Bestands-Check `8` Links, `raw/`-Baseline `30 ≡ 30`. Keine Änderung an `wiki-compiler.md`/`validator.md`/`raw/`; kein Standalone (D-3); keine neue §7-Klasse; keine Vertragsänderung. (Die zugehörigen Defer-Findings — Image-Scope, Multi-Line-, Reference-Style- und Leading-Space-Ziele, künftiges Area-`log.md` — sind in `deferred-work.md` dokumentiert, Story-2.4-Kandidat.)