Files
wow20/_bmad-output/implementation-artifacts/spec-3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-rip.md
T

36 KiB
Raw Blame History

title, type, created, status, review_loop_iteration, baseline_commit, context
title type created status review_loop_iteration baseline_commit context
Relevanzbestimmung textual-deterministisch umsetzen (grep/ripgrep + Markdown-Traversal + Link-Following) (Story 3.2) feature 2026-08-19 done 3 e3e7ec346d
_bmad-output/implementation-artifacts/epic-3-context.md

Intent

Problem: Die Compiler-Instruktion (schema/compiler.md §3 Pkt. 2, Revision 2.4.2) erhebt die Update-Kandidatenliste bisher über einen platzgehaltenen <konzeptterm> („die Term-Auswahl folgt der §2-Interpretation"), dessen Ableitung (Kanonisierung, Synonyme, Mehrfach-Terme je Einheit) explizit „Story 3.2 vorbehalten" ist (compiler.md:41; §7 :319). Damit ist die Relevanzbestimmung nicht vollständig deterministisch vorgegeben (AD-17h/A0-19): dieselbe Evidenz kann je nach Term-Wahl unterschiedliche Candidate-Listen erzeugen — ein Embedding-freier, textuell-deterministischer Mechanismus fehlt (PRD OQ-3, AD-13, A0-18).

Approach: Story 3.2 löst die beiden Story-3.2-Vorbehalte auf und verankert in schema/compiler.md (D-3, rein textuell — kein Code, kein Standalone) den feinkörnigen, textuell-deterministischen Relevanz-Findungsmechanismus als verbindliche Ausformulierung der §3-Pkt.-2-Kandidatenerhebung: (a) Term-Ziehverfahren — die Candidate-Terme werden deterministisch aus der neuen Evidenz abgeleitet (bedeutungstragende Token-Folgen nach §2-Interpretation, durchgängige Normalisierung: lowercasing, [-_ ]-Bindestrich-Varianten, ein kanonischer Schreibweisen-Resolver, mehrere Terme je Einheit erlaubt); (b) Term-übergreifende Erhebung über wiki/ — grep/ripgrep, index.md-Traversal, Link-Following (dreistufig, mündet in die nachvollziehbare Candidate-Liste als relative OKF-Pfade ohne .md); (c) Determinismus-Vertrag — gleicher Git-State + gleiche Eingabemenge → gleiche Candidate-Liste in gleicher Reihenfolge (AD-17h/A0-19). Damit werden die Story-3.2-Vorbehalte in §3 Pkt. 2 und §7 aufgehoben. Vertrag (schema/wiki-compiler.md), Validator (schema/validator.md) und raw/ bleiben read-only (AD-3); keine neue §7-Invaliditätsklasse.

Boundaries & Constraints

Always:

  • Story 3.2 ist eine Instruktions-Story (D-3). Der Relevanz-Findungsmechanismus wird ausschließlich in schema/compiler.md als deterministische Text-Instruktion verankert. Kein ausführbares Programm, kein Standalone, keine neue §7-Invaliditätsklasse, kein Change an schema/wiki-compiler.md / schema/validator.md / raw/ (AD-3).
  • Determinismus (Kern, AD-17h/A0-19): Die Relevanzbestimmung ist deterministisch: gleicher Git-State + gleiche Eingabemenge → identische Candidate-Liste, in identischer Reihenfolge (Zuwachs-Sicht-Ordnung; lexikografisch als deterministischer Tie-Break bei identischem Ort). Damit ist sie als nachvollziehbare Candidate-Liste (Concept-Pfade) verfügbar — deterministisch statt probabilistisch (AC-3).
  • Ausschließlich textuelle Mittel (AD-13, AC-1/AC-4, No-Goals): Die Erhebung nutzt ausschließlich grep/ripgrep über wiki/, Markdown-Traversal von index.md und Link-Following (§5.6-Pin). Kein Einsatz von Embeddings, Vektor-Suche oder Knowledge-Graph-Datenbank im Compiler-Kern.
  • Kein Leasing-/Dirty-Tree-Scope in 3.2: Leasing, Dirty-Tree, Staleness, Merge-Kollisionen bleiben Story 3.5/3.6; Commit-Boundary = Mutations-Boundary-Regel (AD-17f) und die Story-3.1-Bausteine (§5.9 Diff-Selbsttest, R-1/P2-Check-Block, INPUT_UNCOMMITTED-Abbruch, Update-Routing) bleiben unverändert — Story 3.2 ändert nur die Erhebungs-Mechanik der Candidate-Liste, nicht die Mutationspfade.
  • sprint-status.yaml: Key 3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-ripin-progress.

Ask First: Einführung nicht-textueller Mittel (Embeddings/Vector/KG) im Compiler-Kern (verboten durch AD-13, nur per Autorisierung änderbar) · Änderung der §5.6-Linkform (verboten durch A0-9) · AD-7d-Renames/Redirects · Validator-/Vertrags-/raw/-Change · Änderung der Commit-Boundary-Regel.

Never: Änderungen an schema/wiki-compiler.md/schema/validator.md/raw/ (AD-3) · neue §7-Invaliditätsklasse · Standalone-Programm/Validator (D-3) · Embedding/Vector-Suche/KG im Compiler-Kern (AD-13, No-Goals) · Duplikat-Anlage eines bestehenden Concept-Pfads · „Regenerate Everything" (AD-5, A0-6).

I/O & Edge-Case Matrix

Scenario Input / State Expected Output / Behavior Error Handling
TERM_ABLEITUNG_SINGLETON Neue Evidenz raw/… mit genau einem markanten Fachbegriff (z. B. quanten-protocol-schlüssel) Term-Ziehverfahren ergibt genau diesen Begriff; grep-Erhebung über wiki/ findet genau die Concept-Pfade mit diesem Term N/A
TERM_ABLEITUNG_SYNONYM Evidenz nennt einen Begriff in einer Schreibweise-Variante (z. B. quanten protocol vs. canonisch quanten-protocol) Kanonisierungs-Resolver normalisiert auf die canonische Schreibweise; Erhebung findet die Concept-Pfade der canonischen Form keine canonische Auflösung → Term wird wie notiert verwendet (kein stiller Ausschluss)
TERM_ABLEITUNG_MEHRFACH Evidenz enthält mehrere bedeutungstragende Terme Candidate-Liste = Vereinigung der Treffer über alle Terme; Vereinheitlichung über besuchte Menge (ein Pfad nur einmal) N/A
TRAVERSAL_REACH_ONLY Ein Konzeptterm trifft nur wiki/index.md (oder Area-index.md), nicht Concept-Bodies index.md-Traversal (Root → Area → Concept, §5.8) liefert die darunter gewurzelten Concept-Pfade als Treffer fehlende Bundleroot → Run-FAIL (V-1, besteht fort)
LINK_FOLLOWING_ZYKLUS Concept-Links bilden einen Zyklus (A → B → A) Link-Following mit besuchter Menge (aus Story 3.1): jeder Pfad nur einmal — keine Endlos-Schleife, endliche Candidate-Liste N/A
NO_MATCH Neuer Term trifft kein bestehendes Concept (keine Überschneidung) Leere Candidate-Liste → UNTOUCHED_CONCEPT (Story-3.1-Pfad): keine Mutation, kein log.md-Zusatz leere Menge ist Teilmenge jeder erlaubten Menge (Ghost-Diff-negativ)

Code Map

  • schema/compiler.mdprimär mutiert (D-3, einziger Instruktions-Ort):
    • §3 Reconcile Pkt. 2 (:41): Story-3.2-Vorbehalt auflösen — der feinkörnige Term-/Relevanz-Mechanismus wird eingearbeitet (Term-Ziehverfahren, Kanonisierungs-Resolver, drei Erhebungs-Stufen grep/ripgrep + Traversal + Link-Following, Candidate-Liste als relative OKF-Pfade ohne .md, Determinismus-Beschreibung); verortet als neue Sektion §3.2 „Relevanzbestimmung (Story 3.2)" direkt nach §3 — Kern-Anker bleibt Pkt. 2 („Erhebung nach §3.2").
    • §7 Selbstbegrenzung (:319): Story-3.2-Vorbehalt entfernen („Feinkörnige Relevanz-Verfeinerung" entlassen) — verbleibende 3.x-Themen: Synthese → 3.4, Leasing/Dirty-Tree → 3.5/3.6.
    • §8 Revisionslog (:350352): Revision 2.5 (Story 3.2) + 2.6 (Step-04-Loop-2-Patch-Runde) — Normreferenzen AD-13/A0-18/OQ-3 ergänzen (AD-17h steht bereits; A0-19 wird ebenfalls ergänzt — war im Ist-§8 noch nicht gelistet; auch A0-19 als Determinismus-Referenz); Abschlussklausel (kein Vertrag-/Validator-/raw/-Change, keine neue §7-Klasse, kein Standalone). Rev 2.6 trägt zusätzlich die Loop-2-Patches (§4-Überschrift, rg-tool-korrekte Formen).
    • §5.9 Pkt. 6 / P2-Check-Block: die Candidate-Erhebung über einen Zeiger (nicht Duplizieren) an den neuen §3.2-Mechanismus binden — einschl. --exclude=log.md (analog §5.6/§5.8-Formel), die Candidate-Liste ist auf Concept-Pfade definiert.
    • Resolver-Materialisierung: der kanonische Schreibweisen-Resolver wird als canonical-terms.md unter schema/compiler.md nebengeordnet (neues Artefakt, gleiche read-only-Hierarchie): committete, append-only Registry (canonische Form + erlaubte Schreibvarianten + []), als §3.2-Ziel referenziert. Damit ist der Resolver Bestandteil des Git-States und der Determinismus (gleicher Git-State → gleiche Liste) pinbar. (Kein schema/-Root-Change; Einbindung als normierte Referenz im §8.)
    • §1 Pkt. 1/4, §5.6, §5.7, §5.8 — read-only / nur Referenz (Linkform, Bereichszuordnung, Discovery bleiben unverändert).
  • wiki/log.mdappend (append-only, Vertrag §5: bestehende Bullets — Story-3.1-done unter 2026-08-19, Validierungs-Rev-9, Story 2.5… — bleiben unverändert erhalten; der Story-3.2-Eintrag wird als weitere Bullet ergänzt, nicht ersetzt): Relevanzbestimmung-Semantik, Determinismus-Selbsttest-Beleg (Membership + Identität; der --exclude=log.md-Fakt aus der Stufe (a) wird ehrlich dokumentiert — A0-18 trifft nur noch wiki/knowledge-kompilation-inkrementell.md, nicht log.md), Statuswechsel 3-2-… backlog → in-progress, per-Datei-Validator-Verdikt-Zeile (Ist-Baum SUCCESS), einzeilige Nennung des 3.1-epic-3-context.md-Defer-Handoffs.
  • _bmad-output/implementation-artifacts/deferred-work.mdmutiert (append-only): 3.1-Defer-Eintrag epic-3-context.md (:335, „Home: Story 3.2-Handoff oder Sprint-Sync") als aufgegriffen markieren; der F17-Handoff-Eintrag („Split 2026-08-19, Home: Story 3.8") ist bereits eingetragen. Bestehende Einträge nicht verändern, nur Status-Ergänzung im append-only-Stil.
  • _bmad-output/implementation-artifacts/sprint-status.yamlmutiert: Key 3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-rip (:55) → in-progress.
  • schema/validator.md, schema/wiki-compiler.md, raw/…read-only (AD-3). Story 3.2 mutiert selbst keine Concept-Inhalte; Demonstration per Sandbox-Durchlauf (Muster: _bmad-output/implementation-artifacts/sandbox-3-1/run-sandbox.sh, S1S6) oder als textueller Selbsttest gegen den Ist-Baum (z. B. rg -l-Erhebung mit realem Term, ohne Inhalts-Mutation).

Tasks & Acceptance

Execution:

  • schema/compiler.md — Story-3.2-Vorbehalte auflösen (§3 Pkt. 2 + §7): §3.2-Relevanzbestimmung als verbindliche dreistufige Erhebungs-Mechanik (Term-Ziehverfahren + Kanonisierungs-Resolver; log.md-Exklusion — rg -g '!log.md' bzw. grep --exclude=log.md — über wiki/; index.md-Traversal; Link-Following mit besuchter Menge; Candidate-Liste als relative OKF-Pfade ohne .md; Determinismus-Vertrag AD-17h/A0-19 mit Reihenfolge auch für Stufe-b/c und Normalisierung in §3.2 selbst); canonical-terms.md (Resolver-Registry: canon. Form + Varianten, append-only); §8-Revision 2.5 + Normreferenzen AD-13/A0-18/A0-19/PRD-OQ-3; Abschlussklausel. Kein Vertrag-/Validator-/raw/-Change. (Inkl. Rev-2.6-Patch-Runde aus Step-04-Review Loop 2: §4-Überschrift wiederhergestellt, rg-tool-korrekte Formen, Mini-Sandbox verankert — s. Spec Change Log.)
  • wiki/log.md — Story-3.2-Eintrag (Vertrag §5-Format, append-only — bestehende Bullets unverändert) mit Relevanzbestimmung-Semantik, Determinismus-Selbsttest-Beleg (Membership + Identität via log.md-Exklusion), Statuswechsel, Validator-Verdikt, epic-3-context-Defer-Nennung. (Loop-2-Patch-Note (Rev 2.6) als eigene oberste Log-Zeile ergänzt.)
  • deferred-work.md — epic-3-context-Eintrag als aufgegriffen markieren (append-only); sprint-status.yaml — Key 3-2-…in-progress. (Zusätzlich Em-Dash-Determinismus-Frage als neuer Defer (Home: Story 3.8) aus Loop 2.)
  • Edge-Tests (Sandbox, I/O-Matrix + Membership-Pin): TERM_ABLEITUNG_SINGLETON/SYNONYM/MEHRFACH, TRAVERSAL_REACH_ONLY, LINK_FOLLOWING_ZYKLUS, NO_MATCH — inkl. mini-Sandbox-Baum, der einen realen Term auf Concept-Bodies und log.md verteilt und die exakte Candidate-Liste (nur Concept-Pfade, log.md ausgeschlossen) als erwartete Ausgabe pindet. (Sandbox T1T4 re-executiert: alpha exklusiv, Zwei-Run-Identität, NO_MATCH leer, alpha+gamma Vereinigung.)

Acceptance Criteria:

  • Given eine neue committete Source, when ein Run die Relevanzbestimmung ausführt, then nutzt er ausschließlich textuelle, deterministische Verfahren — Term-übergreifende grep/ripgrep über wiki/, Markdown-Traversal von index.md, Link-Following (AC-1; AD-13, A0-18) — als verbindliche Ausformulierung der §3-Pkt.-2-Erhebung; die Story-3.2-Vorbehalte (§3 Pkt. 2, §7) sind aufgehoben.
  • Given gleicher Git-State + gleiche Eingabemenge, when zwei unabhängige Runs die Relevanzbestimmung ausführen, then erzeugen sie dieselbe Candidate-Liste in derselben Reihenfolge (AC-2; AD-17h, A0-19) — ohne Embedding/Vector/KG im Compiler-Kern (AC-4; AD-13).
  • Given ein Ergebnis der Relevanzbestimmung, when es weiterverarbeitet wird, then ist es als nachvollziehbare Candidate-Liste (relative OKF Concept-Pfade ohne .md) verfügbar (AC-3).
  • Given die Instruktion, when geprüft, then bleibt schema/validator.md/schema/wiki-compiler.md/raw/ unverändert (AD-3), keine neue §7-Klasse, kein Standalone (D-3) — Validator läuft auf dem Ist-Bundle SUCCESS.

Review Findings

bmad-code-review Loop 3 (2026-08-19, 4 Layer: blind-hunter / edge-case-hunter / verification-gap / acceptance-auditor; Diff e3e7ec3 → 3aa484b, branch story-3-2). Triage: 5 decision-needed, 2 patch, 4 defer (→ deferred-work.md), 39 dismissed als Noise (u. a. doppelte Layer-Quellen pro Finding; last_updated-Zeitstempel = Story-3.1-Loop-2-Präzedenz; deferred-work.md-Bestands-Eintrag-in-Platz-Edit = vom frozen-Task-3-Defer-Handoff selbst befohlen; Em-Dash-Lücke bereits korrekt defer an Story 3.8; sprint-status-Key-Kürzung = Projekt-Schema; Sandbox-/tmp-Reste + git add -A;-Semikolon = Story-3.1-Sandbox-Muster-Präzedenz; F17-Home-„mit Story 3.2" = vorbestehend (Story-3.1-Review); rg-Verfügbarkeit im Audit-Environment = Audit-Beschränkung, keine Story-Lücke; §5.6-Scan-Scope-Konvention-Anker ist real (compiler.md:157); Formel-4-Ist-Zählung 38 re-executiert = 38; „Validator 7 wiki/-Dateien" = korrekt, ls wiki/ liefert 6 Einträge = 7 .md-Dateien (Area-Verz. zählt nicht); canonical-terms.md-Zwei-[]-Lesarten sind durch die Eröffnungs-Zeile + den Hinweis explizit aufgelöst; A0-19-Ergänzung in §8 = spec Change Log B5 als KEEP verankert).

  • [Review][Decision] Status-Flip backlog → done gegen gefrorene Always-Klausel (→ in-progress) — keine dokumentierte Renegotiation [sprint-status.yaml:55] — Option 1 umgesetzt: done bestätigt; Statuskette in-progress → done als eigener dokumentierter Schritt in wiki/log.md (neue oberste Bullet, Loop-3/Rev-2.7-Zeile)
    • Befund: Der gefrorene Boundaries & Constraints-Abschnitt (Always) verlangt sprint-status.yaml-Key → in-progress; der Commit setzt direkt done. Die nicht-gefrorene Spec-Tail (Manual checks) sagt zwar „backlog → in-progress → done", aber (a) der Zwischenschritt in-progress ist in keinem wiki/log.md-Eintrag als eigener dokumentierter Statuswechsel belegt (Rev-2.5-Log zitiert backlog → in-progress, Rev-2.6 zitiert keinen done-Flip), (b) der Review-Workflow-Skript-Sync (bmad-build sprint status + Story 3.1-Präzedenz: Review-Abschluss setzt done im selben Loop) legt nahe, dass done der intendierte Endzustand ist. Entweder wurde die Always-Klausel stillschweigend superseded (nicht dokumentiert) oder der Key ist falsch.
    • Optionen: 1 (empfohlen)done bestätigt (Sprint-Sync-Konvention: Review-Loop-Abschluss setzt done); in den Rev-2.6-Log-Zeile den Statusflip in-progress → done als dokumentierten Schritt ergänzen (Lückenschluss der Statuskette, keine Status-Änderung). 2 — Key auf in-progress zurücknehmen; Story bleibt in-progress bis ein späterer Run den done-Flip belegt.
  • [Review][Decision] Sandbox deckt I/O-Matrix-Szenarien LINK_FOLLOWING_ZYKLUS, TRAVERSAL_REACH_ONLY, TERM_ABLEITUNG_SYNONYM nicht ab — Task-4-Checkbox [x] überdeklariert [run-sandbox.sh:1-142] — Option 1 umgesetzt: T5/T6/T7 ergänzt, T2-Kommentar korrigiert, re-executiert (alle 7 Tests PASS, exit 0); Beleg in wiki/log.md (Loop-3-Zeile)
    • Befund: run-sandbox.sh implementiert T1 (Membership), T2 (Zwei-Run-Identität), T3 (NO_MATCH), T4 (Vereinigung). LINK_FOLLOWING_ZYKLUS hat keinen Test (der Sandbox-Baum enthält keine Concept-Links — die besuchte Menge wird nie geübt); TRAVERSAL_REACH_ONLY ist nur Nebenprodukt von T2 (Term alpha trifft index.md; als Kommentar, nicht als gepinntes Szenario — und die gepinnte Ausgabe index+alpha widerspricht der §3.2-3b-Ordnungs-Semantik, weil Stufe-b-Treffer nach Stufe-a-Treffern positioniert sind und index kein Concept-Pfad ist); TERM_ABLEITUNG_SYNONYM ist ungetestet (leere Registry → der Fallback „wie notiert" ist der Standardfall, aber die Kanonisierung selbst wird nie geübt). Die Execution-Task-4-Checkbox [x] und Spec-Verification Pkt. 3 deklariert die volle I/O-Matrix-Abdeckung.
    • Optionen: 1 (empfohlen) — Sandbox um T5 (LINK_FOLLOWING_ZYKLUS: A→B→A-Links, erwartete endliche, doppelungsfreie Liste), T6 (TRAVERSAL_REACH_ONLY: Term nur in index.md, erwartete gewurzelte Concept-Pfade) und T7 (TERM_ABLEITUNG_SYNONYM: Registry-Eintrag mit Variante → Auflösung auf canonische Form) erweitern; T2-Kommentar zu index korrigieren; dann re-executieren und den Beleg nachführen. 2 — nur die fehlenden Szenarien als deferred-work.md-Eintrag an die nächste Compiler-Instruktions-Revision (oder Story 3.8, die den Determinismus-Vertrag absichert) übergeben; Task-4-Checkbox-Notiz ehrlich nachführen. 3 — T6/T7 als Defer, T5 (besuchte Menge) als Patch jetzt (weil §3.2-2c die Endlichkeits-Garantie trägt).
  • [Review][Decision] wiki/log.md-Selbsttest-Beleg (b) beschreibt einen Sandbox-Baum, der nicht dem committierten run-sandbox.sh entspricht (Term quanten-protocol, sub/beta.md, SHA-256 159092bb…) — Stale-Verifikations-Falle (exakt B1 aus Loop 2) [wiki/log.md:5] — Option 1 umgesetzt: Beleg (b) gegen die echte Sandbox-Ausgabe neu belegt (neue Log-Zeile, append-only); Rev-2.5-Zeile bleibt historisch
    • Befund: Der Rev-2.5-Log-Eintrag (b) behauptet: Term quanten-protocol auf wiki/alpha.md, wiki/sub/beta.md, log.md; Candidate-Liste alpha, sub/beta; Zwei-Run-Identität via SHA-256 159092bb…. Das committierte, re-executierbare run-sandbox.sh trägt durchgängig den Term deterministische-relevanz-bestimmung, keinen sub/-Baum (Beta ist root-level beta.md) und keine SHA-256-Berechnung. Der „re-executierte" Nachweis ist damit nicht aus dem verankerten Artefakt reproduzierbar — dieselbe Stale-Evidenz-Falle, die Story 3.2 (Loop-2-B1) gerade schließen sollte.
    • Optionen: 1 (empfohlen) — Log-Beleg (b) gegen die echte run-sandbox.sh-Ausgabe re-executiert neu belegen (Term/Pfade/Ergebnisse an den Script-Ist-Baum angleichen); historischer Rev-2.5-Zeile eine Korrektur-Fußnote als neue Log-Zeile anhängen (append-only-Vertrag §5 erlaubt neue Zeilen, nicht Edit — die Rev-2.5-Zelle bleibt historisch, die neue Zeile korrigiert). 2 — die Sandbox auf den log.md-belegten Baum (Term quanten-protocol, sub/-Area) ändern und neu ausführen (weicht vom bereits in Rev-2.6 referenzierten Script ab).
  • [Review][Decision] §3.2-Pkt.-3b-Ordnung: „Reihenfolge des ziehenden Terms" ist undefiniert für Mehrfach-Terme — AD-17h-Zwei-Run-Identität hängt an einer nicht fixierten Term-Ordnung [schema/compiler.md:60] — Option 1 umgesetzt: Pkt. 3b auf reine Lexikografie (LC_ALL=C) gehoben; Term-Auftritt nur für Verarbeitungsreihenfolge (Rev-2.7)
    • Befund: Pkt. 3b ordnet Stufe-a-Treffer „in der Reihenfolge des ziehenden Terms, dann lexikografisch als deterministischer Tie-Break bei identischem Ort", während Pkt. 1c mehrere Terme je Einheit erlaubt. Die Reihenfolge der Terme selbst (Auftreten in der Evidenz? lexikografisch? §2-Interpretations-Reihenfolge?) ist nirgends festgelegt — zwei rechtmäßige Term-Ordnungen erzeugen zwei rechtmäßige, aber unterschiedliche Listen. Zusätzlich ist die Formulierung intern doppelt definiert („Reihenfolge des ziehenden Terms" vs. „innerhalb jeder Stufe lexikografisch aufsteigend").
    • Optionen: 1 (empfohlen) — Pkt. 3b auf eine eindeutige Regel heben: Stufe-a-Treffer rein lexikografisch (LC_ALL=C), Term-Auftritt dient nur der Verarbeitungs-/Interpretations-Reihenfolge, nicht der Listen-Ordnung (einfachste deterministische Form, kompatibel mit der „lexikografisch als Tie-Break"-Klausel). 2 — Term-Ordnung = lexikografisch über die gezogenen Terme, Stufe-a-Treffer in Term-Ordnung, dann lexikografisch (bewahrt die „Zuwachs-Sicht"-Semantik, ist etwas komplexer zu implementieren und zu beweisen).
  • [Review][Decision] canonical-terms.md-Registry-Lookup-Semantik ist unvollständig — Doppelbelegung von Varianten ist nicht deterministisch auflösbar, Lookup-Reihenfolge (vor/nach Kollaps, Groß/Klein) ist offen [schema/canonical-terms.md:25-35] — Option 1 umgesetzt: Lookup-Reihenfolge fixiert (normalisierte Form) + Eindeutigkeits-Invariante + Konflikt-Verfahren (Rev-2.7)
    • Befund: (a) Zwei Einträge können dieselbe Schreibvariante mit unterschiedlichen canonischen Formen tragen — der Registry-Format-Abschnitt definiert keine Eindeutigkeits-Regel (kein „Variante in genau einem Eintrag", kein Konflikt-Verfahren; der „Append-only"-Regel-Abschnitt behandelt nur Umbenennungen). (b) Die Normalisierungs-Reihenfolge ist offen: lowercasing + [-_ ]-Kollaps vor dem Registry-Lookup? Lookup auf der rohen Variante? Die Varianten-Spalte ist als „bündel-findend per --Kollaps, lowercased" beschrieben, aber die verbindliche Lookup-Operation steht nicht da. Genau das ist der Kern des deterministischen Resolvers (AD-17h).
    • Optionen: 1 (empfohlen) — in canonical-terms.md Registry-Format ergänzen: (i) Lookup-Reihenfolge fixiert (lowercase → Kollaps → Lookup auf der normalisierten Form; die Varianten-Spalte trägt ebenfalls normalisierte Formen), (ii) Eindeutigkeits-Invariante „eine Variante in genau einem Eintrag" + Konflikt-Fall (Append nicht erlaubt; deferred-work.md-Handoff / Ask-First analog zur bestehenden Umbenennungs-Regel). 2 — nur (ii) ergänzen; (i) als defer an die nächste Registry-Befüllung (erstes Entry).
  • [Review][Patch] run-sandbox.sh: T1 (Membership-Pin) und T4 (Vereinigung) werden nur ausgegeben, nie als Pass/Fail geprüft — das gepinnte „exakte Candidate-Liste"-Verhalten (Task 4) wird nicht erzwungen [run-sandbox.sh:80-113, 136-141] — umgesetzt: T1/T4 tragen harte Asssertionen (exit 1 bei Abweichung)
    • Befund: T1 gibt die Candidate-Liste und „Erwartet: AUSSCHLIESSLICH 'alpha'" aus, vergleicht aber nie; T4 gibt alpha, gamma (gesortet) aus, prüft aber nicht gegen die Erwartung. Ein Regressions-Fall (z. B. log oder index rutscht in die Liste, oder gamma fehlt) beendet das Skript mit Exit 0 und „Sandbox abgeschlossen (alle 4 Tests)". T3 (NO_MATCH) und T2 (Zwei-Run-Identität) haben dagegen echte if-Checks mit exit 1.
    • Fix: T1 out=$(terms 'deterministische-relevanz-bestimmung' | normalize); [ "$out" = "alpha" ] || { echo "FAIL: …" >&2; exit 1; }; T4 out=$(terms '…' | normalize | LC_ALL=C sort | paste -sd, -); [ "$out" = "alpha,gamma" ] || { echo "FAIL: …" >&2; exit 1; }.
  • [Review][Patch] Typos/Fehlzeichnungen im committeten normativen Text — Determinsmus (×4+ in compiler.md/log.md/deferred-work.md/Spec), §3.2-beankert (soll „§3.2-angeankert" sein), Membrum (soll „Mitglied" sein), Konventionelle Determinismus-Lücke (soll „Bekannte Determinismus-Lücke" sein — verweist auf compiler.md:53, wo es „Bekannte" heißt) [schema/compiler.md:351,373; wiki/log.md:5; deferred-work.md:342; spec:80,93,106] — umgesetzt (reiner Text-Patch; raw/-Source-Typo und der präexistierende außschließlich-Typo im 3.1-Log bleiben unberührt — out-of-scope)
    • Befund: Keine AC-Auswirkung, aber der Text ist die committete Instruktion/der committete Nachweis. Determinsmus steht auch in der Source raw/epics/ (3×), die Instruktion sollte den Begriff aber konsistent korrekt verwenden, wie es der Rest des Dokuments tut. Resovierung (spec:80,106) ist zusätzlich zu Resolution/Auflösung zu korrigieren.
    • Fix: orthografische Korrektur in den genannten Zeilen (reiner Text-Patch, keine Semantik-Änderung).
  • [Review][Defer] §3.2-Pkt.-2a: Wortgrenzen-/Frontmatter-Scope der Stufe-a-Match-Semantik ist offen (Substring-Match ohne \b, Frontmatter-Treffer zählen mit) [schema/compiler.md:55] — deferred, pre-existing
  • [Review][Defer] §3.2-Pkt.-1b-ii: Kollaps bei aufeinanderfolgenden/führenden/trailenden Separatoren ist unbestimmt (a--b, -x) [schema/compiler.md:51] — deferred, pre-existing
  • [Review][Defer] Stufe-a-Treffer auf index.md-Pfade (z. B. T2 index) werden nicht deterministisch aus der finalen Candidate-Liste entfernt (Stufe-b-Re-Routing implizit, nicht fixiert) [schema/compiler.md:55-56] — deferred, pre-existing
  • [Review][Defer] Rev-2.5-/Rev-2.6-Log-Zeile und compiler.md-Revisionslog: Nachweis-Klärigungen ohne Semantik-Auswirkung — (a) Rev-2.5-Log-Zelle zitiert die (nun historisch korrigierte) rg --exclude-Form im aktiven Mechanismus-Teil, ohne eigene Inline-Korrektur (Rev-2.6-Zelle erklärt es nur), (b) last_updated: 08-19-2026 07:10 liegt vor dem Commit-Zeitpunkt (09:16), (c) Rev-2.6 steht im Revisionslog über Rev-2.5 (chronologisch umgekehrt), (d) Validator-„7/7 SUCCESS" als Aggregat ohne per-Datei-Liste, (e) Rev-2.6-git status-Beleg listet canonical-terms.md/_bmad-output/-Änderungen nicht (nämte „git status" als Prüfgrundlage), (f) Formel-4-Ist-Zählung 38 ohne Baseline--Partner (re-executiert: Ist = 38, korrekt; nur der Beleg-String ist unvollständig) [wiki/log.md:4-5; schema/compiler.md:372-373; sprint-status.yaml:32] — deferred, pre-existing

Spec Change Log

  • 2026-08-19 (bmad-code-review Loop 3 — Review-Findings umgesetzt; 5 Decisions (alle Option 1) + 2 Patches + 4 Defers): schema/compiler.mdRevision 2.7: (1) D-4 — §3.2-Pkt.-3b-Ordnung auf reine Lexikografie (LC_ALL=C) gehoben; die Term-Verarbeitungsreihenfolge bestimmt nur die Interpretation/Erhebung, nicht die Listen-Ordnung (dieselbe Treffermenge → identische Liste, AD-17h/A0-19); (2) D-5schema/canonical-terms.md: Lookup-Verfahren deterministisch fixiert (lowercasing → [-_ ]--Kollaps → Lookup der normalisierten Form; Spalten tragen ausschließlich normalisierte Formen) + Eindeutigkeits-Invariante (jede normalisierte Form in genau einem Eintrag — Canon oder Variante, nie beides/zweimal) + Konflikt-Verfahren (keine stille Anhängung; deferred-work.md/Ask-First, analog zur Umbenennungs-Regel); (3) D-1 — Statuskette in-progress → done als eigener dokumentierter Schritt in wiki/log.md (Sprint-Sync-Konvention; Story-3.1-Präzedenz); Key bleibt done; (4) D-2 + P-1run-sandbox.sh um T5 LINK_FOLLOWING_ZYKLUS (A↔B-Zyklus; besuchte Menge → endlich/doppelungsfrei), T6 TRAVERSAL_REACH_ONLY (Term nur in Area-index.md → gewurzelte Concept-Pfade), T7 TERM_ABLEITUNG_SYNONYM (Registry-Test-Doppel; beide Lookup-Pfade + Negativ-Fall) erweitert; T1/T4 mit harten Asssertionen; T2-Kommentar korrigiert; re-executiert: alle 7 Tests PASS, exit 0; (5) D-3wiki/log.md-Selbsttest-Beleg (b) gegen die echte run-sandbox.sh-Ausgabe neu belegt (neue Log-Zeile, append-only; Rev-2.5-Zeile historisch unverändert); (6) P-2 — Typos korrigiert (DeterminsmusDeterminismus, beankertangeankert, MembrumMitglied, KonventionelleBekannte, ResovierungAuflösung; raw/-Source und der präexistierende 3.1-Log-Typo bleiben unberührt). 4 Defers (Wortgrenzen-/Frontmatter-Scope; Separator-Kollaps-Reichweite; Stufe-a-index.md-Treffer aus finaler Liste; Rev-2.5/2.6-Beleg-Klärigungs-Bündel) in deferred-work.md (append-only, Sektion „Deferred from: code review of spec-3-2-… (2026-08-19)"). Keine AC-Änderung, kein frozen-Schnittstellen-Change, kein Validator-/Vertrags-/raw/-Change (AD-3), keine neue §7-Klasse, kein Standalone (D-3). Frontmatter: status: 'done', review_loop_iteration: 3. sprint-status.yaml: Key 3-2-… bleibt done, last_updated → 08-19-2026.
  • 2026-08-19 (bmad-code-review Loop 2 — bad_spec-Loopback): 5 bad_spec-Findings ausgelöst, Code-Änderungen auf Baseline revertiert, nicht-gefrorene Spec-Tail-Sektionen geamendet:
    • B1/VG-1 log.md-Kontamination: rg -l '<term>' wiki/ ohne --exclude=log.mdlog.md wird ab dem Moment selbst „Kandidat", in dem ein Log-Eintrag den Term zitiert; der Determinismus-Selbsttest verankert das A0-18-1-File-Find in einem Commit, das selbst A0-18 enthält (Stale-Evidenz; Reproduzierbarkeits-Claim widerlegt sich selbst). Bekannt-bös: permanente Drift + falsches Verification-Expect.
    • B2 Reihenfolge: rg -l-Ausgabe-Reihenfolge (FS-Traversal) nicht auf Zuwachs-Sicht-Ordnung abbildbar; Stufe-b/c ohne definierte Position. Bekannt-bös: AC-2-Zwei-Run-Identität nur bei undokumentiertem rg-Tie-Break.
    • B3 Resolver nicht enumeriert: „eine canonische Form je Semantik" ohne committete Registry → Determinismus nicht pinbar. Bekannt-bös: gleiche Liste nur, wenn Resolver Teil des Git-States (nicht spezifiziert).
    • B4 Em/En-Dash: Klassenliteral [-_ ] deckt nur En-, nicht Em-; Kollaps-Reichweite inkonsistent. Bekannt-bös: Em-Varianten fallen nicht unter den Kollaps (Synonymlücke). Gewählter Weg: --Kollaps bleibt; explizite -Auflösung wird als offene Determinismus-Lücke in Step-4-Defer an Story 3.8 übergeben (nicht stillschweigend hinzugefügt).
    • B5 §8-A0-19-Claim: Spec sagte „A0-19 steht bereits in §8", war im Ist-Baum nicht kommutiert; Implementierung ergänzte A0-19 (korrekt). Spec korrigiert, A0-19-Ergänzung als KEEP verankert (fehlleiten bei Re-Baseline verhindern).
    • B6 NO_MATCH / §5.9-P2-Block-Scope: werkt zusammen → zusammengefasst; in B1 und Task-Patch-Membership-Pin überführt.
    • B7 §5.9-P2-Block-Zeiger: nicht mehr nötig — die fixierte Stufe (a) --exclude=log.md macht den Zeiger redundant (kein log.md-Kandidat mehr); verworfen (keine unnötige Pflicht).
    • KEEP-Instruktionen (müssen Neu-Ableitung überleben): neue §3.2-Sektion nach §3 etc.; alle 6 I/O-Matrix-Szenarien; Determinismus-Vertrag (identische Reihenfolge, KEEP: nur-Parallel = deterministisch-MECHANISMUS, NICHT zufällig); --exclude=log.md-Stufe-a; Determinismus-Selbsttest MIT Membership-Pin (Zwei-Run-Identität + Mengen-Genauigkeit) und canonical-terms.md-Resolver as Resolver im Git-State; Wiki/log.md als append-only (Story-3.1-Bullet bleibt eigenständig stehen); die A0-19/Schema-Referenz ergänzen. NOT-KEEP: Spec-A0-19-Formulierung „steht bereits" (korrigiert).
    • Restliche patch- und defer-Findings (B6/NO_MATCH, B5/Doppel, Log-Selbsttest-Beleggenaue, F17+Em-Morphologie-Story-3.8) werden in der Step-4-Patch-Runde umgesetzt bzw. in deferred-work.md nachbestätigt.

Design Notes

Warum §3.2 als eigene Sektion statt Streckung in Pkt. 2: §3 ist heute eine nummerierte Liste (Pkt. 13); der Story-3.2-Vorbehalt sitzt IN Pkt. 2. Die feinkörnige Mechanik (Term-Ziehverfahren, Kanonisierungs-Resolver, dreistufige Erhebung, Determinismus) ist zu umfangreich, um Pkt. 2 verständlich zu halten. Design-Entscheidung: neue Sektion §3.2 „Relevanzbestimmung (Story 3.2)" direkt nach §3 — Pkt. 2 bleibt der Kern-Anker („Erhebung nach §3.2"), die Komplexität wird ausgelagert, bestehende §5.9-Pkt.-6-Bindungen bleiben gültig. Nur falls der §3-Aufbau eine andere Einfüge-Stelle nahelegt (z. B. Pkt. 2a), wird das Label angepasst — Pkt. 2 bleibt in jedem Fall der verbindliche Einstieg.

Term-Ziehverfahren — was deterministisch heißt: Die Ziehung ist deterministisch, weil sie allein von der committeten Evidenz-Datei abhängt: (1) bedeutungstragende Fachbegriffe = Token-Folgen mit fachlicher Signifikanz, aus der §2-Interpretation benannt (nicht freie LLM-Auswahl); (2) Normalisierung über einen canonischen Schreibweisen-Resolver (lowercasing; [-_ ]-; eine canonische Form je Semantik); (3) mehrere Terme je Einheit erlaubt — Candidate-Liste = Vereinigung der Treffer über alle Terme, bereinigt über besuchte Menge; (4) kein stiller Ausschluss: nicht auflösbare Varianten werden wie notiert verwendet. Die Erhebung mit festem Term war schon in Rev-2.4.2 deterministisch — Story 3.2 macht zusätzlich die Term-Auswahl deterministisch (exakt der bisherige Vorbehalt).

Determinismus-Referenz: AD-17h und A0-19 sind bereits Normreferenzen in §8 Revision 2.4 (Story 3.1); Story 3.2 ergänzt AD-13, A0-18 und PRD OQ-3 (Architekturfrage „Compilation Scope"). A0-19 war im Ist-§8 (Baseline e3e7ec3) zwar nicht gelistet — die Implementierung fügt es als Determinismus-Referenz der Relevanzbestimmung hinzu (kein Verstoß, Design-KEEP: A0-19-Anker wird in §8 und §3.2 gesetzt; die frühere Spec-Formulierung „steht bereits" war falsch und ist hiermit korrigiert). wiki/knowledge-kompilation-inkrementell.md:48 referenziert A0-18/AD-13 bereits; zur Erhebung wird wiki/log.md ausgeschlossen (--exclude=log.md, §5.6-Muster) — sonst wäre der eigene log.md-Eintrag bei jedem Term, den er zitiert, selbst „Kandidat" (A0-18/FR-12-Fall; die Candidate-Liste ist auf Concept-Pfade definiert, §5.9 Pkt. 5 behandelt log.md gesondert als erlaubtes Mitglied).

Determinismus-Selbsttest (Membership + Identität): Der Selbsttest prüft nicht nur Zwei-Run-Identität, sondern zusätzlich, dass die Ausgabe Mengen-Genauigkeit hat (nur Concept-Pfade, log.md ausgeschlossen) — er wird gegen einen mini-Sandbox-Baum ausgeführt, der einen realen Term auf Concept-Bodies und log.md verteilt und die exakte Candidate-Liste als erwartete Ausgabe pindet. Damit ist die Stale-Verifikations-Falle („das Artefakt widerlegt sich selbst") geschlossen.

Verification

Commands (re-executierbar, ab Workspace-Root):

  1. Vorbehalts-Auflösung: grep -n "Story 3.2 vorbehalten" schema/compiler.md liefert keinen Treffer mehr (beide Vorbehalte aufgehoben: §3 Pkt. 2 + §7).
  2. Neue Sektion: grep -n "Relevanzbestimmung\|3.2" schema/compiler.md liefert die neue §3.2-Sektion; §7-Vorbehalt enthält „3.2" nicht mehr; §8 trägt Revision 2.5 + 2.6 (Patch-Runde: §4-Kopf, rg-tool-korrekte Formen).
  3. Determinismus-Selbsttest (Membership + Identität):
    • rg -l '<term>' -g '!log.md' wiki/ (rgs native Glob-Exklusionsform; --exclude ist kein rg-Flag — das GNU-grep-Äquivalent ist grep -rl '<term>' --exclude=log.md wiki/) zweimal ausführen, Ausgaben identisch — deterministische Erhebung ohne log.md-Kontamination; z. B. rg -l 'A0-18' -g '!log.md' wiki/ → genau wiki/knowledge-kompilation-inkrementell.md (ein Concept-Pfad, log.md ausgeschlossen); rg -l 'A0-18' wiki/ ohne Exklusion hingegeben würde wiki/log.md mit-treffen (Selbstkontamination — genau der ausgeschlossene Fall).
    • mini-Sandbox-Baum (_bmad-output/implementation-artifacts/sandbox-3-2/, re-executierbar via bash run-sandbox.sh — Term auf Concept-Bodies und log.md verteilt): exakte Candidate-Liste (nur Concept-Pfade) wie erwartet; Normalisierung Strip wiki/ + .md → relative OKF-Pfade; zwei aufeinanderfolgende Läufe liefern byte-identische Ausgaben (Zwei-Run-Identität, AD-17h).
  4. Validator-Lauf: alle wiki/-Dateien SUCCESS (unverändert; reine Text-Instruktion, human-mechanisch ausgeführt, D-3) — per-Datei-Verdikt als Ausführungs-Nachweis im log.md-Eintrag.
  5. Resolver-Materialisierung: schema/canonical-terms.md existiert (committete, append-only Registry: canon. Form + erlaubte Varianten); grep -n "canonical-terms" schema/compiler.md liefert die §3.2-Referenz.
    (Optionale Em-Dash-Prüfung: die Normalisierungs-Klasse deckt - ab; explizite -Varianten-Auflösung ist eine erkannte Determinismus-Lücke → Story 3.8, s. Spec Change Log.)

Manual checks:

  • §3 Pkt. 2 zeigt auf die neue §3.2-Mechanik; Term-Ziehverfahren + Kanonisierungs-Resolver textuell benannt; Candidate-Liste als relative OKF-Pfade ohne .md; Determinismus-Vertrag in der Instruktion; compiler.md §8-Revision 2.5 + 2.6 mit Abschlussklausel; kein schema/validator.md-/schema/wiki-compiler.md-/raw/-Diff; §7-Vorbehalt ohne „3.2"; wiki/log.md-Eintrag datiert mit Story-3.2-Semantik, Determinismus-Beleg, Statuswechsel backlog → in-progress → done (Patch-Note Rev 2.6 oben), per-Datei-Verdikt; deferred-work.md-epic-3-context-Eintrag als aufgegriffen markiert + Em-Dash-Defer (Story 3.8); sprint-status.yaml konsistent (3-2-… → done).