feat: Story 3.2 Code-Review-Loop-3-Patches (bmad-code-review, 4 Layer; Nutzer-Entscheidungen D-1/D-2/D-3/D-4/D-5 = 1/1/1/1/1 + P-1/P-2) — compiler.md Revision 2.7, §3.2-Pkt.-3b-lexikografisch, canonical-terms-Lookup-Semantik + Invariante + Konflikt-Verfahren, Sandbox T5-T7 + T1/T4-Asssertionen (7/7 PASS), Stale-Beleg (b) korrigiert, Statuskette in-progress → done, P-2-Typos, Story done
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -65,7 +65,7 @@ Noch nicht adressierte, aber real erkannte Arbeit — gesammelt aus Reviews. Ein
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/spec-1-4-schema-validierung-für-bundle-implementieren.md`
|
||||
summary: Genau-eine-erlaubte-Linkform für den Punkt-11-Index-Check festlegen (mit vs. ohne `.md`-Endung) — Story 2.3.
|
||||
evidence: Step-04-Review (Story 1.4, Loop 1): Der Validator-Punkt-11-Check akzeptiert beide Linkformen (relativer Bundle-Pfad mit oder ohne `.md`-Endung), weil die genau-eine-Form-Regel (A0-9/AD-7b) erst Story 2.3 definiert. Der Determinsmus-Anspruch des Validators bleibt gewahrt (beide Formen zählen als verlinkt); eine Endungs-Festlegung würde die abschließende §7-Liste erweitern und gehört in Story 2.3.
|
||||
evidence: Step-04-Review (Story 1.4, Loop 1): Der Validator-Punkt-11-Check akzeptiert beide Linkformen (relativer Bundle-Pfad mit oder ohne `.md`-Endung), weil die genau-eine-Form-Regel (A0-9/AD-7b) erst Story 2.3 definiert. Der Determinismus-Anspruch des Validators bleibt gewahrt (beide Formen zählen als verlinkt); eine Endungs-Festlegung würde die abschließende §7-Liste erweitern und gehört in Story 2.3.
|
||||
status: umgesetzt (2026-08-17, Story 2.3) — Linkform in `schema/compiler.md` §5.6 gepinnt (bundle-relativ **mit** `.md`-Endung; Rationale: Null-Migration der 3 Concept-Links in `wiki/index.md`, explizite Datei-Ziele, Standard-Markdown-Tools — AD-7b/A0-9/FR-10/AD-8) inkl. vier re-executierbarer Selbsttest-Formeln (AD-17h). Der Validator bleibt strukturell unverändert (Punkt 11 akzeptiert beide Schreibweisen — Story-2.2-Präzedenz, D-3); die konsistente Nachführung der „Story 2.3"-Notizen in `schema/validator.md` (Punkt 11, §8) bleibt Rev-9-Kandidat (Eintrag unten).
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/epic-1-retro-2026-08-15.md`
|
||||
@@ -81,7 +81,7 @@ Noch nicht adressierte, aber real erkannte Arbeit — gesammelt aus Reviews. Ein
|
||||
evidence: Retrospective F-04.
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/epic-1-retro-2026-08-15.md` (F-06)
|
||||
summary: `today`-Zeitzone für die `stale_after`-WARN (Validator §6.4) deterministisch festlegen — „heute in UTC abgeleitet" ist nicht hart definiert (Kalenderdatum des UTC-Zeitpunkts vs. lokaler Tag). Determinsmus-Anspruch (AD-17h) vor Epic-3 (Lifecycle-Konsequenz) sauber machen.
|
||||
summary: `today`-Zeitzone für die `stale_after`-WARN (Validator §6.4) deterministisch festlegen — „heute in UTC abgeleitet" ist nicht hart definiert (Kalenderdatum des UTC-Zeitpunkts vs. lokaler Tag). Determinismus-Anspruch (AD-17h) vor Epic-3 (Lifecycle-Konsequenz) sauber machen.
|
||||
evidence: Retrospective F-06.
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/epic-1-retro-2026-08-15.md` (F-07)
|
||||
@@ -339,6 +339,28 @@ Noch nicht adressierte, aber real erkannte Arbeit — gesammelt aus Reviews. Ein
|
||||
|
||||
- source_spec: `schema/compiler.md` §3.2-Pkt.-1b (Story 3.2)
|
||||
summary: **Em-Dash-»—«-Varianten-Lücke der Normalisierung** — die Kollaps-Klasse `[-–_ ]` (En-Dash »–«, Bindestrich »-«, Unterstrich »_«, Leerzeichen) deckt den Em-Dash »—« **nicht** ab. Eine Schreibvariante mit Em-Dash (z. B. »wissen — relevanz«, aus dem Kontext einer externen Quelle eingelesen) fällt nicht unter den Kollaps und wird nicht zu einer identischen canonischen Form normalisiert — eine erkannte Synonym-/Determinismus-Lücke der Relevanzbestimmung (A0-18/A0-19). Wird nicht stillschweigend in §3.2 ergänzt, sondern als offene Determinismus-Frage an **Story 3.8** (Determinismus-Vertrag, AD-17h) übergeben; bis dahin wird ein nicht auflösbarer Em-Dash-Term **wie notiert** verwendet (Kollaps-normalisiert, kein stiller Ausschluss).
|
||||
evidence: Story-3.2-Review-Umsetzung (2026-08-19) — §3.2-Pkt.-1b dokumentiert die Lücke explizit als »Konventionelle Determinismus-Lücke (aufgezeichnet, nicht still hinzugefügt)« und beruft sich auf diesen deferred-work-Eintrag als Handoff-Ziel.
|
||||
evidence: Story-3.2-Review-Umsetzung (2026-08-19) — §3.2-Pkt.-1b dokumentiert die Lücke explizit als »Bekannte Determinismus-Lücke (aufgezeichnet, nicht still hinzugefügt)« und beruft sich auf diesen deferred-work-Eintrag als Handoff-Ziel.
|
||||
status: offen (Home: Story 3.8)
|
||||
|
||||
## Deferred from: code review of spec-3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-rip (2026-08-19)
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/spec-3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-rip.md`
|
||||
summary: **`§3.2`-Pkt.-2a: Wortgrenzen-/Frontmatter-Scope der Stufe-a-Match-Semantik ist offen** — die Grep/rg-Erhebung matcht ohne Wortgrenze (Substring: `alpha` trifft `alphabet`) und dateiweit inkl. YAML-Frontmatter (`sources[].resource`, `generated.by` — Provenanz-/Tool-Strings können nicht-thematische Concepts als Kandidaten markieren). Keine deterministischen Lücke im Ist-Sinn (das Verhalten ist reproduzierbar), aber die Match-Semantik ist nicht fixiert; zwei Producer-Readings sind möglich. Home: nächste Compiler-Instruktions-Revision, die §3.2 ohnehin berührt (oder Story 3.8, Determinismus-Vertrag-Abgleich).
|
||||
evidence: bmad-code-review Story 3.2 (2026-08-19, Loop 3, Edge-Case-Hunter + Verification-Gap-Layer): `schema/compiler.md:55` (Stufe-a-Form ohne `\b`/Frontmatter-Klausel) vs. §3.2-Intro („Concept-Bodies").
|
||||
status: offen
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/spec-3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-rip.md`
|
||||
summary: **`§3.2`-Pkt.-1b-ii: Kollaps-Reichweite bei aufeinanderfolgenden/führenden/trailenden Separatoren unbestimmt** — „jedes Vorkommen wird in einen einzelnen Bindestrich kollabiert" ist für Läufe (`a--b`), führende (`-x`) und trailende (`x-`) Separatoren nicht eindeutig (Kollaps auf genau ein `-` + Trim? oder 1:1-Ersatz?). Bis dahin ist die Normalisierung für solche Terme nicht vollständig pinbar (AD-17h-Nähe). Home: nächste Compiler-Instruktions-Revision (mit- oder in Story 3.8 zusammen mit der Em-Dash-Lücke, s. obiger Eintrag).
|
||||
evidence: bmad-code-review Story 3.2 (2026-08-19, Loop 3, Edge-Case-Hunter-Layer): `schema/compiler.md:51` (Pkt. 1b-ii).
|
||||
status: offen
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/spec-3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-rip.md`
|
||||
summary: **Stufe-a-Treffer auf `index.md`-Pfade deterministisch aus der finalen Candidate-Liste entfernen** — Pkt. 2b definiert `index.md`-Treffer als Stufe-**b**-Trigger (gewurzelte Concept-Pfade sind die Stufe-b-Treffer), aber Pkt. 3b ordnet „Stufe-a-Treffer zuerst" ohne Fixierung, dass reine `index.md`-Stufe-a-Treffer *nicht* als Candidate (nicht-Concept-Pfad) in die finale Liste einfließen (Sandbox-T2-Ausgabe `index`+`alpha` illustriert den ungeklärten Fall; die Candidate-Liste ist per Definition auf Concept-Pfade beschränkt). Home: nächste Compiler-Instruktions-Revision, die §3.2 berührt.
|
||||
evidence: bmad-code-review Story 3.2 (2026-08-19, Loop 3, Blind-Hunter + Edge-Case-Hunter-Layer): `schema/compiler.md:55-56,60`; `_bmad-output/implementation-artifacts/sandbox-3-2/run-sandbox.sh` T2-Kommentar.
|
||||
status: offen
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/spec-3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-rip.md`
|
||||
summary: **Rev-2.5/2.6-Beleg-Klarigungen ohne Semantik-Auswirkung (Bündel)** — (a) Rev-2.5-Log-Zelle zitiert die `rg --exclude`-Form im aktiven Mechanismus-Teil ohne eigene Inline-Korrektur (Rev-2.6-Zelle erklärt sie nur — ein Producer, der nur Rev 2.5 liest, kopiert ein nicht-existentes Flag); (b) `sprint-status.yaml last_updated: 08-19-2026 07:10` liegt vor dem Story-3.2-Commit (09:16) — Zeitstempel dokumentiert nicht den Abschluss-Zeitpunkt (Story-3.1-Präzedenz: `last_updated` wird im Review-Loop-2-Commit ebenfalls nicht fortgeschrieben); (c) `compiler.md`-Revisionslog: Rev 2.6 steht über Rev 2.5 (chronologisch umgekehrt — Rev-2.6 wurde an der Einfüge-Stelle statt nach 2.5 angehängt); (d) Validator-Beleg „alle 7 `wiki/`-Dateien SUCCESS" als Aggregat ohne per-Datei-Liste (Spec-Verification Pkt. 4 verlangt „per-Datei-Verdikt als Ausführungs-Nachweis"; die Zählung 7 ist korrekt: 5 Root- + 2 Area-Concepts + log — re-executiert); (e) Rev-2.6-`git status`-Beleg listet `schema/canonical-terms.md` (neue Datei) und die `_bmad-output/`-Änderungen nicht, obwohl „`git status`" als Prüfgrundlage genannt wird; (f) Formel-4-Beleg: Ist-Zählung `38` ohne Baseline-`≡`-Partner (re-executiert: Ist = 38, korrekt — nur der Beleg-String ist unvollständig gegenüber der §5.6-Formel-4-Semantik „Ist ≡ Extraktion aus dem Baseline-Commit"). Home: nächste Log-/Nachweis-Runde (Story-3.3-Implementierungseintrag oder Story-3.2-Re-Review), keine Instruktions-Änderung nötig.
|
||||
evidence: bmad-code-review Story 3.2 (2026-08-19, Loop 3, Blind-Hunter + Verification-Gap + Acceptance-Auditor-Layer): `wiki/log.md:4-5`, `schema/compiler.md:372-373`, `_bmad-output/implementation-artifacts/sprint-status.yaml:32`; re-executierte Formel-4-Zählung (38) und `ls wiki/` (7 `.md`-Dateien) bestätigen Korrektheit der Werte.
|
||||
status: offen
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
# Story 3.2 — Sandbox-Tests der textuell-deterministischen Relevanzbestimmung (§3.2)
|
||||
# Re-executierbar: bash run-sandbox.sh (ab Workspace-Root; Sandbox unter /tmp/sb32)
|
||||
# Zweck: Membership-Pin + Zwei-Run-Identität + NO_MATCH (leere Candidate-Liste)
|
||||
# + log.md-Kontaminations-Pin (der Term liegt AUCH in log.md — die Candidate-Liste
|
||||
# bleibt trotzdem auf Concept-Pfade definiert, §3.2-Pkt.-2a).
|
||||
# Zweck: Membership-Pin (T1) + Zwei-Run-Identität (T2) + NO_MATCH (T3) +
|
||||
# log.md-Kontaminations-Pin (T1: der Term liegt AUCH in log.md — die
|
||||
# Candidate-Liste bleibt trotzdem auf Concept-Pfade definiert, §3.2-Pkt.-2a)
|
||||
# + LINK_FOLLOWING_ZYKLUS (T5) + TRAVERSAL_REACH_ONLY (T6) +
|
||||
# TERM_ABLEITUNG_SYNONYM (T7); T1/T4 mit harten Assertions (Review-Patch P-1).
|
||||
set -u
|
||||
ROOT=$(mktemp -d /tmp/sb32-XXXXXX)
|
||||
SB="$ROOT/sb"
|
||||
@@ -74,6 +76,74 @@ terms() { # $1=Term; nutzt rg wenn vorhanden (native -g-Exklusion), sonst grep -
|
||||
# Normalisierung der Ausgabe: wiki/-Präfix + .md-Suffix strippen (§3.2-Pkt.-3a)
|
||||
normalize() { sed -e 's|^wiki/||' -e 's|\.md$||'; }
|
||||
|
||||
# ---------- Helfer: Stufe b/c (Erhebung) + Terminormalisierung (Review-Loop-2, D-2) ----------
|
||||
# Stufe b — index.md-Traversal (TRAVERSAL_REACH_ONLY, §3.2-Pkt.-2b):
|
||||
# $1 = normalisierter Treffer-Name einer index.md (z. B. 'trafo/index' oder 'index');
|
||||
# gibt die darunter gewurzelten Concept-Pfade (normalisiert) aus — die Concept-Links
|
||||
# der getroffenen index.md, file-relativ aufgelöst (§5.7-Pkt.-4).
|
||||
traverse() {
|
||||
local idx="wiki/$1.md" d tgt
|
||||
d=$(dirname "$idx")
|
||||
grep -oE '\]\([^)]+\.md\)' "$SB/$idx" 2>/dev/null | sed -e 's|^\](||' -e 's|)$||' | while read -r tgt; do
|
||||
case "$tgt" in ./*) tgt=${tgt#./} ;; esac
|
||||
printf '%s/%s\n' "$d" "$tgt" | sed -e 's|^wiki/||' -e 's|\.md$||'
|
||||
done
|
||||
}
|
||||
|
||||
# Stufe c — Link-Following mit besuchter Menge (LINK_FOLLOWING_ZYKLUS, §3.2-Pkt.-2c):
|
||||
# $@ = in Stufe a getroffene Concept-Pfade (normalisiert, z. B. 'sigma');
|
||||
# Concept-Links werden file-relativ verfolgt (§5.7-Pkt.-4); ein bereits besuchter
|
||||
# Concept-Pfad wird nicht erneut besucht — Zyklen (A -> B -> A) enden, die
|
||||
# Candidate-Liste bleibt endlich. Ausgabe: getroffene + erreichte Pfade,
|
||||
# in Besuchsreihenfolge (Stufe a zuerst, dann Stufe c; §3.2-Pkt.-3b).
|
||||
follow() {
|
||||
local visited="$ROOT/visited.$$" seed f base tgt res
|
||||
: > "$visited"
|
||||
local queue=()
|
||||
for seed in "$@"; do
|
||||
printf '%s\n' "$seed" >> "$visited"
|
||||
queue+=("$seed")
|
||||
done
|
||||
while [ "${#queue[@]}" -gt 0 ]; do
|
||||
f="wiki/${queue[0]}.md"
|
||||
queue=("${queue[@]:1}")
|
||||
base=$(dirname "$f")
|
||||
for tgt in $(grep -oE '\]\([^)]+\.md\)' "$SB/$f" 2>/dev/null | sed -e 's|^\](||' -e 's|)$||'); do
|
||||
case "$tgt" in ./*) tgt=${tgt#./} ;; esac
|
||||
res=$(printf '%s/%s\n' "$base" "$tgt" | sed -e 's|^wiki/||' -e 's|\.md$||')
|
||||
grep -qx "$res" "$visited" && continue
|
||||
printf '%s\n' "$res" >> "$visited"
|
||||
queue+=("$res")
|
||||
done
|
||||
done
|
||||
cat "$visited"
|
||||
}
|
||||
|
||||
# Terminormalisierung (§3.2-Pkt.-1b): (i) lowercasing; (ii) Binde-Varianten-Kollaps
|
||||
# [-–_ ] -> - (jedes Vorkommen wird in einen einzelnen Bindestrich kollabiert).
|
||||
# Normalisierte Form = die Form, die in der Registry gespeichert/verglichen wird.
|
||||
norm_term() { printf '%s' "$1" | LC_ALL=C tr 'A-Z' 'a-z' | sed -e 's/[-–_ ]/-/g'; }
|
||||
|
||||
# Registry-Lookup (§3.2-Pkt.-1b, canonical-terms.md-Format):
|
||||
# $1 = normalisierter Term, $2 = Registry-Datei; gibt die canonische Form aus,
|
||||
# oder — nicht auflösbar — den Term selbst (§3.2-Pkt.-1b: kein stiller Ausschluss).
|
||||
lookup() {
|
||||
awk -F'|' -v t="$1" '
|
||||
NR > 2 {
|
||||
canon = $2; gsub(/^[ \t]+|[ \t]+$/, "", canon)
|
||||
if (canon ~ /^—/) next
|
||||
if (canon == t) { print canon; found = 1; exit }
|
||||
vars = $3; gsub(/`/, " ", vars)
|
||||
n = split(vars, a, ",")
|
||||
for (i = 1; i <= n; i++) {
|
||||
gsub(/^[ \t]+|[ \t]+$/, "", a[i])
|
||||
if (a[i] != "" && a[i] == t) { print canon; found = 1; exit }
|
||||
}
|
||||
}
|
||||
END { if (!found) print t }
|
||||
' "$2"
|
||||
}
|
||||
|
||||
# =====================================================================
|
||||
runlabel() { echo; echo "########## $1 ##########"; }
|
||||
|
||||
@@ -81,6 +151,13 @@ runlabel "T1: Membership-Pin — Term trifft Concept-Body UND log.md; Candidate-
|
||||
echo "--- Kandidaten-Erhebung: terms 'deterministische-relevanz-bestimmung' (Exklusions-Form) ---"
|
||||
terms 'deterministische-relevanz-bestimmung' | normalize
|
||||
echo "--- Erwartet: AUSSCHLIESSLICH 'alpha' (Concept-Pfad, ohne wiki/ + ohne .md) ---"
|
||||
T1_OUT=$(terms 'deterministische-relevanz-bestimmung' | normalize)
|
||||
if [ "$T1_OUT" = "alpha" ]; then
|
||||
echo "RESULT: PASS (Candidate-Liste = [alpha]; log.md strukturell exkludiert, §3.2-Pkt.-2a)"
|
||||
else
|
||||
echo "FAIL: T1 — erwartet 'alpha', erhalten: '${T1_OUT}'" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "--- Kontaminations-Kontrolle: was OHNE Exklusion getroffen würde (rg-OHNE -g / grep-OHNE --exclude) ---"
|
||||
if command -v rg >/dev/null 2>&1; then
|
||||
rg -l 'deterministische-relevanz-bestimmung' wiki/ | normalize
|
||||
@@ -97,7 +174,7 @@ FIRST2=$(terms 'alpha' | normalize)
|
||||
SECOND2=$(terms 'alpha' | normalize)
|
||||
echo "Lauf 1 (Term deterministische-relevanz-bestimmung): $FIRST1"
|
||||
echo "Lauf 2 (Term deterministische-relevanz-bestimmung): $SECOND1"
|
||||
echo "Lauf 1 (Term alpha): $FIRST2 # 'index' ist der legitime Stufe-b-Traversal-Treffer (Bundleroot verlinkt alpha.md), kein Kontaminations-Fehler"
|
||||
echo "Lauf 1 (Term alpha): $FIRST2 # 'index' ist ein Stufe-a-Treffer auf wiki/index.md — Stufe b (TRAVERSAL_REACH_ONLY, §3.2-Pkt.-2b) löst die darunter gewurzelten Concept-Pfade als Candidate aus (index.md selbst ist KEIN Concept-Kandidat); kein Kontaminations-Fehler"
|
||||
echo "Lauf 2 (Term alpha): $SECOND2 # identische Ausgabe (Zwei-Run-Identität, AD-17h)"
|
||||
if [ "$FIRST1" = "$SECOND1" ] && [ "$FIRST2" = "$SECOND2" ]; then
|
||||
echo "RESULT: IDENTISCH (gleicher Git-State + gleiches Eingabeset -> identische Candidate-Liste, AD-17h)"
|
||||
@@ -133,10 +210,144 @@ generated:
|
||||
Gamma teilt den Term deterministische-relevanz-bestimmung (Stelle S-1).
|
||||
EOF
|
||||
git add -A; git commit -qm "Zuwachs gamma (teilt den Term)"
|
||||
echo "--- Kandidaten-Erhebung (Term in alpha + gamma): ---"
|
||||
terms 'deterministische-relevanz-bestimmung' | normalize | LC_ALL=C sort
|
||||
echo "--- Erwartet: alpha, gamma (beide Concept-Pfade, lexikografisch; log ABGESCHNITTEN) ---"
|
||||
echo "--- Kandidaten-Erhebung (Term in alpha + gamma; §3.2-Pkt.-3b: innerhalb jeder Stufe rein lexikografisch, LC_ALL=C): ---"
|
||||
terms 'deterministische-relevanz-bestimmung' | normalize | LC_ALL=C sort | paste -sd, -
|
||||
echo "--- Erwartet: alpha,gamma (beide Concept-Pfade, lexikografisch; log ABGESCHNITTEN) ---"
|
||||
T4_OUT=$(terms 'deterministische-relevanz-bestimmung' | normalize | LC_ALL=C sort | paste -sd, -)
|
||||
if [ "$T4_OUT" = "alpha,gamma" ]; then
|
||||
echo "RESULT: PASS (Vereinigung beider Concept-Pfade, lexikografisch; log.md exkludiert)"
|
||||
else
|
||||
echo "FAIL: T4 — erwartet 'alpha,gamma', erhalten: '${T4_OUT}'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# =====================================================================
|
||||
# T5-T7 (Review-Loop-2, D-2): Zyklen-Endlichkeit, Traversal-Only, Synonym-Auflösung
|
||||
# =====================================================================
|
||||
|
||||
# ---------- T5: LINK_FOLLOWING_ZYKLUS — A -> B -> A endet endlich (besuchte Menge) ----------
|
||||
runlabel "T5: LINK_FOLLOWING_ZYKLUS — Zyklus alpha <-> omega endet endlich; Candidate-Liste endlich (§3.2-Pkt.-2c/3b)"
|
||||
cat > wiki/omega.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/omega-v1.md
|
||||
id: s1
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-16T09:00:00Z
|
||||
---
|
||||
Omega verweist zirkular auf Alpha: [Alpha](alpha.md).
|
||||
EOF
|
||||
# Backlink: alpha -> omega (erzeugt den echten A->B->A-Zyklus, der die besuchte Menge übt):
|
||||
printf '\nOmega-Verweis: [Omega](omega.md).\n' >> wiki/alpha.md
|
||||
git add -A; git commit -qm "Zuwachs omega (Link-Zyklus alpha <-> omega)"
|
||||
echo "--- Stufe a (Term zirkular): ---"
|
||||
STAGE_A=$(terms 'zirkular' | normalize | LC_ALL=C sort | paste -sd, -)
|
||||
echo "$STAGE_A"
|
||||
echo "--- Stufe c (Follow aus Stufe a; ZYKLUS omega -> alpha -> omega ... MUSS enden): ---"
|
||||
STAGE_C=$(follow omega)
|
||||
echo "$STAGE_C"
|
||||
# Deduplication über die besuchte Menge (sort -u: endliche, doppelungsfreie Menge —
|
||||
# die Stufe-Ordnung a→c ist bereits in STAGE_A/STAGE_C sichtbar; hier wird die Endlichkeit geprüft):
|
||||
T5_EXPECT="alpha,omega"
|
||||
T5_LIST=$(printf '%s\n%s\n' "$STAGE_A" "$STAGE_C" | grep -v '^$' | LC_ALL=C sort -u | paste -sd, -)
|
||||
if [ "$T5_LIST" = "$T5_EXPECT" ]; then
|
||||
echo "RESULT: PASS (endlich, dedupliziert: omega, alpha — Zyklus endete; jeder Pfad genau einmal)"
|
||||
else
|
||||
echo "FAIL: T5 — erwartet '$T5_EXPECT', erhalten: '$T5_LIST'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---------- T6: TRAVERSAL_REACH_ONLY — Term nur in index.md -> gewurzelte Concept-Pfade ----------
|
||||
runlabel "T6: TRAVERSAL_REACH_ONLY — Term 'trafo-gebiet' trifft NUR wiki/trafo/index.md -> gewurzelte Concept-Pfade sind die Treffer (index.md selbst kein Concept-Kandidat, §3.2-Pkt.-2b)"
|
||||
mkdir -p wiki/trafo
|
||||
cat > wiki/trafo/index.md <<'EOF'
|
||||
# Trafo-Gebiet-Index
|
||||
Dieses trafo-gebiet wird hier indexiert.
|
||||
- [Delta](delta.md)
|
||||
- [Epsilon](epsilon.md)
|
||||
EOF
|
||||
cat > wiki/trafo/delta.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/delta-v1.md
|
||||
id: s1
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-16T09:00:00Z
|
||||
---
|
||||
Delta-Body (trägt den Index-Term NICHT — nur der Index trägt ihn).
|
||||
EOF
|
||||
cat > wiki/trafo/epsilon.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/epsilon-v1.md
|
||||
id: s1
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-16T09:00:00Z
|
||||
---
|
||||
Epsilon-Body (trägt den Index-Term NICHT — nur der Index trägt ihn).
|
||||
EOF
|
||||
git add -A; git commit -qm "Zuwachs trafo/Area (Index trägt den Term, Bodies nicht)"
|
||||
echo "--- Stufe a (Term trafo-gebiet; nur index.md trifft — der Traversal-Trigger): ---"
|
||||
STAGE_A=$(terms 'trafo-gebiet' | normalize)
|
||||
echo "$STAGE_A"
|
||||
echo "--- Stufe b (Traversal: gewurzelte Concept-Pfade der getroffenen index.md): ---"
|
||||
STAGE_B=$(traverse 'trafo/index')
|
||||
echo "$STAGE_B"
|
||||
# Kandidaten = gewurzelte Concept-Pfade (lexikografisch; index.md selbst ist KEIN Concept-Kandidat):
|
||||
T6_OUT=$(printf '%s\n' "$STAGE_B" | grep -v '^$' | LC_ALL=C sort | paste -sd, -)
|
||||
if [ "$T6_OUT" = "trafo/delta,trafo/epsilon" ]; then
|
||||
echo "RESULT: PASS (Candidate-Liste = gewurzelte Concept-Pfade; Index-Body-Trigger, kein Kontaminations-Fehler)"
|
||||
else
|
||||
echo "FAIL: T6 — erwartet 'trafo/delta,trafo/epsilon', erhalten: '$T6_OUT'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---------- T7: TERM_ABLEITUNG_SYNONYM — Schreibvariante -> canonische Form -> Kandidaten ----------
|
||||
runlabel "T7: TERM_ABLEITUNG_SYNONYM — gezogene Schreibvariante wird über canonical-terms.md auf die canonische Form aufgelöst (Lookup auf normalisierter Form, §3.2-Pkt.-1b)"
|
||||
mkdir -p "$ROOT/registry"
|
||||
cat > "$ROOT/registry/canonical-terms.md" <<'EOF'
|
||||
# Sandbox-Registry (Test-Doppel des canonical-terms-Formats; append-only, ein Eintrag = Canon + Varianten;
|
||||
# D-5-Invariante: Canon- UND Varianten-Spalte tragen ausschliesslich NORMALISIERTE Formen)
|
||||
|
||||
| canonische Form | erlaubte Schreibvarianten | Semantik |
|
||||
|---|---|---|
|
||||
| quanten-protocol | `quantenprotocol` | Sandbox-Semantik: Test-Synonymgruppe |
|
||||
EOF
|
||||
# Invariante-Check (D-5): keine normalisierte Form in beiden Spalten oder in zwei Einträgen:
|
||||
# hier: 'quanten-protocol' nur Canon-Spalte, 'quantenprotocol' nur Varianten-Spalte — eindeutig.
|
||||
# (Registry liegt ausserhalb des Sandbox-Git-Roots — sie modelliert den Git-State-Anteil des Resolvers;
|
||||
# der Sandbox-Repo-Commit trägt sie deshalb nicht, hier nur Notiz statt Commit-Noise:)
|
||||
echo "Registry (ausserhalb des Sandbox-Roots, modelliert den Resolver-Git-State): $ROOT/registry/canonical-terms.md"
|
||||
echo "--- Gezogene Schreibvarianten (Roh-Notat): 'Quanten Protocol' + 'QuantenProtocol' ---"
|
||||
RAW_A='Quanten Protocol'
|
||||
RAW_B='QuantenProtocol'
|
||||
NORM_A=$(norm_term "$RAW_A")
|
||||
NORM_B=$(norm_term "$RAW_B")
|
||||
echo "Normalisierung (§3.2-Pkt.-1b): '$RAW_A' -> '$NORM_A'; '$RAW_B' -> '$NORM_B'"
|
||||
CANON_A=$(lookup "$NORM_A" "$ROOT/registry/canonical-terms.md")
|
||||
CANON_B=$(lookup "$NORM_B" "$ROOT/registry/canonical-terms.md")
|
||||
echo "Lookup: '$NORM_A' -> '$CANON_A'; '$NORM_B' -> '$CANON_B'"
|
||||
if [ "$CANON_A" = "quanten-protocol" ] && [ "$CANON_B" = "quanten-protocol" ]; then
|
||||
echo "RESULT: PASS (beide Varianten -> canonische Form 'quanten-protocol'; Auflösung auf normalisierter Form)"
|
||||
else
|
||||
echo "FAIL: T7 — erwartet 'quanten-protocol' für beide, erhalten: '$CANON_A' / '$CANON_B'" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Nicht aufgelöster Term wird wie notiert (Kollaps-normalisiert) verwendet — kein stiller Ausschluss:
|
||||
CANON_MISS=$(lookup 'nicht-in-registry' "$ROOT/registry/canonical-terms.md")
|
||||
if [ "$CANON_MISS" = 'nicht-in-registry' ]; then
|
||||
echo "PASS (Negativ-Fall: 'nicht-in-registry' -> wie notiert, kein stiller Ausschluss)"
|
||||
else
|
||||
echo "FAIL: T7-Negativ — erwartet 'nicht-in-registry', erhalten: '$CANON_MISS'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "===== Sandbox abgeschlossen (alle 4 Tests) ====="
|
||||
echo "===== Sandbox abgeschlossen (alle 7 Tests) ====="
|
||||
echo "Sandbox-Root: $ROOT"
|
||||
|
||||
+36
-5
@@ -2,8 +2,8 @@
|
||||
title: 'Relevanzbestimmung textual-deterministisch umsetzen (grep/ripgrep + Markdown-Traversal + Link-Following) (Story 3.2)'
|
||||
type: 'feature'
|
||||
created: '2026-08-19'
|
||||
status: 'in-review'
|
||||
review_loop_iteration: 2
|
||||
status: 'done'
|
||||
review_loop_iteration: 3
|
||||
baseline_commit: e3e7ec346df3e6190644d2c94e5cc7c42e6ed239
|
||||
context:
|
||||
- _bmad-output/implementation-artifacts/epic-3-context.md
|
||||
@@ -71,13 +71,44 @@ context:
|
||||
- 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).
|
||||
|
||||
- [x] [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.
|
||||
- [x] [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).
|
||||
- [x] [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).
|
||||
- [x] [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).
|
||||
- [x] [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).
|
||||
- [x] [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; }`.
|
||||
- [x] [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).
|
||||
- [x] [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
|
||||
- [x] [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
|
||||
- [x] [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
|
||||
- [x] [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.md` → **Revision 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-5** — `schema/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-1** — `run-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-3** — `wiki/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 (`Determinsmus`→`Determinismus`, `beankert`→`angeankert`, `Membrum`→`Mitglied`, `Konventionelle`→`Bekannte`, `Resovierung`→`Auflö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.md` → `log.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 `—`-Resovierung wird als offene Determinismus-Lücke in Step-4-Defer an Story 3.8 übergeben (nicht stillschweigend hinzugefügt).
|
||||
- **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).
|
||||
@@ -90,7 +121,7 @@ context:
|
||||
|
||||
**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 Membrum).
|
||||
**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.
|
||||
|
||||
@@ -103,7 +134,7 @@ context:
|
||||
- `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. <br>_(Optionale Em-Dash-Prüfung: die Normalisierungs-Klasse deckt `-` ab; explizite `—`-Varianten-Resovierung ist eine erkannte Determinismus-Lücke → Story 3.8, s. Spec Change Log.)_
|
||||
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. <br>_(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).
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended)
|
||||
# - Retrospective appends its action items to action_items; the status view surfaces open ones
|
||||
generated: 08-14-2026 00:00
|
||||
last_updated: 08-19-2026 07:10
|
||||
last_updated: 08-19-2026 13:14
|
||||
project: wow20
|
||||
project_key: NOKEY
|
||||
tracking_system: file-system
|
||||
|
||||
Reference in New Issue
Block a user