--- title: 'Deterministische Bereichszuordnung & Concept-Hierarchie (Story 2.4)' type: 'feature' created: '2026-08-18' status: 'done' review_loop_iteration: 2 baseline_commit: 66451b6e6c9e139fb3aa3bbf4b01291e1e2d273a context: - _bmad-output/implementation-artifacts/epic-2-context.md --- ## Intent **Problem:** Die Ziel-Pfad-Regel (§5.1) erzwingt noch konzeptlos alle neuen Concepts auf Root-Ebene ("Area-Zuordnung ist Story 2.4") — es gibt keine deterministische Regel, wohin ein erkanntes Thema gehört (AD-7c/A0-10 sind offen); die §5.6-Linkformeln exkludieren `../`-Ziele pauschal und wären für Area-Pfade nicht renderer-konform (offenes Deferred, Home Story 2.4). **Approach:** Neue §5.7 „Deterministische Bereichszuordnung & Concept-Hierarchie" in `schema/compiler.md`: Bereichszuordnung textual-deterministisch ((a) First-Class-Link aus dem bestehenden `index.md`-Baum, sonst (b) Root-Ebene; nie Embedding/Vector — AD-7c/AD-13), kanonische ID-Normalisierung (AD-7a), §3.2-Kollisions-Hold für Top-Level-Konflikte (A0-10, kein neues Prädikat), file-relatives Link-Auflösungsmodell (eine syntaktische Form, `../`-fähig; §5.6-Formeln area-fest). §5.1/§5.3/§7/§8/§6.6 nachgeführt. Demo: neue Area `wiki/wissensarchitektur/` (frontmatterloser Area-`index.md` + ein neues Area-Concept aus `raw/` mit `../`-Links auf Root-Concepts) + Negativ-Test der Kollision im Sandbox-Baum; kein MOVE bestehender Concepts (Kuratierung/AD-7d ist Epic-3-Nähe, nicht in den ACs). ## Boundaries & Constraints **Always:** - Bereichszuordnung ist **textual-deterministisch** ((a) bestehender `index.md`-Link gibt den Bereich vor; (b) Default Root-Ebene), nie Embedding/Vector (AD-7c, A0-10, AD-13). Die Regel wird als Instruktion in **§5.7** verankert — einziger Instruktions-Ort (D-3); keine Vertrags-/Validator-Änderung (§-Struktur wie Story 2.2/2.3-Präzedenz). Validator Punkt 11 akzeptiert bereits Areas (Area-`index.md`, verlinkt im nächsten Vorfahren) — strukturell unverändert. - Identität = relativer OKF-Pfad ohne `.md` (AD-7a): `wiki/spring/index.md` → `spring`, `wiki//.md` → `/`; genau eine Normalisierung. Eine als Area gedachte Anlage (`wiki//index.md` + Concept darunter) ist ab dieser Story **konform**, nicht mehr Bereichs-Hinweis. - **Link-Auflösungsmodell (löst §5.6-Defer):** Concept-Links sind **file-relativ** zur `.md`-Datei — eine syntaktische Form (bundle-relativ = identisch bei Root-Dateien; `../` für Aufwärts-Ziele innerhalb `wiki/`; `.md`-Endung bleibt Pflicht). §5.6-Formeln 2/3 exkludieren `../` **nicht mehr pauschal**, sondern validieren `../`-Ziele als in-Bundle-Aufwärts-Pfade (Quell-Verzeichnis relativ, Ziel muss unter `wiki/` liegen). `../schema/` bleibt anderer Schicht (exkludiert). Dangling-Auflösung: Existenztest relativ zum Bundleroot nach `../`-Auflösung. - Neue Area `wiki/wissensarchitektur/`: `index.md` **frontmatterlos** (Vertrag §2, Punkt 10), verlinkt die Area-Concepts in gepinnter Form (§5.6); neues Area-Concept `source-material.md` (`type: concept`, `sources` → `raw/architecture-spine/…`/`raw/prd/…`, §5.5-Inline-Verweise), Body-Links zu Root-Concepts im file-relativem `../`-Format (`[LLM-Wiki-Prinzip](../llm-wiki-prinzip.md)` u. ä.), inhaltsbegründet. Root-Concept `wissensarchitektur-trennung-states.md` bleibt unverändert auf Root. - `wiki/index.md`: neue Area-Sektion verlinkt `wissensarchitektur/index.md` (Navigation Root → Area, AD-9); bestehende Root-Links unverändert. `wiki/log.md`: Eintrag (Vertrag-§5-Format) mit Area-Anlage, neuem Concept, `sprint-status`-Wechsel `2-4-…` `backlog` → `in-progress`. - §5.6-Formel-4-Basislinie: Dieser Run ist ein expliziter „Datei-Zuwachs"-Run (neue Area-Dateien) — die „unveränderte Dateimenge"-Voraussetzung ist per §5.6-Text für diesen Run nicht erfüllt; die Baseline-Extraktion wird auf den neuen Baum (dieser Spezifikations-`baseline_commit`) neu durchgeführt und im log-Eintrag/Zählung dokumentiert. Kein Widerspruch zu §5.6-Text (dieser sieht den Zuwachs-Fall ausdrücklich vor). - `deferred-work.md`: die Story-2.4-benannten Defer-Einträge (bundlerelative Area-Auflösung; ggf. Cross-Page-Anker) erhalten `status:`-Zeile geschlossen bzw. dokumentarisch korrigiert (append-only; bestehende Einträge unverändert). `sprint-status.yaml`: Key `2-4-…` → `in-progress`. - Negativ-Test im Sandbox-/tmp-Baum: Erstellungskandidat mit Top-Level-ID-Kollision (z. B. `llm-wiki-prinzip`) löst den **§3.2-Hold** aus („Concept existiert bereits — Aktualisierung ist Epic 3"), kein stiller Overwrite, keine Index-Verlinkung. **Ask First:** Andere Pin-Wahl als file-relativ (`../`-fähig) · MOVE/Neuzuordnung bestehender Concepts (AD-7d) · Änderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` · neue Areas über die eine Demo-Area hinaus · Standalone-Tool. **Never:** Veränderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3) · neuen §7-Invaliditätsklasse · Vorwegnahme progressiver Discovery-Indizes/Navigation (Story 2.5) · Renames/Redirects (AD-7d) · Embedding/Vector-Infrastruktur (AD-13) · OKF-Dialekt. ## I/O & Edge-Case Matrix | Scenario | Input / State | Expected Output / Behavior | Error Handling | |----------|--------------|---------------------------|----------------| | HAPPY_PATH | Bundle + neue Area `wissensarchitektur/`, neues Area-Concept `source-material.md` | Area-`index.md` (frontmatterlos) verlinkt das Concept; Root-`index.md` verlinkt die Area; `../`-Body-Links lösen in Renderern und Dangling-Check auf; Validator SUCCESS (6 `wiki/`-Dateien) | N/A | | TOP_LEVEL_COLLISION | Erstellungskandidat mit ID = bestehendem Root-Pfad (`llm-wiki-prinzip`) | §3.2-Kollisions-Hold: kein Overwrite, kein Index-Link, keine Datei; Run „teilweise erfolgreich"/textueller Hinweis | N/A (Hold-Verhalten fixiert, §3.2) | | AREA_WITHOUT_INDEX | `wiki//` ohne `index.md` | validator Punkt 11 FAIL („Area ohne index.md=…") — Anlage ohne Area-Index ist strukturell invalide | Run-FAIL, textuelle Ursache (NFR-4) | | DEEP_LINK_UP | Body-Link `../llm-wiki-prinzip.md` aus `wiki/wissensarchitektur/source-material.md` | Form-Check `0`; Dangling: Auflösung relativ zum Quell-Verzeichnis → `wiki/llm-wiki-prinzip.md` existiert → keine Ausgabe | `../schema/…` weiterhin exkludiert (andere Schicht) | | DIVING_NON_EXISTENT | `../fehlt.md` aus Area-Concept | Dangling-Check meldet `DANGLING: ../fehlt.md` | Run-FAIL textuell benannt | ## Code Map - `schema/compiler.md` — **mutiert**: neue **§5.7** „Deterministische Bereichszuordnung & Concept-Hierarchie (Story 2.4)" (nach §5.6, vor §6): (1) Routing-Regel textual-deterministisch (index.md-Erst-`Link` → Bereich, sonst Root; AD-7c/A0-10/AD-13), (2) kanonische ID-Normalisierung (AD-7a, Beispieltabelle `wiki//index.md` → ``), (3) Kollisions-Hold → Verweis auf fixierten §3.2 (kein neues Prädikat, A0-10), (4) Link-Auflösungsmodell file-relativ (`../`-fähig, eine Form) + Formel-2/3-`../`-Schärfung, (5) Worked Example Area-Concept; **§5.1 Pkt.1** umgeschrieben (Root-Formel → Verweis auf §5.7; „Area-Zuordnung ist Story 2.4"-Backlog-Klausel aufgelöst); **§5.3 Pkt.3** (Area-Concept → Link in Area-`index.md` statt Bundleroot); **§5.6 Pkt.2/3** (Geltungsbereich/Auflösung `../` präzisiert, Formel-2-Exklusions-Liste + Formel-3-`case` um `../`-in-Bundle-Auflösung ergänzt; **Containment nach dem Loop-1-Review: Formel 3 MUSS Out-of-Bundle-Ausbruch über `..`-Traversale sperren** — ein Ziel `../[^./]…` (bzw. nach Auflösung unter `wiki/`) ist zulässig als in-Bundle-Aufwärts-Pfad, ein Ziel, dessen `..`-Auflösung **nicht** unter `wiki/` bleibt, MUSS als `DANGLING` gemeldet werden); **§5.6 Pkt.4 (Formel-4-Neu-Baseline)** muss die Baseline **aus dem `baseline_commit`-Kopf dieser Spezifikation** (`66451b6e6c9e139fb3aa3bbf4b01291e1e2d273a`) extrahieren, nicht aus dem Story-2.3-`7e1f449…`; **§5.7 Pkt.5** meldet eine Area ohne `index.md` **wörtlich** als `FAIL … Punkt 11: Index-Regel verletzt (Area ohne index.md=…)` (kein inventiertes `AREA_WITHOUT_INDEX`-Label); **§6.6** `§5.1`-Zeile angepasst (`wiki//.md` konform; Bereichs-Hinweis-Zelle entfällt); **§7**-Bullet „Deterministische Area-Zuordnung" von „verbleibt Story 2.4" → „in §5.7 verankert"; **§8**-Revisionslog 2.1 + Normreferenzen AD-7c/A0-10. - `wiki/wissensarchitektur/index.md` — **neu**: Area-`index.md`, frontmatterlos, verlinkt `source-material.md` (gepinnte Form). - `wiki/wissensarchitektur/source-material.md` — **neu**: Area-Concept, `type: concept`, `sources` → `raw/architecture-spine/architecture-spine-2026-08-14.md` (+ ggf. `raw/prd/prd-wow20-2026-08-14.md`), §5.5-Inline-Verweise, `../`-Links auf Root-Concepts. - `wiki/index.md` — **mutiert**: Area-Sektion verlinkt `wissensarchitektur/index.md`; bestehende Root-Links unverändert. - `wiki/log.md` — **append**: Eintrag (Area-Anlage, neues Concept, §5.6-Formel-4-Neu-Baseline, `sprint-status`-Wechsel, Negativ-Test-Hold-Nachweis). - `_bmad-output/implementation-artifacts/sprint-status.yaml` — **mutiert**: `2-4-deterministische-bereichszuordnung-concept-hierarchie` → `in-progress`. - `_bmad-output/implementation-artifacts/deferred-work.md` — **mutiert**: Story-2.4-Defer (bundlerelative Area-Auflösung) `status: umgesetzt (…)`-Zeile; Cross-Page-Anker-Eintrag dokumentarisch auf Ist-Verhalten korrigiert (append-only, keine bestehende Zeile ändern außer Status-/Korrektur-Fall). - `schema/wiki-compiler.md` (Punkt 11, §6), `schema/validator.md`, `raw/…` — **read-only** (AD-3). ## Tasks & Acceptance **Execution:** - [x] `schema/compiler.md` — §5.7 (Routing, ID-Normalisierung, Hold-Verweis, file-relativ-Auflösung + Formel-2/3-`../`-Schärfung, Worked Example); §5.1/§5.3/§5.6/§6.6/§7/§8 nachgeführt. Kein Schema-/Validator-/raw-Change. - [x] `wiki/wissensarchitektur/index.md` + `wiki/wissensarchitektur/source-material.md` — anlegen; Area-Index frontmatterlos, Concept §5.5-konform, `../`-Links gepinnt/inhaltsbegründet. - [x] `wiki/index.md` — Area-Sektion + Link auf `wissensarchitektur/index.md`. - [x] `wiki/log.md` — Eintrag gemäß Verifikations-Vorgaben; `sprint-status.yaml` → in-progress; `deferred-work.md`-Einträge schließen/korrigieren. - [x] Negative-/Edge-Tests im Sandbox-/tmp-Baum (TOP_LEVEL_COLLISION → §3.2-Hold; Area ohne `index.md` → Punkt 11 „Area ohne index.md=…"; `../`-Dangling; Out-of-Bundle-`..`-Escape → `DANGLING`). **Acceptance Criteria:** - Given ein erkanntes Thema, when der Bereich bestimmt wird, then geschieht dies textual-deterministisch (bestehender `index.md`-Link oder Root-Ebene; nie Embedding) (A0-10, AD-13). - Given die Concept-Identität, when ein Concept abgelegt wird, then entspricht sie dem relativen OKF-Pfad ohne `.md` mit genau einer Normalisierung (`wiki//index.md` → ``, AD-7a, A0-8). - Given eine Bereichsnavigation, when ein Consumer sich orientiert, then führt die Hierarchie (Area-`index.md`) schrittweise zu den Concepts — die neue Area ist über die Root-`index.md` erreichbar (AD-9, FR-11). - Given ein Konflikt mit existierendem Top-Level-Pfad, when erkannt, then löst der fixierte §3.2-Hold aus statt stillem Überschreiben (A0-10). - Given die Instruktion, when geprüft, then ist §5.7 der einzige Instruktions-Ort (D-3), §5.6-Formeln area-fest re-executierbar (AD-17h) und der Validator läuft SUCCESS (keine neue §7-Klasse, kein Schema-/Validator-/raw-Change). ## Spec Change Log - **2026-08-18 (Loop 2, bmad-code-review, 4 Layer; Abschluss):** Review-Loop 2 abgeschlossen — 3 `decision-needed` (Nutzer-Entscheidungen 1/1/1), 14 `patch` (alle umgesetzt), 4 `defer` (in `deferred-work.md` verankert), 8 dismissed. **Amendierung der nicht-gefrorenen Sektionen:** (a) Verification-Item 3 (Formel 4) von „Extraktion aus `baseline_commit` `66451b6…`" auf „Extraktion aus dem **Kopf des letzten Zuwachs-Runs** (`862cf41…`, 38 ≡ 38)" umgestellt (Decision 1 — der gepinnte Selbsttest hätte deterministisch `38 ≠ 30` = Run-FAIL geliefert); (b) Verification-Item 1 um den byte-identischen Formel-3-String (quellenbasierte `../schema/*`-Exklusion, Decision 2) ergänzt; (c) Verification-Item 4 auf 7 `wiki/`-Dateien + korrekten Punkt-Satz (die „6" der gefrorenen I/O-Matrix bleibt frozen — Defer). **Frozen-Sektionen unverändert** (I/O-Matrix „6 `wiki/`-Dateien"/„stillem Overwrite" = Änderungskandidat der nächsten Renegotiations-Runde). **Status:** `sprint-status.yaml` `2-4-…` `review` → `done` (spec-2-3-Präzedenz: `done` nach Review-Freigabe; Frontmatter `status: 'done'` damit deckungsgleich), `review_loop_iteration` → 2. **Kein Schema-/Validator-/raw-Change (AD-3); keine neue §7-Klasse; keine Vertragsänderung.** - **2026-08-18 (Erstellung):** Initiale Approve-Baseline. - **2026-08-18 (Loop 1, Step-04-bad_spec):** Amendierung der nicht-gefrorenen Sektionen (Code Map / Tasks / Verification) nach dem Review-Loop 1. **Auslöser-Findings:** (A1) `schema/compiler.md` §5.6 Formel 3 (Dangling-Check) ließ Out-of-Bundle-`..`-Traversale still passieren — `[x](../../README.md)` aus einem Area-Concept erzeugte **keine** Ausgabe (der `-f`-Existenztest löste `wiki//../../README.md` zur existierenden Workspace-`README.md` auf); Kontainment war nur Prosa („Ziel muss unter `wiki/` liegen", „kein Stiller Vorbeilass"), nie durch eine Prüfung erzwungen. (A2) Formel 4 (Kontakt-mit-`raw/`-Baseline) extrahierte aus dem veralteten Story-2.3-`7e1f449…` (Ergebnis `30`), während die Formel-Prosa `66451b6` + Basename-Filter + „dieser Run: 30" beanspruchte und die Ist-Zählung `38` beträgt — ein Producer, der den wörtlichen Selbsttest ausführt, erhält `38 ≠ 30` = FAIL ohne Auflösung. (B1) Das Label `AREA_WITHOUT_INDEX` ist **inventiert** — es existiert in keinem Validator-Output; die reale Meldung ist `FAIL … Punkt 11: Index-Regel verletzt (Area ohne index.md=…)`. **Geändert:** (a) Code Map präzisiert, dass Formel 3 Out-of-Bundle-Ausbruch sperren MUSS (aufgelöster Ziel-Pfad bleibt unter `wiki/`, sonst `DANGLING`); (b) Formel-4-Extraktion auf den `baseline_commit`-Kopf dieser Spezifikation (`66451b6…`) fixiert; (c) `AREA_WITHOUT_INDEX` durch die wörtliche Punkt-11-Meldung ersetzt (Code Map/Tasks/Verification). **Vermeidet den bekannten-bösen Zustand:** (A1) ein Consumer-Renderer kann `../../README.md` nicht auflösen → stiller Verstoß gegen das Renderer-konforme Link-Auflösungsmodell der Story; (A2) re-executierbarer Selbsttest (AD-17h) schlägt auf dem neuen Baum fehl; (B1) Instruktions-Text behauptet eine Validator-Meldung, die der Validator nicht emittiert (Falsch-Attribution auf den Validator). **KEEP (positive Erhaltung, muss die Re-Derivation überleben):** neue Area `wissensarchitektur/` (frontmatterlose `index.md` + `source-material.md`, `type: concept`, `sources` s1=architecture-spine + s2=prd, §5.5-Inline-Verweise, `../`-Links mit Kontext-Marker); bestehende Root-Concepts + Root-`index.md`-Links byte-identisch (kein MOVE, AD-7d); §5.7-Routing-Prinzip ((a) bestehender `index.md`-Link → Bereich / (b) Default Root; neue Areas nur konsolidiert; kein neues Prädikat; kein MOVE); file-relatives Auflösungsmodell; Formel-Berichtigungen oben; die Story-2.4-`deferred-work.md`-Einträge (file-relativ umgesetzt, Basename-Filter). **Kein Schema-/Validator-/raw-Change (AD-3); keine neue §7-Klasse; keine Vertragsänderung. ## Design Notes **File-relatives Auflösungsmodell (statt bundleroot-relativ):** Bei Root-Dateien sind file-relativ und bundleroot-relativ identisch (alle 8 bestehenden Bestands-Links bleiben byte-identisch — Null-Delta zum Story-2.3-Pin). In Areas unterscheiden sie sich: `wissensarchitektur/trennung-states.md → llm-wiki-prinzip.md` ist bundleroot-relativ `llm-wiki-prinzip.md` (im Renderer falsch), file-relativ `../llm-wiki-prinzip.md` (im Renderer korrekt). File-relativ erfüllt die zwei Story-2.3-Pin-Rationale (Standard-Tools lösen ohne Konventionswissen auf, FR-10/AD-8) und ist der einzige beide-Ebenen-taugliche Modus; es bleibt **eine syntaktische Form** (relativer Pfad + `.md`-Endung), damit die AD-7b-„zwei-Producer-Eine-ID"-Eigenschaft erhalten bleibt. Die §5.6-`../`-Exklusion war fürs flache Bundle korrekt (jedes `../` war einst außerhalb); mit Areas wird sie zur in-Bundle-Aufwärts-Auflösung. `../schema/` bleibt als andere Schicht exkludiert — Abgrenzung über das Zielverzeichnis (unter `wiki/` = in-Bundle) statt über das bloße `../`-Präfix. **Warum kein MOVE bestehender Concepts in der Demo:** Neuzuordnung/Umbenennung existierender Concepts ist semantische Kuratierung mit AD-7d-Redirect-Pflicht — Epic-3-Nähe, nicht in den Story-2.4-ACs (die nur _neue_ Einheiten zuordnen). Die Demo erzeugt deshalb ein neues Area-Concept + Area-Index; die Routing-/Hold-/Normalisierungs-ACs sind vollständig durch den Sandbox-Negativ-Test und den realen Erzeugungspfad belegt. ## Verification **Commands (re-executierbar, ab Workspace-Root):** 1. **§5.6-Formel 1/2/3 (area-fest)** — erwartet: Bestands-Check zeigt den neuen Bestand (inkl. `wissensarchitektur/source-material.md` und `../`-Ziele); Form-Check Ausgabe `0`, Exit `0`; Dangling-Check keine Ausgabe: - `sh -c "grep -roE '\]\([^)]*\)' --include='*.md' --exclude=log.md wiki/"` - Formel 3 (Dangling-Check, nach Story-2.4-`../`-Schärfung, byte-identisch in §5.6 gespiegelt — Rev-2.0-Konvention; Loop-2: quellenbasierte `../schema/*`-Exklusion, Decision 2): - `sh -c 'grep -roE "]\([^)]*\)" --include="*.md" --exclude=log.md wiki/ | sed -E "s#^([^:]+):\]\(([^)]*)\)\$#\1|\2#" | sort -u | while IFS="|" read -r src t; do case "$t" in ""|*:*|raw/*|./*|/*) if [ "$t" = "" ]; then echo "DANGLING: (leeres Ziel)"; fi; continue;; esac; case "$t" in "#"*) continue;; esac; case "$t" in "../schema/"*) if [ "$(dirname "$src")" = "wiki" ]; then continue; fi;; esac; p=${t%%#*}; f="/$(dirname "$src")/$p"; while printf "%s" "$f" | grep -qE "/[^/]+/\.\.(/|$)"; do f=$(printf "%s" "$f" | sed -E "s#/[^/]+/\.\.(/|$)#/#g"); done; f=${f#/}; case "$f" in wiki/*) [ -f "$f" ] || echo "DANGLING: $t";; *) echo "DANGLING: $t";; esac; done' - **Out-of-Bundle-Escape-Negativkontrolle (Loop-1-Review-Fix):** In einer Sandbox-/tmp-Kopie des `wiki/`-Baums, die auch die Workspace-`README.md` bzw. `schema/compiler.md` außerhalb von `wiki/` enthält, MUSS Formel 3 ein Body-Ziel `[x](../../README.md)` bzw. `[x](../../schema/compiler.md)` aus einem Area-Concept **als `DANGLING: …` melden** (Existenztest reicht nicht — `-f` löst `wiki//../../README.md` zu einer existierenden Out-of-Bundle-Datei auf und würde still passieren). Die Formel MUSS stattdessen sperren: aufgelöster Ziel-Pfad nach `..`-Auflösung muss unter `wiki/` bleiben. 2. **Determinismus-Show (Routing):** Negativ-Test Sandbox-`/tmp/…/wiki`: Kandidat mit ID `llm-wiki-prinzip` → §3.2-Hold-Meldung, keine Datei/kein Link; `wiki/foo/` ohne `index.md` → wörtliche Punkt-11-Ausgabe `FAIL … Punkt 11: Index-Regel verletzt (Area ohne index.md=foo)` (kein inventiertes `AREA_WITHOUT_INDEX`). 3. **§5.6-Formel 4 (Re-Baseline für Zuwachs-Runs, Loop-2-Decision 1):** aktuelle Vorkommen-Zählung `(raw/` (log.md-exkludiert) mit Extraktion aus dem **Kopf des letzten Zuwachs-Runs** (dieser Run: `862cf410c624072833cd959da9a2fb26235716f6`, beide Zählungen = **38**) re-executieren — die Extraktions-Formel im §5.6-Text trägt den Run-Kopf-Commit, nicht den Story-2.3-`7e1f449…` und nicht den `baseline_commit`-Wert der Spec-Frontmatter (`66451b6…` = Zustand **vor** dem Zuwachs, extrahiert `30`; bleibt als Referenz dieses Runs im Log); bei jedem weiteren Datei-Zuwachs ist die Baseline-Extraktion erneut auf den dann aktuellen Run-Kopf durchzuführen (Wieder-Baseline-Klausel §5.6 Pkt. 3, Formel (4)). 4. **Validator-Lauf:** alle 7 `wiki/`-Dateien SUCCESS (Bundleroot `index.md`, `log.md`, 3 Root-Concepts, Area-`index.md`, Area-Concept; Punkte 1/2/6/7/8/9/10/11/12/13/14, EC-1) — incl. Area-`index.md` frontmatterlos (Punkt 10) und Area-Concept verlinkt im nächsten Vorfahren (Punkt 11). Die „6 `wiki/`-Dateien" der gefrorenen I/O-Matrix bleiben frozen (Defizitzählung; Defer in `deferred-work.md`). **Manual checks:** - §7-Story-2.4-Bullet als „in §5.7 verankert" statt „verbleibt"; kein Schema-/Validator-/raw-Diff; `log.md`-Eintrag datiert (2026-08-18), Vertrag-§5-Format, dokumentiert den `sprint-status`-Wechsel und die Formel-4-Neu-Baseline; `deferred-work.md`-Einträge geschlossen/korrigiert (append-only); `sprint-status.yaml` konsistent. ## Suggested Review Order **Story 2.4 — deterministische Bereichszuordnung & Concept-Hierarchie (Loop 0 → Loop-1-Findings A1/A2/B1).** Review-Reihenfolge nach Belang, beginnend beim Design-Einstieg. **Design-Einstieg — die neue Routing-Regel** - §5.7 ist der einzige Instruktions-Ort (D-3); von hier versteht man den gesamten Change: (a) bestehender `index.md`-Link → Bereich, (b) Default Root, neue Areas nur konsolidiert, kein MOVE (AD-7c/A0-10/AD-13). [`compiler.md:178`](../../schema/compiler.md#L178) - Routing-Regel im Detail — textual-deterministische Bereiche, nie Embedding (Pkt. 1). [`compiler.md:182`](../../schema/compiler.md#L182) - Top-Level-Kollisions-Hold → fixierter §3.2, kein neues Prädikat, kein MOVE (Pkt. 3, A0-10). [`compiler.md:196`](../../schema/compiler.md#L196) **Link-Auflösungsmodell & die Loop-1-Fixes** - File-relatives Auflösungsmodell inkl. Out-of-Bundle-`..`-Containment — der Kern der Story; löst das §5.6-Defer (Pkt. 4; Root byte-identisch). [`compiler.md:198`](../../schema/compiler.md#L198) - Dangling-Check (Formel 3): Quell-Datei-Spur + `..`-Kollabierung + `wiki/*`-Containment — Loop-1-**A1-Fix** (Out-of-Bundle-Escape → `DANGLING`). [`compiler.md:154`](../../schema/compiler.md#L154) - Negativ-Beispiel 2 (Escape): `[x](../../README.md)` wird als `DANGLING` gesperrt statt still passiert (Loop-1-A1-Nachweis). [`compiler.md:174`](../../schema/compiler.md#L174) - Kontakt-mit-`raw/`-Baseline (Formel 4): Extraktion aus `66451b6…` (`baseline_commit` dieser Spec) + Basename-Filter — Loop-1-**A2-Fix** (nicht mehr der alte `7e1f449…`). [`compiler.md:163`](../../schema/compiler.md#L163) **Area-Hierarchie & Index** - Area-`index.md`-Regel: frontmatterlos (Punkt 10), Punkt-11-Meldung wörtlich (`Area ohne index.md=`) — Loop-1-**B1-Fix** (kein inventiertes `AREA_WITHOUT_INDEX`). [`compiler.md:199`](../../schema/compiler.md#L199) - Worked Example: `source-material.md` — `type: concept`, `sources` s1/s2, `../`-Links, gepinnte Verlinkung in der Area-`index.md`. [`compiler.md:200`](../../schema/compiler.md#L200) **Bundle-Instanz (Demo-Area)** - Frontmatterlose Area-`index.md` verlinkt das Area-Concept (Punkt 10/11 konform, §5.7-Hierarchie). [`wissensarchitektur/index.md:1`](../../wiki/wissensarchitektur/index.md#L1) - Bereichs-Concept mit §5.5-Inline-Verweisen + `../`-Body-Links auf Root-Concepts (AD-7a/A0-8). [`wissensarchitektur/source-material.md:1`](../../wiki/wissensarchitektur/source-material.md#L1) - Bundleroot: neue Area-Sektion verlinkt `wissensarchitektur/index.md` (Navigation Root → Area, AD-9). [`index.md:35`](../../wiki/index.md#L35) **Nachweis & Logistik** - Spec-Änderung nach Loop 1 (Code Map/Verification präzisiert: Containment-Pflicht, `66451b6`-Baseline, wörtliche Punkt-11-Meldung). [`spec …:48`](../../_bmad-output/implementation-artifacts/spec-2-4-deterministische-bereichszuordnung-concept-hierarchie.md#L48) - Spec Change Log: Loop-1-Eintrag (Auslöser, Geändert, vermiedener Zustand, KEEP). [`spec …:75`](../../_bmad-output/implementation-artifacts/spec-2-4-deterministische-bereichszuordnung-concept-hierarchie.md#L75) - `log.md`-Eintrag 2026-08-18: Formel-4-Re-Baseline (`38`), Statuswechsel, gültige Punkt-11-Wortwahl, `sprint-status`-Wechsel. [`wiki/log.md:3`](../../wiki/log.md#L3) - `sprint-status.yaml`: `2-4-…` → `review` (review-loopiterierte Story, bereit zur Review-Freigabe). [`sprint-status.yaml:49`](../../_bmad-output/implementation-artifacts/sprint-status.yaml#L49) ## Review Findings (bmad-code-review, 2026-08-18 — Loop 2, 4 Layer) ### Decision-Needed (resolved 2026-08-18, Nutzer-Entscheidung) - [x] [Review][Decision] Formel 4 (Kontakt-mit-`raw/`) ist auf dem ausgelieferten Baum per eigener Vorgabe nicht passierbar (38 ≠ 30) — `schema/compiler.md` §5.6 Pkt. 3, Formel (4) hält an „erwartet: aktuell ≡ Baseline" und „Beide Vorkommen-Zählungen **müssen** übereinstimmen" fest, während derselbe Absatz die Ist-Zahl `38` und die aus `66451b6` extrahierte Baseline `30` benennt; ein Producer, der den AD-17h-Selbsttest wörtlich re-executiert, erhält deterministisch `38 ≠ 30` = Run-FAIL nach NFR-4 — exakt der von Loop-1-A2 als bekannt-bös klassifizierte Zustand. `wiki/log.md` rahmt „38 ≠ 30" als „kein Fehlalarm: Zuwachs-Re-Baseline", die Logik sagt also OK, die Formel FAIL; der neue Referenzwert 38 existiert nur als Prosa, nicht in extrahierbarer Form. Re-Execution bestätigt: Ist=38, Baseline(`66451b6`)=30, Extraktion aus Run-Kopf `862cf41`=38. — **Aufgelöst (Nutzer, Option 1):** Re-Baseline auf den Run-Kopf `862cf41` (Extraktion = 38) pinnen; Erwartungstext „Ist ≡ Extraktion aus dem Baseline-Commit des letzten Zuwachs-Runs"; `66451b6`/30 bleibt als Dokumentation dieses Runs im Log. → Patch (unten). - [x] [Review][Decision] `../schema/*`-Exklusion in Formel 3/2 ist zielbasiert, nicht quellbasiert — die Prosa (compiler.md `:174`, `:198`, Negativ-Beispiel 2) beschränkt die Exklusion auf „einstufiges `../schema/*` **aus Root-Dateien**", die Formel (`:154` `case "$t" in …|../schema/*) continue`) exkludiert aber unabhängig von der Quelle. Sandbox-verifiziert: `[z](../schema/compiler.md)` aus `wiki/wissensarchitektur/source-material.md` → Auflösung `wiki/schema/compiler.md` (unter `wiki/`, existiert nicht) → Formel-Ausgabe **leer**, Exit 0. Stiller Vorbeilass der einstufigen in-Bundle-Form aus Areas (NFR-4), während der Out-of-Bundle-Escape (`../../…`) korrekt gesperrt wird. — **Aufgelöst (Nutzer, Option 1):** Formel quellenbasiert schärfen — `../schema/*` wird nur exkludiert, wenn die Quell-Datei `wiki/index.md` ist; aus anderen Quellen läuft das Ziel durch Auflösung + Containment + `-f`-Test (→ `DANGLING` bei Nichtexistenz). Prosa bleibt, Formel folgt der Prosa. → Patch (unten). - [x] [Review][Decision] Routing-Regel §5.7 Pkt. 1(a) ist bei mehreren passenden `index.md`-Links nicht deterministisch — „inhaltlich deckungsgleichen Eintrag" trägt kein textuelles Prädikat; bei Mehrfachtreffern (real im Ist-Bundle: Bundleroot verlinkt Root-Concept `wissensarchitektur-trennung-states.md`, die Area `wissensarchitektur/` denselben Themenraum) ist unklar, welcher Link den Bereich vorgibt; AD-7c/A0-10 verlangen textual-deterministische Zuordnung. — **Aufgelöst (Nutzer, Option 1):** Deterministisches Treffer-Prädikat + Tie-Break in Pkt. 1(a) verankern: Treffer = Identitäts-Identität des Link-Ziels ≡ kanonischer Name des Themas (kein „inhaltlich deckungsgleich"-Urteil, AD-13); Mehrfachtreffer → Bundleroot-Links vor Area-Links, dann lexicografische Pfad-Reihenfolge. → Patch (unten). ### Patch - [x] [Review][Patch] Negativ-Test-Nachweis fehlt in `wiki/log.md` — Code Map verspricht „Negativ-Test-Hold-Nachweis", Task 5 ist `[x]`, aber der 2026-08-18-Log-Eintrag enthält keine Hold-Meldung, keine wörtliche Punkt-11-`Area-ohne-index.md`-Ausgabe, keinen `DANGLING`-Nachweis und keinen Sandbox-Pfad; Execution-Nachweis der I/O-Matrix-Zeilen (TOP_LEVEL_COLLISION, AREA_WITHOUT_INDEX, DIVING_NON_EXISTENT) fehlt im Artefakt [wiki/log.md:4] - [x] [Review][Patch] Veraltete „bundle-relativ"-Passagen widersprechen dem neuen file-relativen Pin — `schema/compiler.md:62` (§5.3 Pkt. 3: „file-relativ bundle-relativ mit `.md-Endung" — Oxymoron), `:241` (§6.6-Zelle: „bundlerelativ"), `:254` (§7-Bullet: „bundle-relativ mit `.md-Endung"`) wurden nicht auf file-relativ nachgeführt; für Area-Links faktisch falsch, widerspricht §5.6 Pkt. 1/§5.7 Pkt. 4 [schema/compiler.md:62,241,254] - [x] [Review][Patch] Log/YAML/Spec-Status-Divergenz: `sprint-status.yaml` zeigt `review`, der Log-Eintrag dokumentiert nur `backlog → in-progress` („dieser Statuswechsel findet mit diesem Eintrag statt") — die Transition `in-progress → review` (Review-Handoff) ist protokolldokumentarisch nicht abgebildet; die gefrorene Vorgabe („→ `in-progress`") und die Spec-SRO („→ `review`") sind intern spaltig [wiki/log.md:4, sprint-status.yaml:49] - [x] [Review][Patch] Spec-Verification „6 `wiki/`-Dateien" vs. Log „7 Dateien" + falsche Punkt-9-Begründung — Spec-Verification (`:96`) erwartet „6 `wiki/`-Dateien, Punkte 1/6/8/9/10/11/14"; der Log dokumentiert 7 Dateien (inkl. `log.md`) mit dem Punkt-Satz 1/2/6/7/8/9/10/11/12/13/14 und begründet die Differenz fälschlich mit „Punkt 9/10" (Punkt 9 = `okf_version`/`type: bundle`-Verbot außerhalb der Bundleroot, nicht log.md-Validierung). Die gefrorene I/O-Matrix („6 `wiki/`-Dateien") selbst bleibt angefasst (→ Defer) [wiki/log.md:4, spec:96] - [x] [Review][Patch] Spec-Verification spiegelt die neue Formel 3 nicht byte-identisch — Rev-2.0-Konvention („5/5 Formel-Strings identisch compiler↔spec") bricht: die Verification listet nur den Formel-1-String; der neue Formel-3-String (Quell-Datei-Spur, `..`-Kollabierung, Containment, compiler.md `:154`) fehlt als re-executierbarer Spiegel in der Spec [spec-2-4-….md:124-127] - [x] [Review][Patch] §7-Scope-Einleitung veraltet — „Diese Instruktion ist auf die Erzeugung neuer Concepts auf Root-Ebene begrenzt" (`:249`) widerspricht dem eigenen Bullet direkt darunter, das die Area-Anlage in §5.7 verankert; Scope-Satz auf „Root-Ebene und Areas gemäß §5.7" nachführen [schema/compiler.md:249] - [x] [Review][Patch] Typos/Orthografie in normativen Texten — `schema/compiler.md:166` + `wiki/log.md:4`: „akte-Baseline" (→ „aktuelle Baseline"); `compiler.md:241`: doppeltes Leerzeichen „(bundlerelativ , `.md`-Endung)"; (frozen-Spec „stillem Overwrite" → Defer) [schema/compiler.md:166,241] - [x] [Review][Patch] Ambiguität „Kopf dieser Spezifikation" — Formel 4/Rev-2.1-Log bezeichnen `66451b6` als „Kopf dieser Spezifikation"; gemeint ist der deklarierte `baseline_commit`-Wert der Spec-Frontmatter (Eltern-Commit, nicht der Story-2.4-Branch-Kopf) — Referenz auf den deklarierten Wert umstellen [schema/compiler.md:159,163,283] - [x] [Review][Patch] Area-`index.md`-Prosa überzeichnet den Area-Inhalt — `wiki/wissensarchitektur/index.md:3` verspricht „die Link-Form und die progressive Discovery" als gebündelte Themen; existiert genau ein Area-Concept (`source-material.md`), zur Link-Form/Discovery kein Concept (Story 2.5) [wiki/wissensarchitektur/index.md:3] - [x] [Review][Patch] `sprint-status.yaml last_updated` ohne Zeitanteil — `08-18-2026` bricht das etablierte Feld-Format `MM-DD-YYYY HH:MM` (bisher `08-17-2026 15:40`) [sprint-status.yaml:32] - [x] [Review][Patch] Drei „Story-2.4-Kandidat"-Defer-Einträge bleiben offen, ohne Status-Nachführung — `deferred-work.md:219` (`)`-blinde Ziel-Extraktion), `:223` (Cross-Page-Anker), `:249` (Multi-Line-Ziele) nennen Story 2.4 als Home; die Story ist abgeschlossen ohne Umsetzung und ohne Weiterleitung — Home-Angaben auf nächste Runde (z. B. Story 2.5/fokussierte Instruktionsrunde) umstellen [deferred-work.md:219,223,249] - [x] [Review][Patch] (aus Decision 1) Formel-4-Re-Baseline auf Run-Kopf — `schema/compiler.md` §5.6 Pkt. 3, Formel (4): Extraktions-Commit von `66451b6` auf `862cf41` (Run-Kopf, Extraktion = 38) umstellen, Erwartungstext auf „Ist ≡ Extraktion aus dem Baseline-Commit des letzten Zuwachs-Runs"; `66451b6`/30 bleibt als Dokumentation dieses Zuwachs-Runs im Log; `wiki/log.md`-Eintrag um die neue Runnable-Baseline (38 ≡ 38 aus `862cf41`) nachführen [schema/compiler.md:159-166, wiki/log.md:4] - [x] [Review][Patch] (aus Decision 2) Formel 3 quellenbasierte `../schema/*`-Exklusion — `schema/compiler.md` §5.6 Pkt. 3, Formel (3): `case "$t" in "#"*|../schema/*)` um Quell-Bedingung schärfen (Exklusion nur, wenn `src` = `wiki/index.md`); aus anderen Quellen läuft das Ziel durch die bestehende Auflösung + Containment + `-f`-Test; Prosa/§5.7 Pkt. 4/Negativ-Beispiel 2 bleiben (sie sind jetzt konsistent); Sandbox-Negativnachweis (in-Bundle-`../schema/x.md` aus Area → `DANGLING`) im Patch-Vergleich verifizieren [schema/compiler.md:154] - [x] [Review][Patch] (aus Decision 3) §5.7 Pkt. 1(a) Treffer-Prädikat + Tie-Break — `schema/compiler.md` §5.7 Pkt. 1(a): „auf das erkannte Thema bzw. einen inhaltlich deckungsgleichen Eintrag" ersetzen durch textuelles Prädikat (Identität des Link-Ziels ≡ kanonischer Name des neuen Themas) und Mehrfachtreffer-Regel (Bundleroot-Links vor Area-Links, dann lexicografische Pfad-Reihenfolge); AD-7c/A0-10/AD-13-Referenzen bleiben [schema/compiler.md:183] ### Defer - [x] [Review][Defer] Spec-Frontmatter `status: 'done'` bei offenem Review — Präzedenz spec-2-3: `done` erst nach Review-Freigabe; der Status wird mit diesem Review-Loop abgeschlossen synchron (Step-6-Regel), kein separates Patch [spec-2-4-….md:5] - [x] [Review][Defer] Gefrorene I/O-Matrix „6 `wiki/`-Dateien" + „stillem Overwrite" — frozen-after-approval-Sektion, nur per Renegotiation änderbar; wird mit der Loop-2-Spec-Amendierung (Decision-Resolution) nachgeführt [spec-2-4-….md:74-76] - [x] [Review][Defer] ID-Kollision Area-`index.md` vs. Root-Concept (`wiki//index.md` und `wiki/.md` → beide Identität ``) — der §3.2-Hold feuert nur auf Datei-Kollision; eine Identitätskollision ohne Dateikollision ist undefiniert. Fix erfordert §3.2-Erweiterung/Vertragsänderung (AD-3 read-only, „kein neues Prädikat") — Home: nächste autorisierte Validator-/Vertragsrevision [schema/compiler.md:190-197] - [x] [Review][Defer] Spec-These „Validator Punkt 11 akzeptiert bereits Areas" nicht vom read-only-Validator-Text gedeckt — Punkt 11 verlangt die Identität „als relativer Bundle-Pfad referenziert"; die Area-`index.md` verlinkt file-relativ `source-material.md`, die Bundle-Identität `wissensarchitektur/source-material` erscheint textuell nicht → ein wörtlicher Punkt-11-Check ist auf dem Demo-Concept nicht deterministisch entscheidbar; SUCCESS-Nachweis der Log nicht unabhängig überprüfbar. Fix = autorisierte Validator-Revision (AD-3) — Home: Rev-9-Aktionsitem [validator.md:70, wiki/wissensarchitektur/index.md:9]