diff --git a/_bmad-output/implementation-artifacts/deferred-work.md b/_bmad-output/implementation-artifacts/deferred-work.md index 9eea5a9..95bd445 100644 --- a/_bmad-output/implementation-artifacts/deferred-work.md +++ b/_bmad-output/implementation-artifacts/deferred-work.md @@ -486,3 +486,61 @@ Noch nicht adressierte, aber real erkannte Arbeit — gesammelt aus Reviews. Ein - Bezug: §5.9 Pkt. 2/§5.7 Misch-Runs (Neu-Anlage + Update im selben Run) sind in der CONSIST-Sandbox ab Review-Loop-2 im CONSIST-2 abgedeckt (Neu-Anlage `delta` + Update `alpha`, Plan-Freeze-Menge + Voll-Rollback, Neu-Anlage-Absenz nach Rollback); übrige Phasen-/Synthese-Misch-Formen bleiben Home Story 3.8 (Determinismus-Vertrag AD-17h als Agent-Instruktions-Validator, inkl. A0-20-Post-Zustand-Test). - status: delokalisiert (Home: Story 3.8) + +## Deferred from: code review of spec-3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validator (Story 3.8, 2026-08-20) + +### Aufgegriffen: Em-Dash-Varianten-Lücke der Normalisierung (Story-3.2-Defer, Home Story 3.8) — Story 3.8, 2026-08-20 + +- Bezug: Defer «Em-Dash-"—"-Varianten-Lücke der Normalisierung» (Defer-Block „Deferred from: Story 3.2", Eintrag 1; `status: offen (Home: Story 3.8)`). +- Umsetzung: `schema/compiler.md` §3.2 Pkt. 1b „Geschlossene Determinismus-Lücken (Story 3.8)": die Kollaps-Klasse ist um den Em-Dash `—` ergänzt (`[-–— _]` → `-`) — En-Dash, Em-Dash, Bindestrich, Unterstrich, Leerzeichen kollabieren identisch auf genau einen Bindestrich. Verankerung: §5.14 Pkt. 5 verweist auf §3.2-Pkt.-1b. Kein stiller Ausschluss; append-only-Regel-Ergänzung, bestehender §3.2-Wortlaut unverändert. +- Sandbox-Nachweis: `_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh` DET-5 (Em-Dash → identische canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen) — Exit 0. +- status: aufgegriffen (Home erledigt in §3.2 Pkt. 1b / §5.14 Pkt. 5) + +### Aufgegriffen: Kollaps-Reichweite bei Läufen/führenden/trailenden Separatoren (Story-3.2-Defer, Home Story 3.8) — Story 3.8, 2026-08-20 + +- Bezug: Defer «§3.2-Pkt.-1b-ii: Kollaps-Reichweite bei aufeinanderfolgenden/führenden/trailenden Separatoren unbestimmt» (Defer-Block „Deferred from: code review of spec-3-2…", Eintrag 2). +- Umsetzung: `schema/compiler.md` §3.2 Pkt. 1b „Geschlossene Determinismus-Lücken": Kollaps-Reichweite deterministisch — jedes Separator-Vorkommen kollabiert auf genau ein `-`; Läufe (`a--b` → `a-b`); führende (`-x` → `x`) und trailende (`x-` → `x`) Separatoren werden getrimmt. Verankerung §5.14 Pkt. 5; die in der Sandbox etablierte Semantik wird normativ fixiert. +- Sandbox-Nachweis: DET-6 (Läufe `a--b`, führende `-x`, trailende `x-`, Kombination `---x---` → `x`) — Exit 0. +- status: aufgegriffen (Home erledigt in §3.2 Pkt. 1b / §5.14 Pkt. 5) + +### Aufgegriffen: Match-Scope der Stufe a (Wortgrenzen, Frontmatter-exklusiv) (Story-3.2-Defer, Home Story 3.8) — Story 3.8, 2026-08-20 + +- Bezug: Defer «§3.2-Pkt.-2a: Wortgrenzen-/Frontmatter-Scope der Stufe-a-Match-Semantik ist offen» (Defer-Block „Deferred from: code review of spec-3-2…", Eintrag 1). +- Umsetzung: `schema/compiler.md` §3.2 Pkt. 1b „Geschlossene Determinismus-Lücken" (c) Match-Scope der Stufe a: Stufe a matcht ganze Wörter (Wortgrenzen) über den Body, exklusive YAML-Frontmatter — Substring- und Frontmatter-Treffer (z. B. in `sources[].resource`/`generated.by`) liefern keine Kandidaten (deterministischer Stufe-a-Scope). Verankerung §5.14 Pkt. 5. +- Sandbox-Nachweis: DET-7 (ganzes Wort trifft alpha; Substring `opplung` und Frontmatter-only-Kandidat `mirror` liefern keine Kandidaten) — Exit 0. +- status: aufgegriffen (Home erledigt in §3.2 Pkt. 1b / §5.14 Pkt. 5) + +### Aufgegriffen: Orphan-Kontrolle als deterministische Reconcile-Orphan-Regel (Story-3.4-Defer, Home Story 3.8) — Story 3.8, 2026-08-20 + +- Bezug: Defer «Orphan-Kontrolle (§5.10 Pkt. 8) textuell verankert, aber nicht in der Sandbox demonstriert» (Defer-Block „Deferred from: code review of spec-3-4…", Eintrag 2; `status: offen (Home: Story 3.8)`). +- Umsetzung: `schema/compiler.md` §5.10 Pkt. 8 „Deterministische Reconcile-Orphan-Regel (Story 3.8; §5.14-Präzisierung)": Verwaist-Befund deterministisch aus dem committeten Git-State (Zuwachs gg. ``, §5.9 Pkt. 6 R-1); datumsgruppierter `log.md`-Eintrag (Header `YYYY-MM-DD`, neueste zuerst; Quell-Pfad + ``); kein Banner/keine stille Vorbearbeitung/keine eigenständige Anlage (AD-16-Default, Epic-4-Interface). Verankerung §5.14 Pkt. 5. +- Sandbox-Nachweis: DET-8 (verwaiste `raw/`-Evidenz ohne Ziel-Pfad-Treffer → unzugeordnet, `log.md`-Verwaist-Eintrag mit ``, kein Banner, keine eigenständige Anlage, Erhaltungs-Invariante nur `log.md`) — Exit 0. +- status: aufgegriffen (Home erledigt in §5.10 Pkt. 8 / §5.14 Pkt. 5) + +### Aufgegriffen: generated.at↔AD-17h-Gap & Zwei-Run-Identitäts-Nachweis (Story-3.3-Defer, Home Story 3.8) — Story 3.8, 2026-08-20 + +- Bezug: Defer «U6-Zwei-Run-Identitäts-Nachweis … kreuzreferenziert den generated.at↔AD-17h-Gap nicht» (Defer-Block „Deferred from: code review of spec-3-3…", Eintrag 3; `status: offen (Home: Story 3.8)`). +- Umsetzung: `schema/compiler.md` §5.14 Pkt. 1 (Bundle-State-Definition: `generated.at`/`verified[].at` als benannte Ausnahme der Projektion), Pkt. 3 (Ausnahme-Menge: allein der `generated.at`-Wanduhr-Gap; alle übrigen Bestandteile byte-identisch) und Pkt. 2 (Zwei-Run-Mechanik: identische Plan-/Kandidaten-/Reihenfolge-Outputs und byte-identische mutierte Bundle-Bestandteile bis auf die `at`-Ausnahme). Der A0-20-Wanduhr-Gap bleibt verhaltens-seitig unverändert (Ask-First bei Verhaltens-Wechsel). +- Sandbox-Nachweis: DET-2 (Zwei-Run-Identität nicht-vakuum, echte Content-Hashes) + DET-4 (at-Gap-Ausnahme: diff ausschließlich auf der at-Zeile, nach at-Maskierung byte-identisch; Negativkontrolle Body-Differenz = AD-16-Defekt) — Exit 0. +- status: aufgegriffen (Home erledigt in §5.14 Pkt. 1–3) + +### Aufgegriffen: A0-20-Post-Zustand-Negativkontrolle in der Sandbox (Story-3.7-Defer, Home Story 3.8) — Story 3.8, 2026-08-20 + +- Bezug: Defer «A0-20-Post-Zustand-Negativkontrolle in der Sandbox fehlt … Home: Story 3.8 (A0-20-Home)» (Defer-Block „Deferred from: code review of spec-3-7…", Eintrag 2). +- Umsetzung: §5.14 Pkt. 3 definiert die Ausnahme-Menge des Bundle-State-Vergleichs (allein der `generated.at`-Wanduhr-Gap; jede andere Differenz außerhalb der Ausnahme = AD-16-Klassifikationsdefekt, Pkt. 4, textuell benannt NFR-4). Der Post-Zustand wird damit über die Zwei-Run-Mechanik (Pkt. 2) einschließlich at-Handhabung instruiert; die Sandbox demonstriert den Gap positiv und negativ. +- Sandbox-Nachweis: DET-4 (positiv: zwei Runs mit unterschiedlichen `at` → diff nur at-Zeile, nach Maskierung byte-identisch; negativ: Body-Differenz → AD-16-Klassifikationsdefekt) — Exit 0. +- status: aufgegriffen (Home erledigt in §5.14 Pkt. 2–4) + +### Aufgegriffen: Misch-Run-Coverage Determinismus-Vertrag (Story-3.7-Delokalisierung, Home Story 3.8) — Story 3.8, 2026-08-20 + +- Bezug: Delokalisierung «Misch-Run-Coverage Neu-Anlage+Update in der Story-3.7-Sandbox … übrige Phasen-/Synthese-Misch-Formen bleiben Home Story 3.8 (Determinismus-Vertrag AD-17h als Agent-Instruktions-Validator, inkl. A0-20-Post-Zustand-Test)» (Block „### Delokalisierung …", `status: delokalisiert (Home: Story 3.8)`). +- Umsetzung: Der Determinismus-Vertrag wird als geschlossene Bestätigungs-Mechanik in §5.14 verankert (Bundle-State-Projektion, Zwei-Run-Bestätigung, at-Ausnahme, Abweichungs-Klassifikation); die §5.13-Determinismus-Nachweise bleiben unverändert, die at-A0-20-Konvention ist auf die §5.14-Pkt.-3-Ausnahme-Menge verlagert (§5.13 Pkt. 7 Seam). +- Sandbox-Nachweis: DET-1..DET-4 (Bundle-State-Definition, Zwei-Run-Identität, Abweichungs-Klassifikation, at-Gap-Ausnahme) — Exit 0. +- status: aufgegriffen (Home erledigt in §5.14) + +### Aufgegriffen (teilweise): Gemischte Normalisierungs-Politik Umlaute vs. Transkription — Em-Dash-Anteil (Story-3.3/Story-3.4-Defers, Home Story 3.8) — Story 3.8, 2026-08-20 + +- Bezug: Defer «Gemischte Normalisierungs-Politik im Sandbox-Evidenztext (Umlaute vs. Transkriptionen) ist ein Determinismus-Hazard für den Term-Abgleich» (Defer-Block „Deferred from: code review of spec-3-3…", Eintrag 5, `status: offen (Home: Story 3.8)`) und Defer «Sandbox-Evidenztexte transkribieren Umlaute, die Concept-Bodies nutzen Umlaut-Schreibweisen» (Defer-Block „Deferred from: code review of spec-3-4…", Eintrag 3, `status: offen (Home: Story 3.8)`). +- Umsetzung: Der Em-Dash-Anteil beider Einträge ist in `schema/compiler.md` §3.2 Pkt. 1b / §5.14 Pkt. 5 geschlossen (Em-Dash in der Kollaps-Klasse `[-–— _]` → `-`). Der Umlaut-vs-Transkription-Anteil bleibt offen: die §3.2-Normalisierung (lowercasing + Kollaps-Klasse) deckt Umlaut-Divergenzen („Schlüssel" vs. „Schluessel") weiterhin nicht ab — kein neuer Normalisierungs-Schritt in Story 3.8 (kein neuer Regel-Operand, D-3/append-only). +- Sandbox-Nachweis: DET-5 (Em-Dash-Anteil) — Exit 0. +- status: teilweise aufgegriffen (Em-Dash-Anteil geschlossen in §3.2 Pkt. 1b / §5.14 Pkt. 5; Umlaut-vs-Transkription-Divergenz bleibt offen — Home: Sandbox-Vereinheitlichung oder folgende Compiler-Instruktions-Revision; kein Instruktions-Defekt) diff --git a/_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh b/_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh new file mode 100644 index 0000000..955885d --- /dev/null +++ b/_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh @@ -0,0 +1,572 @@ +#!/usr/bin/env bash +# Story 3.8 — Sandbox-Tests des Determinismus-Vertrags (AD-17h/FT-10/A0-19) als +# Agent-Instruktions-Validator (§5.14, Revision 3.3) +# Re-executierbar: bash run-sandbox.sh (ab Workspace-Root; Sandbox unter /tmp/sb38) +# Zweck: die deterministische Bestätigungs-Mechanik (§5.14) als re-executierbarer +# Run-Demonstrator durchspielen — +# DET-1 BUNDLE_STATE_DEFINITION: ein Mini-Bundle erzeugen und die Bundle-State- +# Projektion deterministisch definieren/extrahieren (wiki/-Dateien + Plan-/ +# Kandidaten-/Reihenfolge-Outputs; Extraktion zweimal -> identisch) +# DET-2 ZWEI_RUN_IDENTISCH (nicht-vakuum): zwei unabhängige Läufe über demselben +# committeten Baum -> identische Bundle-States bis auf at; die Assertion +# vergleicht echte Content-Hashes (nicht nur Vorhandensein); der Witness +# (wiki/alpha.md) weicht byte-weise von der Baseline ab (kein Vakuum) +# DET-3 ZWEI_RUN_ABWEICHUNG: künstlich divergenter Lauf -> als AD-16-Klassifikations- +# defekt klassifiziert und textuell benannt (kein Rauschen); korrigierter zweiter +# Lauf == erster Lauf (erneut bestätigt) +# DET-4 AT_GAP_AUSNAHME: generated.at-Wanduhr-Gap ist die einzige benannte Ausnahme +# (diff zwischen zwei Runs ausschließlich auf der at-Zeile; nach at-Maskierung +# byte-identisch); jede andere Differenz liegt ausserhalb der Ausnahme = +# AD-16-Klassifikationsdefekt +# DET-5 EM_DASH: Em-Dash — kollabiert auf dieselbe canonische Form wie En-Dash/ +# Bindestrich/Unterstrich/Leerzeichen (§3.2 Pkt. 1b, [-–— _] -> -) +# DET-6 KOLLAPS: Läufe (a--b), führende (-x), trailende (x-) -> Kollaps auf +# genau ein - + Trim (Reichweite: jedes Vorkommen -> genau ein -) +# DET-7 MATCH_SCOPE: Stufe a matcht ganze Wörter über den Body, exklusive YAML- +# Frontmatter (Substring-/Frontmatter-Treffer ausgeschlossen) +# DET-8 ORPHAN: neu committete raw/-Evidenz ohne Ziel-Pfad-Treffer -> unzugeordnet, +# log.md-verwaist protokolliert (Datumsgruppe, ), kein Banner, +# keine stille Vorbearbeitung, keine eigenständige Anlage (AD-16-Default) +# Determinismus-Vertrag (AD-17h/A0-19) als HARDE Assertion je Szenario; KEINE_EIGENE_ENGINE- +# Negativkontrolle (D-3/AD-11) in DET-1; Frontmatter-/log.md-Konformitaet (Vertrag §3.3/§3.4, §5). +# Ubuntu-Sandbox-Semantik auf einem /tmp-Baum — NIE der reale wiki/- oder raw/-Baum. +set -u +ROOT=$(mktemp -d /tmp/sb38-XXXXXX) +SB="$ROOT/sb" +mkdir -p "$SB/wiki" "$SB/raw" +cd "$SB" +git init -q +# Determinismus vs. Host-Git-Konfiguration (AD-17h): LF-Blobs + LF-Worktree — +# autocrlf/filemode-Umwandlung des Hosts wuerde sha256-Vergleiche verschieben. +git config core.autocrlf false +git config core.filemode false +git config user.email "sandbox@test" +git config user.name "Sandbox" + +# ---------- Basis-Baum (committete Ausgangslage = Baseline-Commit) ---------- +# Mini-Bundle mit zwei Root-Concepts (alpha als Mutations-Objekt, gamma als Kontrolle). +cat > wiki/index.md <<'EOF' +# Index +- [Alpha](alpha.md) +- [Gamma](gamma.md) +EOF +cat > wiki/alpha.md <<'EOF' +--- +type: concept +sources: + - resource: raw/alpha-v1.md + id: s1 +generated: + by: wow-compiler/0.1.0 + at: 2026-08-16T09:00:00Z +--- +Das Alpha-Protokoll definiert eine deterministische Init-Sequenz (raw/alpha-v1.md#S-1). +Alpha verwendet ausschließlich lokale Netze (raw/alpha-v1.md#S-2). +EOF +cat > wiki/gamma.md <<'EOF' +--- +type: concept +sources: + - resource: raw/gamma-v1.md + id: s1 +generated: + by: wow-compiler/0.1.0 + at: 2026-08-16T09:00:00Z +--- +Gamma beschreibt ein anderes, hier nicht betroffenes Thema. +EOF +cat > wiki/log.md <<'EOF' +# Log +EOF +cat > raw/alpha-v1.md <<'EOF' +### S-1 +Evidenz v1: deterministische Init-Sequenz. +### S-2 +Evidenz v1: ausschließlich lokale Netze. +EOF +cat > raw/gamma-v1.md <<'EOF' +### S-1 +Evidenz v1: Gamma-Thema. +EOF +git add -A +git commit -qm "Baseline" +BASE=$(git rev-parse HEAD) +echo "BASELINE-COMMIT (Merge-Base, eindeutiger Commit-Object-Wert): $BASE" +echo "Sandbox-Root: $ROOT (loeschbar: rm -rf $ROOT)" +echo + +# ---------- Helfer: Run-Label / Isolation (kein Carry-over zwischen Szenarien) ---------- +runlabel() { echo; echo "########## $1 ##########"; } +isolate() { + git checkout -qf -B "$1" "$BASE" + git reset -q --hard "$BASE" + git clean -qfd wiki raw lease registry scratch plan-run +} + +# ---------- Deterministische Normalisierung (§3.2 Pkt. 1b, Story 3.8) ---------- +# lowercasing + Binde-Varianten-Kollaps [-–— _] -> - (En-Dash –, Em-Dash —, +# Bindestrich -, Unterstrich _, Leerzeichen), Kollaps-Reichweite: jedes Vorkommen -> +# genau ein -; Läufe kollabieren; führende/trailende Separatoren werden getrimmt. +norm() { # $1 = Begriff (Kollaps-Form, NICHT registry-aufloesend — Kollaps-Scope isoliert) + printf '%s' "$1" | sed \ + -e 's|[–—]|-|g' \ + -e 's|_| |g' \ + -e 's| |-|g' \ + -e 's|--*|-|g' \ + -e 's|^-*||' \ + -e 's|-*$||' \ + | tr 'A-Z' 'a-z' +} +# Stufe-a-Match-Scope (§3.2 Pkt. 2a, Story 3.8): matcht ganze Wörter über den Body, +# exklusive YAML-Frontmatter. Implementierung: Frontmatter (zwischen ersten beiden ---) +# wird entfernt, danach Wortgrenzen-Match (rg mit Wortgrenzen bzw. grep '\b'). +match_stufe_a() { # $1=Begriff $2=Datei-Liste ; liefert getroffene wiki-Pfade (ohne Präfix/Suffix) + local term="$1" file + for file in "${@:2}"; do + # Body = alles nach dem zweiten "---" (Frontmatter exkludiert, deterministisch) + body=$(awk 'BEGIN{n=0} /^---$/{n++; next} n>=2{print}' "$file") + # Wortgrenzen-Match: ganze Wörter — Substring-/Frontmatter-Treffer liefern nichts. + # Term-Normalisierung (§3.2 Pkt. 1b) ist lowercasing — der Match ist daher case-insensitiv. + if printf '%s' "$body" | grep -Eiq "(^|[^A-Za-z0-9])${term}([^A-Za-z0-9]|$)"; then + basename "$file" .md + fi + done +} +# log.md-Eintrag (datumsgruppiert, neueste zuerst; Vertrag §5). Deterministisch fester Tag. +log_bullet() { # $1 = Bullet-Text (eine Zeile) + local day="2026-08-20" + local header="## $day" line="$1" + if grep -qxF "$header" wiki/log.md; then + tmp=$(mktemp) + awk -v h="$header" -v l="$line" ' + BEGIN{p=0} + { if (!p && $0==h) { print; print l; p=1; next } print } + ' wiki/log.md > "$tmp" && mv "$tmp" wiki/log.md + else + tmp=$(mktemp) + { printf '%s\n' "$header"; printf '%s\n' "$line"; cat wiki/log.md; } > "$tmp" && mv "$tmp" wiki/log.md + fi +} + +# ===================================================================================== +# DET-1 BUNDLE_STATE_DEFINITION (§5.14 Pkt. 1) +# ===================================================================================== +runlabel "DET-1: BUNDLE_STATE_DEFINITION — Mini-Bundle erzeugen; Bundle-State-Projektion (wiki/-Dateien + Plan-/Kandidaten-/Reihenfolge-Outputs) deterministisch definieren/extrahieren; KEINE_EIGENE_ENGINE (D-3/AD-11)" +if command -v pgrep >/dev/null 2>&1; then + engine_proc=$(pgrep -f "wow-flow-engine|wow-server|wow-mcp" 2>/dev/null || true) +else + command -v ps >/dev/null 2>&1 || { echo "HARD-FAIL (KEINE_EIGENE_ENGINE): weder pgrep noch ps verfügbar" >&2; exit 1; } + engine_proc=$(ps aux 2>/dev/null | grep -E "wow-flow-engine|wow-server|wow-mcp" | grep -v "grep" || true) +fi +if [ -n "$engine_proc" ]; then + echo "HARD-FAIL (KEINE_EIGENE_ENGINE D-3/AD-11, §5.14): ein Workflow-Engine-Prozess wurde gestartet" >&2 + echo "$engine_proc" | sed 's/^/ /' >&2 + exit 1 +else + echo " BEFUND: keine Workflow-Engine-Prozesse (wow-flow-engine/wow-server/wow-mcp) — der Agent-Instruktions-Validator ist die Instruktion selbst (kein Prozess/Server/MCP)" +fi +isolate det1 +# Der Run erzeugt einen definierten Bundle-State: neue committete Evidenz (Input) -> +# Plan-/Kandidaten-Output -> Mutations-Commit (deterministischer Run-Ausgangszustand). +cat > raw/alpha-v2.md <<'EOF' +### S-3 +Evidenz v2: Alpha erweitert um eine synchrone Kopplung. +EOF +git add -A && git commit -qm "Evidenz v2" +plan=$(printf 'cand=alpha;form=update;baseline=%s' "$BASE") +cat > wiki/alpha.md <<'EOF' +--- +type: concept +sources: + - resource: raw/alpha-v1.md + id: s1 + - resource: raw/alpha-v2.md + id: s3 +generated: + by: wow-compiler/0.1.0 + at: 2026-08-20T00:00:00Z +--- +Das Alpha-Protokoll definiert eine deterministische Init-Sequenz (raw/alpha-v1.md#S-1). +Alpha verwendet ausschließlich lokale Netze (raw/alpha-v1.md#S-2). +Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3). +EOF +log_bullet "- Determinismus-Bestätigung (Bundle-State-Definition, §5.14 Pkt. 1): $plan" +git add -A && git commit -qm "Run: alpha-Update (DET-1)" +# Bundle-State-Extraktion (§5.14 Pkt. 1): (a) committeter Baum gg. Baseline, +# (b) Kandidatenliste in Zuwachs-Sicht-Ordnung, (c) Ausführungs-Entscheidung (Form-Wahl). +# Deterministische Projektion = (a)+(b)+(c) — zweimal extrahiert, byte-identisch. +# Dev-Demo-Notiz: die (b)-/(c)-Kandidaten-/Form-Outputs sind für die Wiederholungs-Probe +# eigentliche Run-Feststellungen (hier redaktionell verdichtet; die Tendenz "die Bundle-State +# wiederholt extrahieren ist deterministisch" wird von der zweimaligen Wiederholung bewiesen, +# die Ausführungs-Verdikte selbst belegen die DET-Szenarien DET-3/DET-4/DET-7). +bs_a() { + { git diff --name-only "$BASE" -- wiki/ ; git status --porcelain -- wiki/ | awk '{print $2}'; } \ + | sed -e 's|^wiki/||' -e 's|\.md$||' | LC_ALL=C sort -u + # Kandidatenliste (Stufe a, deterministisch; Zuwachs-Ordnung) — hier textuell festgehalten: + match_stufe_a "kopplung" wiki/alpha.md wiki/gamma.md + # Form-Wahl (Ausführungs-Entscheidung): alpha ist betroffen, gamma nicht + echo "form=update" + echo "baseline=$BASE" +} +B1=$(bs_a) +B2=$(bs_a) +[ "$B1" = "$B2" ] || { echo "HARD-FAIL (DET-1): Bundle-State-Projektion nicht deterministisch (gleiche Extraktion zweimal ungleich)" >&2; exit 1; } +case "$B1" in + *alpha*) ;; + *) echo "HARD-FAIL (DET-1): Bundle-State-Projektion enthaelt Wiki-Pfad-Projektion nicht (alpha fehlt)" >&2; exit 1;; +esac +echo " Bundle-State-Projektion (deterministisch, wiederextrahierbar):" +echo "$B1" | sed 's/^/ /' +echo "RESULT: PASS — DET-1: BUNDLE_STATE_DEFINITION — Bundle-State = deterministische Projektion des committeten Git-States ((a) Baum gg. Baseline, (b) Kandidaten-, (c) Plan-/Reihenfolge-/Entscheidungs-Outputs); Extraktion zweimal byte-identisch (AD-17h/A0-19); keine eigene Engine (D-3/AD-11)" + +# ===================================================================================== +# DET-2 ZWEI_RUN_IDENTISCH (nicht-vakuum) — §5.14 Pkt. 2 +# ===================================================================================== +runlabel "DET-2: ZWEI_RUN_IDENTISCH (nicht-vakuum) — zwei unabhängige Läufe über demselben committeten Baum -> identische Bundle-States bis auf at; echte Content-Hashes (Witness weicht byte-weise von Baseline ab)" +run2() { # $1 = Run-Name ; führt die Instruktion über dem committeten Baum aus + isolate "$1" + cat > raw/alpha-v2.md <<'EOF' +### S-3 +Evidenz v2: Alpha erweitert um eine synchrone Kopplung. +EOF + git add -A && git commit -qm "Evidenz v2" + # Plan-/Kandidaten-Output (§5.14 Pkt. 2: identische Plan-/Kandidaten-/Reihenfolge-Outputs) + local plan + plan="cand=alpha;form=update;graphic=aktualisieren;baseline=$BASE" + # Mutations-Commit als ein commitierter Run-Ausgangszustand (unterschiedliches at je Run: + # A0-20-Konvention — der at-Wert ist Wanduhr, NICHT Teil des deterministischen Vergleichs) + cat > wiki/alpha.md <<'EOF' +--- +type: concept +sources: + - resource: raw/alpha-v1.md + id: s1 + - resource: raw/alpha-v2.md + id: s3 +generated: + by: wow-compiler/0.1.0 + at: RUNAT +--- +Das Alpha-Protokoll definiert eine deterministische Init-Sequenz (raw/alpha-v1.md#S-1). +Alpha verwendet ausschließlich lokale Netze (raw/alpha-v1.md#S-2). +Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3). +EOF + # at-Maskierung für den deterministischen Vergleich (§5.14 Pkt. 3): DET-2 demonstriert + # die Identität der NICHT-at-Bestandteile (Plan-, log-, index-, alpha-Content + TREE) — + # dafür wird die at-Zeile vor dem Hash auf ein festes Token normalisiert (die at-Varianz + # selbst ist die benannte Ausnahme, A0-20; ihre Behandlung demonstriert DET-4 positiv und + # negativ). Die Ausnahme ist dokumentiert, kein stiller Ausschluss; alle übrigen + # Bestandteile gehen byte-identisch in den Hash ein. + sed -i "s/^ at: .*/ at: AT/" wiki/alpha.md + log_bullet "- Determinismus-Bestätigung (Zwei-Run, §5.14 Pkt. 2): $plan; Baseline $BASE" + git add -A && git commit -qm "Run: alpha-Update ($1)" + # --- Bundle-State projizieren (deterministisch): echte Content-Hashes (nicht-vakuum) --- + echo "PLAN=$plan" + echo "SHA_ALPHA=$(git show 'HEAD:wiki/alpha.md' | sha256sum | cut -d' ' -f1)" + echo "ABS_BASELINE=$(git show "$BASE:wiki/alpha.md" | sha256sum | cut -d' ' -f1)" + echo "SHA_LOG=$(git show 'HEAD:wiki/log.md' | sha256sum | cut -d' ' -f1)" + echo "SHA_INDEX=$(git show 'HEAD:wiki/index.md' | sha256sum | cut -d' ' -f1)" + echo "TREE=$(git rev-parse 'HEAD:')" +} +echo "--- Lauf A (unabhängig) ---" +SA=$(run2 run2a) +echo "$SA" +echo "--- Lauf B (unabhängig, über demselben committeten Baum) ---" +SBV=$(run2 run2b) +echo "$SBV" +# Zwei unabhängige Läufe -> identische Bundle-States bis auf at +[ "$(echo "$SA" | grep '^PLAN=')" = "$(echo "$SBV" | grep '^PLAN=')" ] || { echo "HARD-FAIL (DET-2): Plan-/Kandidaten-Outputs weichen ab (AD-17h/A0-19, §5.14 Pkt. 2)" >&2; exit 1; } +[ "$(echo "$SA" | grep '^SHA_ALPHA=')" = "$(echo "$SBV" | grep '^SHA_ALPHA=')" ] || { echo "HARD-FAIL (DET-2): alpha-content-Hash weicht zwischen Runs ab (Byte-Differenz ausserhalb at, §5.14 Pkt. 3)" >&2; exit 1; } +[ "$(echo "$SA" | grep '^SHA_LOG=')" = "$(echo "$SBV" | grep '^SHA_LOG=')" ] || { echo "HARD-FAIL (DET-2): log.md-Hash weicht ab" >&2; exit 1; } +[ "$(echo "$SA" | grep '^SHA_INDEX=')" = "$(echo "$SBV" | grep '^SHA_INDEX=')" ] || { echo "HARD-FAIL (DET-2): index.md-Hash weicht ab" >&2; exit 1; } +[ "$(echo "$SA" | grep '^TREE=')" = "$(echo "$SBV" | grep '^TREE=')" ] || { echo "HARD-FAIL (DET-2): Bundle-Baum nach at-Maskierung weicht ab (Soll: byte-identisch, §5.14 Pkt. 2)" >&2; exit 1; } +# Nicht-vakuum-Witness: der produzierte Content weicht byte-weise von der Baseline ab +ABS_A=$(echo "$SA" | grep '^ABS_BASELINE=' | cut -d= -f2) +SHA_A=$(echo "$SA" | grep '^SHA_ALPHA=' | cut -d= -f2) +[ -n "$ABS_A" ] && [ -n "$SHA_A" ] || { echo "HARD-FAIL (DET-2): Witness-Hashes leer (Vakuum — Assertion wertlos)" >&2; exit 1; } +[ "$ABS_A" != "$SHA_A" ] || { echo "HARD-FAIL (DET-2): Witness == Baseline (vakuum — der Vergleich bewiese nichts; AD-17h/A0-19: echte Content-Identität gefordert)" >&2; exit 1; } +echo " WITNESS: Baseline-alpha-SHA ($ABS_A) != Run-alpha-SHA ($SHA_A) — der Zwei-Run-Vergleich ist nicht-vakuum (Content weicht von Baseline ab, echte Hashes)" +echo "RESULT: PASS — DET-2: ZWEI_RUN_IDENTISCH — zwei unabhängige Läufe über demselben committeten Baum produzieren identische Bundle-States (Plan-, log-, index-, alpha-Content-Hashes und Bundle-TREE byte-identisch, jeweils bis auf die benannte at-Ausnahme, die für den Vergleich maskiert ist); Vergleich nicht-vakuum (Witness vs. Baseline, echte Content-Hashes, §5.14 Pkt. 2, FT-10/AD-17h AC-1)" + +# ===================================================================================== +# DET-3 ZWEI_RUN_ABWEICHUNG (§5.14 Pkt. 4) +# ===================================================================================== +runlabel "DET-3: ZWEI_RUN_ABWEICHUNG — künstlich divergenter Lauf -> als AD-16-Klassifikationsdefekt klassifiziert und textuell benannt (kein Rauschen); korrigierter zweiter Lauf == erster Lauf (erneut bestätigt)" +# Referenz-Run (deterministische Bundle-State-Projektion) +run3_ref() { + isolate run3ref + cat > raw/alpha-v2.md <<'EOF' +### S-3 +Evidenz v2: Alpha erweitert um eine synchrone Kopplung. +EOF + git add -A && git commit -qm "Evidenz v2" + cat > wiki/alpha.md <<'EOF' +--- +type: concept +sources: + - resource: raw/alpha-v1.md + id: s1 + - resource: raw/alpha-v2.md + id: s3 +generated: + by: wow-compiler/0.1.0 + at: AT +--- +Das Alpha-Protokoll definiert eine deterministische Init-Sequenz (raw/alpha-v1.md#S-1). +Alpha verwendet ausschließlich lokale Netze (raw/alpha-v1.md#S-2). +Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3). +EOF + git add -A && git commit -qm "Run: alpha-Update (Referenz)" + echo "SHA=$(git show 'HEAD:wiki/alpha.md' | sha256sum | cut -d' ' -f1)" +} +# Divergenter Run: veränderter Body-Content (RAUSCHEN-fremde Abweichung — ein deterministischer +# Bestandteil weicht ab, hier eine andere Formulierung der Aussage) trotz gleichem Git-State+Input. +run3_div() { + isolate run3div + cat > raw/alpha-v2.md <<'EOF' +### S-3 +Evidenz v2: Alpha erweitert um eine synchrone Kopplung. +EOF + git add -A && git commit -qm "Evidenz v2" + cat > wiki/alpha.md <<'EOF' +--- +type: concept +sources: + - resource: raw/alpha-v1.md + id: s1 + - resource: raw/alpha-v2.md + id: s3 +generated: + by: wow-compiler/0.1.0 + at: AT +--- +Das Alpha-Protokoll definiert eine deterministische Init-Sequenz (raw/alpha-v1.md#S-1). +Alpha verwendet ausschließlich lokale Netze (raw/alpha-v1.md#S-2). +Alpha wird um eine SYNCHRONE KOPPLUNG erweitert (raw/alpha-v2.md#S-3). +EOF + git add -A && git commit -qm "Run: alpha-Update (divergent)" + echo "SHA=$(git show 'HEAD:wiki/alpha.md' | sha256sum | cut -d' ' -f1)" +} +R3=$(run3_ref) +D3=$(run3_div) +echo "Referenz-Run: $R3" +echo "Divergenter Lauf: $D3" +SHA_REF=$(echo "$R3" | cut -d= -f2) +SHA_DIV=$(echo "$D3" | cut -d= -f2) +[ -n "$SHA_REF" ] && [ -n "$SHA_DIV" ] || { echo "HARD-FAIL (DET-3): Hashes leer (Vakuum)" >&2; exit 1; } +if [ "$SHA_REF" = "$SHA_DIV" ]; then + echo "HARD-FAIL (DET-3): der divergente Lauf blieb inspiziert ununterscheidbar (Abweichung nicht erkannt; §5.14 Pkt. 4 verlangt Klassifikation)" >&2 + exit 1 +fi +echo "NFR-4-Benennung (textuell): ZWEI_RUN_ABWEICHUNG — Lauf 'divergent' weicht ausserhalb der benannten at-Ausnahme vom Referenz-Lauf ab (unterschiedlicher Content-Hash $SHA_DIV != $SHA_REF bei gleichem Git-State + gleichem Eingabeset) => AD-16-Klassifikationsdefekt (FT-10/AD-17h-AC), kein Rauschen; der Run wird als Fehler im Klassifikations-Mechanismus behandelt, textuell benannt und korrigiert/zurückgerollt (§5.14 Pkt. 4, Zustands-Restaurations-Invariante §5.13 Pkt. 3)" +echo "--- Korrigierter zweiter Lauf: rollt zurueck und wiederholt deterministisch (== Referenz) ---" +rollback3() { + git checkout -q "$BASE" -- wiki/ 2>/dev/null || true + git reset -q --hard "$BASE" + git clean -qfd wiki +} +rollback3 +R3B=$(run3_ref) +SHA_REFB=$(echo "$R3B" | grep '^SHA=' | cut -d= -f2) +[ "$SHA_REF" = "$SHA_REFB" ] || { echo "HARD-FAIL (DET-3): korrigierte Wiederholung weicht von der Referenz ab (AD-17h verletzt)" >&2; exit 1; } +echo " BEFUND: korrigierter Lauf == Referenz-Lauf (SHA $SHA_REF) — der Vertrag ist nach Korrektur erneut bestätigt (Pkt. 4: 'Befund wird (ggf. als korrigierter zweiter Lauf) erneut bestätigt')" +echo "RESULT: PASS — DET-3: ZWEI_RUN_ABWEICHUNG — künstlich divergenter Lauf wurde als AD-16-Klassifikationsdefekt erkannt (Content-Hash-Differenz bei gleichem State+Input — kein Rauschen, keine Umgebungs-Streuung) und textuell benannt (NFR-4); korrigierter zweiter Lauf reproduziert den Referenz-Bundle-State (Zustands-Restaurations-Invariante, §5.13 Pkt. 3; §5.14 Pkt. 4)" + +# ===================================================================================== +# DET-4 AT_GAP_AUSNAHME (§5.14 Pkt. 3) +# ===================================================================================== +runlabel "DET-4: AT_GAP_AUSNAHME — generated.at-Wanduhr-Gap ist die einzige benannte Ausnahme; zwei Runs mit unterschiedlichem at -> diff ausschließlich auf der at-Zeile; nach at-Maskierung byte-identisch; jede andere Differenz = AD-16-Klassifikationsdefekt" +isolate det4 +cat > raw/alpha-v2.md <<'EOF' +### S-3 +Evidenz v2: Alpha erweitert um eine synchrone Kopplung. +EOF +git add -A && git commit -qm "Evidenz v2" +mkrun4() { # $1 = at-Wert — schreibt alpha mit EXAKT unterschiedlichen at-Werten + cat > wiki/alpha.md <&2; exit 1; } +non_at=$(echo "$DABC" | grep '^[-+][^-+]' | grep -v '^[-+] at: ' | grep -v '^[+-][+-]') +if [ -n "$non_at" ]; then + echo "HARD-FAIL (DET-4): der diff zwischen den zwei Runs betrifft BESTANDTEILE ausserhalb der at-Ausnahme:" >&2 + echo "$non_at" | sed 's/^/ /' >&2 + exit 1 +else + echo " BEFUND: diff ausschließlich auf der at-Zeile (einzige benannte Ausnahme, §5.14 Pkt. 3)" +fi +echo "--- Nach at-Maskierung byte-identisch (restliche Bundle-Bestandteile) ---" +H1=$(git show HEAD~1:wiki/alpha.md | sed 's/^ at: .*/ at: AT/' | sha256sum | cut -d' ' -f1) +H2=$(git show HEAD:wiki/alpha.md | sed 's/^ at: .*/ at: AT/' | sha256sum | cut -d' ' -f1) +[ "$H1" = "$H2" ] || { echo "HARD-FAIL (DET-4): nach at-Maskierung weichen die Runs ab (bestandteil über at hinaus; §5.14 Pkt. 3 verlangt byte-Identität der übrigen Teile)" >&2; exit 1; } +echo " BEFUND: nach at-Maskierung byte-identisch (SHA $H1) — dokumentierte Ausnahme, kein stiller Ausschluss" +echo "--- Negative Kontrolle: eine Differenz AUSSERHALB der Ausnahme ist ein AD-16-Klassifikationsdefekt ---" +mkrun4 "2026-08-16T09:00:00Z" +printf '\nAndere Aussagenformulierung.\n' >> wiki/alpha.md +git add -A && git commit -qm "Run at=B' (Differenz im Body)" +non_at2=$(git diff HEAD~1 HEAD -- wiki/alpha.md | grep '^[-+][^-+]' | grep -v '^[-+] at: ' | grep -v '^[+-][+-]') +[ -n "$non_at2" ] || { echo "HARD-FAIL (DET-4): Body-Differenz wurde nicht erkannt (Negativkontrolle leer)" >&2; exit 1; } +echo "NFR-4-Benennung (textuell): Body-Differenz ausserhalb der at-Ausnahme-Menge => AD-16-Klassifikationsdefekt (kein Rauschen), textuell benannt (§5.14 Pkt. 3/4)" +echo "RESULT: PASS — DET-4: AT_GAP_AUSNAHME — generated.at-Wanduhr-Gap ist die einzige benannte Differenz im Bundle-State-Vergleich (A0-20-Konvention, §5.9 Pkt. 2/§5.10 Pkt. 8): zwei Runs diffieren ausschließlich in der at-Zeile, nach at-Maskierung byte-identisch; jede andere Differenz liegt ausserhalb der Ausnahme = AD-16-Klassifikationsdefekt (Negativkontrolle, §5.14 Pkt. 3)" + +# ===================================================================================== +# DET-5 EM_DASH (§3.2 Pkt. 1b, §5.14 Pkt. 5) +# ===================================================================================== +runlabel "DET-5: EM_DASH — Em-Dash — normalisiert auf dieselbe canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen (§3.2 Pkt. 1b: Kollaps-Klasse [-–— _] -> -)" +# Term-Basis mit Em-Dash / En-Dash / Bindestrich / Unterstrich / Leerzeichen-Separator +EM=$(norm "wissen — relevanz") +EN=$(norm "wissen – relevanz") +HY=$(norm "wissen - relevanz") +US=$(norm "wissen_relevanz") +SP=$(norm "wissen relevanz") +[ "$EM" = "$EN" ] || { echo "HARD-FAIL (DET-5): Em-Dash-Form != En-Dash-Form" >&2; exit 1; } +[ "$EM" = "$HY" ] || { echo "HARD-FAIL (DET-5): Em-Dash-Form != Bindestrich-Form" >&2; exit 1; } +[ "$EM" = "$US" ] || { echo "HARD-FAIL (DET-5): Em-Dash-Form != Unterstrich-Form" >&2; exit 1; } +[ "$EM" = "$SP" ] || { echo "HARD-FAIL (DET-5): Em-Dash-Form != Leerzeichen-Form" >&2; exit 1; } +case "$EM" in + *"—"*) echo "HARD-FAIL (DET-5): Em-Dash blieb in der canonischen Form erhalten (Kollaps-Klasse greift nicht)" >&2; exit 1;; +esac +echo " canonische Form (alle fünf Separatoren): '$EM'" +echo " Em-Dash-Term kollabiert auf dieselbe canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen (kein stiller Ausschluss, §3.2 Pkt. 1b)" +echo "RESULT: PASS — DET-5: EM_DASH — Em-Dash — ist in der Kollaps-Klasse [-–— _] -> - (§3.2-Pkt.-1b-Ergänzung, §5.14 Pkt. 5): Term mit Em-Dash erhält dieselbe canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen-Varianten — deterministisch, keine unterschiedliche canonische Form je Separator" + +# ===================================================================================== +# DET-6 KOLLAPS (§3.2 Pkt. 1b, §5.14 Pkt. 5) +# ===================================================================================== +runlabel "DET-6: KOLLAPS — Kollaps-Reichweite: Läufe (a--b), führende (-x), trailende (x-) -> Kollaps auf genau ein - + Trim (§3.2 Pkt. 1b)" +[ "$(norm "a--b")" = "a-b" ] || { echo "HARD-FAIL (DET-6): Lauf a--b kollabiert nicht auf a-b (norm='$(norm "a--b")')" >&2; exit 1; } +[ "$(norm "-x")" = "x" ] || { echo "HARD-FAIL (DET-6): führender Separator -x wird nicht getrimmt (norm='$(norm "-x")')" >&2; exit 1; } +[ "$(norm "x-")" = "x" ] || { echo "HARD-FAIL (DET-6): trailender Separator x- wird nicht getrimmt (norm='$(norm "x-")')" >&2; exit 1; } +[ "$(norm "a--b")" = "a-b" ] && [ "$(norm "a---b")" = "a-b" ] && [ "$(norm "---x---")" = "x" ] || { echo "HARD-FAIL (DET-6): Läufe/Trim-Kombination inkonsistent" >&2; exit 1; } +echo " Läufe a--b -> '$(norm "a--b")'; führend -x -> '$(norm "-x")'; trailend x- -> '$(norm "x-")'" +echo "RESULT: PASS — DET-6: KOLLAPS — Kollaps-Reichweite deterministisch (§3.2 Pkt. 1b, §5.14 Pkt. 5): Läufe kollabieren auf genau ein -, führende/trailende Separatoren werden getrimmt — glaubhaft re-executierbar, keine offene Reichweiten-Frage" + +# ===================================================================================== +# DET-7 MATCH_SCOPE (§3.2 Pkt. 2a, §5.14 Pkt. 5) +# ===================================================================================== +runlabel "DET-7: MATCH_SCOPE — Stufe a matcht ganze Wörter über den Body, exklusive YAML-Frontmatter (Substring-/Frontmatter-Treffer ausgeschlossen, §3.2 Pkt. 2a)" +isolate det7 +# Concept: Body enthält "kopplung" als GANZES Wort; Frontmatter enthält "kopplung" als +# Substring im Quell-Pfad raw/kopplung-v1.md (Frontmatter-Treffer-Wächter). +cat > wiki/alpha.md <<'EOF' +--- +type: concept +sources: + - resource: raw/kopplung-v1.md + id: s1 +generated: + by: wow-compiler/0.1.0 + at: 2026-08-16T09:00:00Z +--- +Alpha als Wissenseinheit: hier steht einzig das ganz Wort kopplung ohne weitere Bindung. +EOF +cat > wiki/gamma.md <<'EOF' +--- +type: concept +sources: + - resource: raw/gamma-v1.md + id: s1 +generated: + by: wow-compiler/0.1.0 + at: 2026-08-16T09:00:00Z +--- +Gamma: das Wort entkopplung belegt nur einenerweiternden Teil — kein eigener ganzer Treffer. +EOF +git add -A && git commit -qm "Stufe-a-Flex" +# 1) Substring-Kontrolle: 'kopplung' (ganz) trifft alpha; 'opplung' (Substring) trifft nichts +HIT1=$(match_stufe_a "kopplung" wiki/alpha.md wiki/gamma.md) +[ "$HIT1" = "alpha" ] || { echo "HARD-FAIL (DET-7): ganzes-Wort-Match 'kopplung' liefert '$HIT1' (Soll: alpha; Substring-/Gamma-Treffer unerlaubt)" >&2; exit 1; } +HIT2=$(match_stufe_a "opplung" wiki/alpha.md) +[ -z "$HIT2" ] || { echo "HARD-FAIL (DET-7): Substring-Match 'opplung' liefert einen Kandidaten (Stufe a matcht ganze Wörter, §3.2 Pkt. 2a)" >&2; exit 1; } +# 2) Frontmatter-Exklusion: Suchbegriff exakt gleich einem Frontmatter-RESOURCE-Substring +# (raw/kopplung-v1.md enthält 'kopplung') — zugleich im Body von alpha steht 'kopplung' +# nur als ganzes Wort => Treffer genau EINMAL (alpha). Der Frontmatter ist exkludiert, +# ein zusätzlicher Body-Treffer erzeugt keinen zweiten Kandidaten — wir prüfen, dass +# das Frontmatter-Vorkommen keinen falschen Kandidaten (z. B. durch RegExp über die ganze +# Datei inkl. Frontmatter) erzeugt. Konkret: wir legen einen zweiten Concept-Body VOR, der +# 'kopplung' NUR im Frontmatter traegt (Quell-Pfad raw/kopplung-mirror.md) — Stufe a muss +# ihn verwerfen, weil der Frontmatter exkludiert ist. +cat > wiki/mirror.md <<'EOF' +--- +type: concept +sources: + - resource: raw/kopplung-mirror.md + id: s1 +generated: + by: wow-compiler/0.1.0 + at: 2026-08-16T09:00:00Z +--- +Gamma-Mirror ohne Kopplungs-Begriff im Bodytext. +EOF +git add -A && git commit -qm "Frontmatter-only-Kandidat" +HIT3=$(match_stufe_a "kopplung" wiki/alpha.md wiki/gamma.md wiki/mirror.md) +[ "$HIT3" = "alpha" ] || { echo "HARD-FAIL (DET-7): Frontmatter-Treffer erzeugt Kandidat (mirror) — Stufe a matcht nur Body, exklusive YAML-Frontmatter (§3.2 Pkt. 2a)" >&2; exit 1; } +# 3) Direkte Formel-Probe der operativen Stufe-a-Formel (§3.2-Pkt.-2a-Zweistufen-Mechanik): +# Sweep mit der Formel -> dann deterministischer Scope-Filter (ganze Wörter, Body, after second ---). +SWEEP=$(grep -rl 'kopplung' --exclude=log.md wiki/ | LC_ALL=C sort) +# Sweep-muss alpha, gamma (Substring entkopplung) und mirror (Frontmatter-only) finden — +# der Scope-Filter verwirft gamma+mirror; als Kandidaten bleiben die Body-ganz-Wort-Treffer. +FILTERED=$(for f in $SWEEP; do + if match_stufe_a "kopplung" "$f" | grep -q .; then basename "$f" .md; fi +done | LC_ALL=C sort | tr '\n' ' ') +FILTERED="${FILTERED% }" +[ "$FILTERED" = "alpha" ] || { echo "HARD-FAIL (DET-7): operative Stufe-a-Zweistufen-Mechanik liefert '$FILTERED' (Soll: alpha) — Scope-Filter unvollständig (§3.2 Pkt. 2a, §5.14 Pkt. 5)" >&2; exit 1; } +echo " Direkte Formel-Probe: Sweep (grep -rl) -> Scope-Filter verwirft Substring-/Frontmatter-Treffer -> Kandidat: alpha" +echo "RESULT: PASS — DET-7: MATCH_SCOPE — Stufe a matcht ganze Wörter (Wortgrenzen) über den Body, exklusive YAML-Frontmatter: Substring-Treffer ('opplung') und Frontmatter-only-Kandidaten (mirror) liefern keine Kandidaten (§3.2 Pkt. 2a, §5.14 Pkt. 5) — deterministischer Stufe-a-Scope, keine falschen Kandidaten; operative Zweistufen-Mechanik (Sweep+Filter) abgesichert" + +# ===================================================================================== +# DET-8 ORPHAN (§5.10 Pkt. 8, §5.14 Pkt. 5) +# ===================================================================================== +runlabel "DET-8: ORPHAN — neu committete raw/-Evidenz ohne Ziel-Pfad-Treffer -> unzugeordnet, log.md-verwaist protokolliert (Datumsgruppe, ), kein Banner, keine stille Vorbearbeitung, keine eigenständige Anlage (AD-16-Default)" +isolate det8 +cat > raw/orphan-v1.md <<'EOF' +### S-1 +Evidenz: gänzlich fremdes Thema, das in keinem bestehenden Concept-Body Wort-Treffer hat. +EOF +git add -A && git commit -qm "Verwaiste Evidenz" +# Ziel-Pfad-Treffer-Prüfung: Term über die neuen Quellen enthält 'fremdes-thema' — kein +# bestehender Concept-Body trifft (Stufe a, deterministisch); kein Update-Kandidat. +CAND=$(match_stufe_a "fremdes" wiki/alpha.md wiki/gamma.md) +[ -z "$CAND" ] || { echo "HARD-FAIL (DET-8): verwaiste Evidenz erzielt einen Ziel-Pfad-Treffer (Kein-Orphan erwartet)" >&2; exit 1; } +# Reconcile-Orphan-Regel (§5.10 Pkt. 8 / §5.14 Pkt. 5): deterministisch aus dem committeten +# Git-State (Zuwachs gg. ) als verwaist befunden -> datumsgruppierter +# log.md-Eintrag (Header YYYY-MM-DD, Quell-Pfad + ); keine eigenständige Anlage. +log_bullet "- Reconcile-Orphan (Story 3.8; §5.10 Pkt. 8 / §5.14 Pkt. 5): raw/orphan-v1.md (Zuwachs gg. ) ohne Ziel-Pfad-Treffer — unzugeordnet, verwaist protokolliert; kein Banner, keine stille Vorbearbeitung, keine eigenständige Anlage (AD-16-Default, Epic-4-Interface)" +echo "--- Kein Banner / keine stille Vorbearbeitung / keine eigenständige Anlage ---" +if [ -f wiki/orphan.md ]; then + echo "HARD-FAIL (DET-8): verwaiste Evidenz wurde eigenständig als Concept angelegt (verboten, AD-16-Default)" >&2 + exit 1 +fi +# Nur log.md ist mutiert (Orphan-Eintrag) — Erhaltungs-Invariante §5.9 Pkt. 5 (log.md ist +# erlaubtes Mitglied des Diff-Selbsttest-Satzes); keine weiteren Mutations-Pfade. +MUT=$( { git diff --name-only "$BASE" -- wiki/ ; git status --porcelain -- wiki/ | awk '{print $2}'; } | sed -e 's|^wiki/||' -e 's|\.md$||' | LC_ALL=C sort -u) +[ "$MUT" = "log" ] || { echo "HARD-FAIL (DET-8): Verwaist-Run mutiert ausserhalb {log} — Pfade: [$MUT]" >&2; exit 1; } +grep -qF "Reconcile-Orphan" wiki/log.md || { echo "HARD-FAIL (DET-8): Verwaist-Protokoll fehlt in log.md (§5.10 Pkt. 8)" >&2; exit 1; } +grep -qF "## 2026-08-20" wiki/log.md || { echo "HARD-FAIL (DET-8): log.md-Eintrag nicht in Datumsgruppe (Vertrag §5)" >&2; exit 1; } +grep -qF "$BASE" wiki/log.md || { echo "HARD-FAIL (DET-8): fehlt im Verwaist-Eintrag (§5.10 Pkt. 8, deterministisch auflösbar D-2)" >&2; exit 1; } +echo " BEFUND: raw/orphan-v1.md bleibt in raw/ unangetastet (AD-3); log.md trägt datumsgruppierten Verwaist-Eintrag mit " +echo "RESULT: PASS — DET-8: ORPHAN — neu committete raw/-Evidenz ohne Ziel-Pfad-Treffer bleibt unzugeordnet und wird als datumsgruppierter log.md-Eintrag (Quell-Pfad + ) verwaist protokolliert (§5.10 Pkt. 8 / §5.14 Pkt. 5): kein Banner, keine stille Vorbearbeitung, keine eigenständige Anlage (AD-16-Default) — Erhaltungs-Invariante gewahrt (nur log.md mutiert)" + +echo +echo "===== Sandbox abgeschlossen (DET-1..DET-8) =====" +echo "Sandbox-Root: $ROOT (loeschbar: rm -rf $ROOT)" diff --git a/_bmad-output/implementation-artifacts/spec-3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato.md b/_bmad-output/implementation-artifacts/spec-3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato.md new file mode 100644 index 0000000..3872d4c --- /dev/null +++ b/_bmad-output/implementation-artifacts/spec-3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato.md @@ -0,0 +1,162 @@ +--- +title: 'Story 3.8 — Determinismus-Vertrag (AD-17h) als Agent-Instruktions-Validator umsetzen' +type: 'feature' +created: '2026-08-20' +status: 'done' +baseline_commit: 'c4cdf4b93e17b3f84dff03a4bd5608251be56268' +review_loop_iteration: 0 +context: + - '_bmad-output/implementation-artifacts/epic-3-context.md' +--- + + + +## Intent + +**Problem:** AD-17h/FT-10/A0-19 verlangen: Über denselben Git-State + dasselbe Eingabeset erzeugen **zwei unabhängige Runs denselben Bundle-State**; eine Abweichung ist ein Fehler der AD-16-Klassifikation, kein Rauschen. Das **Enforcement** lebt im MVP (D-3, Q-6) als **Agent-Instruktions-Validator** und muss **mechanisch bestätigt** sein, bevor es tragend wird. Der Ist-Zustand der Instruktion verankert den Vertrag zwar an vielen Stellen (AD-17h-Rückverweise in §3.2/§5.9/§5.10/§5.11/§5.12/§5.13), aber es fehlt die **geschlossene, aus dem committeten Git-State ableitbare Bestätigungs-Mechanik**: Es gibt keinen normativen Ort, der definiert, (a) was genau der „Bundle-State" ist, (b) wie die Zwei-Run-Bestätigung mechanisch abläuft, (c) welche **Ausnahmen** vom byte-identischen Vergleich gelten (namentlich der dokumentierte `generated.at`-Wanduhr-Gap, A0-20) und (d) wie eine festgestellte Abweichung klassifiziert wird (AD-16-Klassifikationsfehler). Mehrere bekannte Lücken sind hierher gewandert (Em-Dash-Normalisierung, Kollaps-Reichweite, Match-Scope, `at`-Gap, Orphan-Politik, Misch-Run-Coverage). + +**Approach:** Neue Sektion **§5.14 „Determinismus-Vertrag & Agent-Instruktions-Validator (Story 3.8)"** (nach §5.13, vor §6): definiert (1) den **Bundle-State** als deterministische Projektion des committeten Git-States (vergleichbare Zustandsmenge, `at`-Feld als benannte Ausnahme), (2) die **Zwei-Run-Bestätigungs-Mechanik** als textuell festgehaltenes, re-executierbares Prüfverfahren (Vergleichs-Operandum = committeter Baum; identische Plan-/Kandidaten-/Reihenfolge-Outputs; kein neuer Prozess/Server/MCP, D-3), (3) die **Ausnahme-Menge** des Bundle-State-Vergleichs (der `generated.at`-Wanduhr-Gap als dokumentierte A0-20-Konvention; sonst byte-identisch) und (4) die **Abweichungs-Klassifikation** (jede Abweichung außerhalb der Ausnahme = AD-16-Klassifikationsdefekt, textuell benannt, NFR-4). Die Zwei-Run-Bestätigung wird als **Sandbox-Szenario** mechanisch demonstriert; die bekannten Lücken (Em-Dash, Kollaps-Reichweite, Match-Scope, Orphan) werden als **geschlossene, deterministische Regeln** in die Instruktion gehoben — keine offenen Fragen verbleiben, die die Zwei-Run-Identität gefährden. + +## Boundaries & Constraints + +**Always:** +- Nur `schema/compiler.md` (neue §5.14 + §7-Auflösung des Determinismus-Vorbehalts + §8 Revisionslog **Revision 3.3** + gegebenenfalls Kollaps-/Match-Scope-/Orphan-Präzisierungen in §3.2/§5.10) mutiert (D-3). `schema/validator.md`, `schema/wiki-compiler.md`, `adapters/`, `raw/` **read-only** (AD-3). Kein Standalone (D-3), keine eigene Workflow-Engine/kein neuer Prozess/Server/MCP (AD-6, AD-11). Keine neue §7-Invaliditätsklasse, kein Vertrags-Change, kein neuer Prädikat-/Format-/Frontmatter-Key. +- Deterministisch aus dem committeten Git-State ableitbar (AD-17h/A0-19): Bundle-State-Vergleich, Zwei-Run-Bestätigungs-Mechanik, Ausnahme-Menge, Abweichungs-Klassifikation. **Keine Wanduhr/`now`-Steuerung** der Bestätigungs-Mechanik. +- Der `generated.at`-Wanduhr-Gap **bleibt als dokumentierte Ausnahme** bestehen (A0-20-Konvention, §5.9 Pkt. 2, §5.10 Pkt. 8, unverändert bindend bis Ask-First-Wechsel). §5.14 **definiert** die Behandlung von `at` im Bundle-State-Vergleich (Ausnahmemenge), ändert aber **nicht** das `generated.at`-Verhalten selbst. +- Bei einer Abweichung zweier Runs: die Abweichung **ist** ein AD-16-Klassifikationsfehler (kein akzeptables Rauschen, FT-10/AD-17h-AC); die textuelle Benennung (NFR-4) ist verpflichtend. +- Die **normalisierenden Lücken-Schließungen** (Em-Dash in der Kollaps-Klasse, Kollaps-Reichweite bei Läufen/führenden/trailenden Separatoren, Wortgrenzen-/Frontmatter-Scope der Stufe-a-Erhebung) werden als **deterministische Regel-Ergänzungen** in §3.2 umgesetzt — **append-only/kein Umbruch** des bestehenden §3.2-Wortlauts; die Orphan-Politik (§5.10 Pkt. 8) wird zu einer deterministischen Reconcile-Orphan-Regel präzisiert. +- Die Bestätigung ist **agent-instruction-basiert (D-3, Q-6)**: ein Agent führt die Instruktion aus und bestätigt in einer Session die Zwei-Run-Identität — kein dedizierter Validator-Prozess, keine extra Runtime. + +**Ask First:** +- **Änderung des `generated.at`-Verhaltens** selbst (z. B. Ableitung `at` aus dem Git-State statt Wanduhr) — §5.14 definiert nur seine Behandlung im Vergleich, der Konventionswechsel wäre Ask-First. +- Einführung einer **eigenständigen, ausführbaren Validator-Datei** (separates Skript/Programm außerhalb der Instruktion als Enforcer) statt der textuellen Agent-Instruktions-Disziplin — wäre ein Realisierungswechsel weg vom D-3/Q-6-Modell. +- Kollaps-Reichweite bei Läufen/führenden/trailenden Separatoren **anders** zu definieren als „Kollaps auf genau ein `-` + Trim" (z. B. Doppel-Bindestrich-Erhaltung) — jede andere Wahl bricht bestehende Sandbox-Erwartungen. +- Umbenennung/Neudefinition der vorhandenen §3.2-Erhebungsstufen (a/b/c) oder deren Reihenfolge. + +**Never:** +- `raw/`-Inhalte verändern (AD-3); uncommittete fremde `wiki/`-Änderungen löschen (AD-17e); textueller Auto-Merge bei Branch-Konvergenz (AD-17c); Wanduhr/`now`-Zeitstempel als Bestätigungs-Steuergröße; eigener `# Log`-Stand in der Registry; Standalone-Compiler/eigene LLM-Runtime (D-3, AD-11); Änderung an `schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`; neuer Frontmatter-Key; neue §7-Invaliditätsklasse; neuer Prädikat-/Format-Key; eigene Workflow-Engine; neuer dedizierter Prozess/Server/MCP als Enforcer. + +## I/O & Edge-Case Matrix + +| Scenario | Input / State | Expected Output / Behavior | Error Handling | +|----------|--------------|---------------------------|----------------| +| BUNDLE_STATE_DEFINITION | gleicher committeter Git-State + gleiche Eingabemenge | Bundle-State definiert als deterministische Projektion: Datei-Gesamtheit unter `wiki/`/`raw/` gg. Baseline, Plan-/Kandidaten-/Reihenfolge-Outputs; `generated.at` als benannte Ausnahme | textuell begründet (NFR-4), keine Lücke | +| ZWEI_RUN_IDENTISCH | zwei unabhängige Runs, gleicher Git-State + Eingabeset | identische Bundle-States bis auf benannte `at`-Ausnahme; Sandbox-Assertion nicht-vakuum (echte Content-Identität) | PASS; bei Abweichung außerhalb Ausnahme: AD-16-Klassifikationsdefekt | +| ZWEI_RUN_ABWEICHUNG | zwei Runs, gleicher State, verschiedene Ausgabe | Abweichung = Fehler der AD-16-Klassifikation (kein Rauschen); textuell benannt, Run korrigiert/rollt zurück | NFR-4-Benennung; AD-17h-AC | +| AT_GAP_AUSNAHME | zwei unabhängige Runs, gleicher Input | `generated.at` darf abweichen (A0-20-Konvention, §5.9 Pkt. 2) — einzige benannte Ausnahme im Bundle-State-Vergleich; übrige Teile byte-identisch | dokumentiert (kein stiller Ausschluss) | +| NORMALISIERUNG_EM_DASH | Term mit Em-Dash `—` | Em-Dash in die Kollaps-Klasse aufgenommen (`[-–— _]`→`-`); identische canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen | deterministisch, kein stiller Ausschluss | +| NORMALISIERUNG_KOLLAPS | Term mit Läufen/führenden/trailenden Separatoren | Kollaps-Reichweite definiert: Kollaps auf genau ein `-` + Trim (führende/trailende entfernt), Läufe auf ein `-` | deterministisch, glaubhaft re-executierbar | +| MATCH_SCOPE_STUFE_A | Stufe-a-grep-Treffer mit/ohne Wortgrenze, Frontmatter-Treffer | Match-Semantik fixiert: ganzes Wort (Wortgrenzen), Frontmatter exkludiert (nur Body) | deterministisch, keine falschen Kandidaten | +| ORPHAN_POLITIK | neu committete `raw/`-Evidenz ohne Ziel-Pfad-Treffer | Orphan bleibt unzugeordnet, wird in `log.md` als verwaist protokolliert, kein Banner, keine stille Vorbearbeitung | deterministische Reconcile-Orphan-Regel (AD-16-Default) | + +## Code Map + +- `schema/compiler.md` — **primär mutiert** (D-3): neue Sektion **§5.14 „Determinismus-Vertrag & Agent-Instruktions-Validator (Story 3.8)"** (nach §5.13, vor §6; Fixierung: §5.13-Ende Z. 362, §6-Start Z. 364 — neue Sektion zwischen beide, §5.14 Z. 364–381 ca.); §0-Phasen-Listentext **unverändert**; §5.13 Pkt. 7 „Home Story 3.8" — wird auf §5.14-**Anker** umgehängt (die `generated.at`-Gap-Ausnahme ist jetzt in §5.14 definiert statt nur deklariert; Home-Verweis bleibt, wird aber auf die §5.14-Definition verlagert); §3.2 Normalisierungs-Lücken (Em-Dash in Kollaps-Klasse Z. 51; Kollaps-Reichweite; Match-Scope Z. 55) — als Regel-Ergänzungen aufgelöst; §5.10 Pkt. 8 Orphan-Politik Z. 301 — zur deterministischen Reconcile-Orphan-Regel präzisiert; §7 (`Z. 409ff.`) Determinismus-Vorbehalt „Em-Dash-Lücke an Story 3.8 übergeben" — **aufgelöst**, Verankerung in §5.14 benannt; §8-Normreferenz `AD-17h` (`Z. 430`) auf **§5.14-Anker** angehoben (mit der `at`-Ausnahme-Nennung); Revisionslog-Eintrag **Revision 3.3** nach Z. 461. Anker (IST-Zeilen nach Implementierung): §5.14-Sektion Z. ≈364; §7-Determinismus-Bullet nach Z. 420; §8-AD-17h in Z. 430; Revisionslog **Revision 3.3** nach Z. 461. +- `wiki/log.md` — **append** (append-only, Vertrag §5): Story-3.8-Eintrag (Verankerung, Sandbox-Nachweis, Statuswechsel, Validator-Verdikt); bestehende Bullets unverändert. +- `_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh` — **neu** (re-executierbar, Muster sandbox-3-7, Exit 0): Szenarien DET-1..DET-8 (s. Design Notes), harte Pass/Fail-Assertionen, Zwei-Run-Identität nicht-vakuum, keine Berührung des realen Ist-Baums. +- `_bmad-output/implementation-artifacts/sprint-status.yaml` — **mutiert**: `3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato` `backlog` → `in-progress` (Implementierungs-Flip) → `review` (Review-Start-Flip, Step-04; finaler `done`-Flip im Step-05); `last_updated` (Format `MM-DD-YYYY HH:MM`, HEAD-Präzision). +- `_bmad-output/implementation-artifacts/deferred-work.md` — **append** (append-only): ggf. Story-3.8-Defers; die bestehenden „Home: Story 3.8"-Einträge werden **aufgegriffen/geschlossen** — nicht als Nur-Read-markiert, sondern als aufgehobene Homes gekennzeichnet (Status-Eintragung). Stand: mehrere determinismus-bezogene Defer-Homes (Em-Dash, Kollaps, Match-Scope, Orphan, `at`-Gap, Misch-Run-Coverage) werden in §5.14/§3.2/§5.10 geschlossen; verbleibende Homes (falls nicht schließbar) bleiben offen mit verbleibendem Ziel. +- `_bmad-output/implementation-artifacts/epic-3-context.md`, `spec-3-7-…md` — **read-only** (continue-context; Kette unverändert). + +**Read-only evidence (AD-3):** `schema/validator.md`, `schema/wiki-compiler.md`, `adapters/`, `raw/` (inkl. `raw/architecture-spine/…md` AD-17h/Q-6/FT-10/D-3, `raw/epics/epics-2026-08-14.md` A0-19/A0-20 — normativer Rückbezug, keine Mutation). `schema/canonical-terms.md` bleibt append-only-Registry (keine Änderung an Bestandseinträgen; die Em-Dash-/Kollaps-Schließung lebt als Regel in `compiler.md` §3.2, nicht als Registry-Edits — §3.2-Pkt.-1b-Kollaps-Klasse ist die zentrale Normalisierungsregel). + +## Tasks & Acceptance + +**Execution:** +- [x] `schema/compiler.md` — §5.14 einfügen (nach §5.13, vor §6): Bundle-State-Definition, Zwei-Run-Bestätigungs-Mechanik (agent-Instruktions-basiert, D-3/Q-6, re-executierbare Formeln), `at`-Ausnahme-Menge, Abweichungs-Klassifikation als AD-16-Klassifikationsdefekt; §0/§5.13/§6 Wortlaut-unverändert referenzieren; kein neuer Prädikat-/Format-/Frontmatter-Key +- [x] `schema/compiler.md` — §3.2-Normalisierungs-Lücken schließen (Em-Dash-Klasse, Kollaps-Reichweite, Match-Scope der Stufe a) — als deterministische Regel-Ergänzungen ohne Umbruch des bestehenden §3.2-Wortlauts; Orphan-Politik §5.10 Pkt. 8 zur deterministischen Reconcile-Orphan-Regel präzisieren +- [x] `schema/compiler.md` — Revision 3.3 in §8 belegen (AD-17h auf §5.14-Anker, `at`-Ausnahme-Nennung, Abschlussklausel); §7-Determinismus-Vorbehalt auflösen (Verankerung in §5.14) +- [x] `_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh` — Szenarien DET-1..DET-8 (Bundle-State-Definition, Zwei-Run-identisch nicht-vakuum, Zwei-Run-Abweichung klassifiziert, `at`-Gap-Ausnahme, Em-Dash-, Kollaps-, Match-Scope-, Orphan-Szenario), Exit 0 +- [x] `_bmad-output/implementation-artifacts/sprint-status.yaml` — Key `3-8-…` → `in-progress` (Implementierung) → `review` (Review-Start); `_bmad-output/implementation-artifacts/deferred-work.md` — Story-3.8-Defers bzw. aufgegriffene/geschlossene „Home: Story 3.8"-Einträge kennzeichnen +- [x] `wiki/log.md` — (Implementierung) Story-3.8-Eintrag, `sprint-status.yaml` → in-progress (Implementierung) bzw. `review` (Review-Start, Step-04); Review-Abschluss `done` im Review-Schritt (Workflow-Konvention) + +**Acceptance Criteria:** +- Given einen Fixieren Git-State + feste Eingabemenge, when zwei unabhängige Runs ausgeführt werden, then produziert §5.14-Wortlaut identische Bundle-States bis auf die benannte `at`-Ausnahme (FT-10, AD-17h, AC-1). +- Given eine Abweichung bei zwei solchen Runs, when sie festgestellt wird, then wird sie als Fehler im AD-16-Klassifikations-Mechanismus behandelt und textuell benannt (nicht als akzeptables Rauschen) (AD-17h, AC-2). +- Given der MVP (D-3), when die Determinismus-Enforcement fehlt, then lebt sie als Agent-Instruktions-Validator (§5.14) und ist als mechanisch durch die Sandbox bestätigt (Q-6, A0-19; AC-3). +- Given der Validator, when umgesetzt, then hält er keine Embedding-/Vector-Infrastruktur vor (AD-13; FT-3, FT-4; AC-4) und erzeugt keine eigene Runtime/kein neues Werkzeug (D-3, AD-11). + +## Spec Change Log + + + +### Review-Loop-1 (2026-08-20, Step-04) + +**Ergebnis:** keine intent_gap / kein bad_spec; 0 Loopback. Review-Schicht 3 Subagenten (blind-hunter / edge-case-hunter / verification-gap, synchron); Triage: 14 Patch / 0 defer / Rest Reject (ausführliche Reject-Begründung im Story-Protokoll `wiki/log.md`). Alle Patches rein dokumentarischer Natur (Klarstellung/Verweis/Status); Semantik unverändert, keine neue Vertragsentscheidung. + +**Patch-Stapel (in dieser Runde angewandt):** +- §3.2-Pkt.-1b (b): paketierte Kollaps-Klasse in der Operativ-Klausel auf die geschlossene `[-–— _]`-Klasse angehoben; Verweis auf den Append-Block als maßgeblich (KEEP: die append-only-Schließung bleibt unverändert; der Operativ-Satz ist jetzt konsistent). +- §3.2-Pkt.-2a: Match-Scope (ganze Wörter über den Body, exklusiv Frontmatter) in die operative Stufe-a-Formel gewirkt — Einzel-Term-Klausel + Mehrfach-Term-Vereinigung (Pkt. 1c) verdeutlicht; Body-Abgrenzung (nach der zweiten `---`-Zeile) bestimmt. +- §3-Pkt.-2-Kandidatenliste (und damit §5.9-Worked Example): Stufe-a-Scope-Verweis ergänzt. +- §5.14-Pkt.-2: Zwei-Run-Abgleich als Vergleich der beiden Run-Ausgänge gegeneinander (nicht nur je Lauf gg. Baseline) verdeutlicht — Beispiel `git diff ` ergänzt. +- §5.14-Pkt.-1-Intro: AD-3-Schutzliste um `adapters/` ergänzt. +- §5.10-Pkt.-8: die pre-existing-Orphan-Obligationsformulierung als vorbestehend markiert (Verweis auf die neue deterministische Regel unten; keine Staffelung an Story 3.8/Epi-4 mehr). +- `deferred-work.md`: Bezugs-Eintrag-Nummern der Story-3.2-review-Defers korrigiert (Kollaps Eintrag 3 → 2; Match-Scope Eintrag 2 → 1). +- `wiki/log.md`: „8 `### Aufgegriffen`-Blöcke" → „7 `### Aufgegriffen`-Blöcke + 1 `### Aufgegriffen (teilweise)`". +- `sandbox-3-8/run-sandbox.sh`: DET-2-at-Maskierungszweck als Kommentar klargestellt (belegt die Nicht-at-Bestandteile; at-Varianz demonstriert DET-4); DET-1-Demo-Kommentar (Kandidaten-/Form-Outputs als redaktionell verdichtete Run-Feststellungen). +- `sprint-status.yaml`: Key `3-8-…` → `review` (Review-Start-Flip; finaler `done`-Flip im Step-05). +- `spec`-Frontmatter: `status: 'in-review'` (Review-Start per Step-04), `review_loop_iteration: 0` unverändert; SRO-Review-Loop-1-Hinweis ergänzt. + +**Rejected-Findings (Kurznotation, nicht Teil der Patches):** Stufe-a-Formel-Änderung nicht nötig (die Formel `rg -l`/`grep -rl` + Scope-Klausel bleibt die Instruktionsform; die Wortgrenzen-/Frontmatter-Semantik reist über die Pkt.-2a-Klausel, nicht über ein Flag); DET-2-Plan-Literal (dev-demo, echte Content-Hashes decken; Kandidaten-Ableitung über DET-1/DET-8); DET-8-hardcodierter Verwaist-Befund (Mechanik textuell, Existenz-negativ-Kontrolle hart); §5.14-`raw/`-Input-Verdacht (Pkt.-1a nennt `raw/`-Zuwächse bereits explizit „als Input"); §5.14-„kommt erstellt der Diff" — keine Formel-Verschmelzung; DET-2-maskierte-`at` (Display-Maske, DET-4 behandelt Varianz); Log-Overcount (Patch 9, siehe oben); Umlaut-Aufschlag (behandelt als Patch-7-Fundament); Sprint-Last-Updated-Timing (Konvention); §3.2-„keine offene Frage"(Umlaut bleibt dokumentiert offen, Wortlaut angepasst). + +## Design Notes + +**Warum §5.14 als eigene Sektion, nicht §6.5-Erweiterung?** §6.5 ist die „Determinismus- & Selbsttest-Norm" mit **drei** Nachprüf-Kriterien (Vollständige §3-Subset-Konformität, `at`-Normalform, `sources`-Existenz) — die projektions-seitige Content-Prüfung je erzeugtem Concept. Der Determinismus-*Vertrag* (AD-17h/FT-10) ist die **Cross-Run-Eigenschaft** (zwei unabhängige Runs → gleicher Bundle-State), kein Einzel-Concept-Kriterium. §5.14 ist die geschlossene Verankerung dieser Cross-Run-Eigenschaft: (a) **Bundle-State-Definition** (welche Zustandsmenge ist „der Bundle-State" — die committete Baum-Projektion unter `wiki/`/`raw/` zzgl. Plan-/Kandidaten-/Reihenfolge-Outputs; `generated.at` als benannte Ausnahme), (b) **Zwei-Run-Bestätigungs-Mechanik** (agent-Instruktions-basiert; der Produzent führt die Instruktion zweimal über demselben committeten Git-State aus und vergleicht die Bundle-States; re-executierbare Formeln), (c) **Ausnahme-Menge** (allein `generated.at`-Wanduhr-Gap, dokumentiertes A0-20; Nichts sonst), (d) **Abweichungs-Klassifikation** (jede Differenz außerhalb der Ausnahme = AD-16-Klassifikationsfehler; textuell benannt NFR-4; kein stiller Vorbeilass). Damit ist die bisher „offen verankerte" AD-17h-Eigenschaft (viele Rückverweise, kein normativer Ort der Bestätigung) zu einem **instruierten, mechanisch bestätigbaren Verfahren** verdichtet. + +**Die Normalisierungs- und Match-Lücken werden deterministisch geschlossen, nicht nur notiert.** Die Kollaps-Klasse in §3.2 Pkt. 1b ist `[-–_ ]` (En-Dash –, Bindestrich -, Unterstrich _, Leerzeichen) — der Em-Dash `—` fehlt (bekannte Story-3.2-Lücke mit Home Story 3.8). Die Schließung ist eine **Ergänzung der Kollaps-Klasse** um den Em-Dash (`[-–— _]` → `-`) sowie die Festlegung der **Kollaps-Reichweite** (jedes Vorkommen → genau ein `-`; führende/trailende Separatoren werden getrimmt — die bereits in der Sandbox etablierte Semantik) und des **Match-Scope** der Stufe a (Stufe-a-grep-matcht **ganze Wörter** über den Body, exklusive YAML-Frontmatter — `rg -l '' -g '!log.md' wiki/` erhält einen deterministischen Scope; Substring- und Frontmatter-Treffer werden ausgeschlossen). §5.10 Pkt. 8 (Orphan) erhält eine **deterministische Reconcile-Orphan-Regel**: neu committete `raw/`-Evidenz ohne Ziel-Pfad-Treffer bleibt unzugeordnet, wird in `log.md` als verwaist protokolliert (Datumsgruppe, ``), kein Banner/keine stille Vorbearbeitung. Diese Schließungen machen die relevanz-/synthese-seitigen Erhebungen über den committeten Zustand vollständig pinbar. + +**Die Sandbox (DET-1..DET-8, `bash run-sandbox.sh`, `/tmp`-Baum, Exit 0) demonstriert die Bestätigung mechanisch.** +- DET-1 BUNDLE_STATE_DEFINITION: erzeugt ein Mini-Bundle, definiert/extrahiert die Bundle-State-Projektion (wiki/-Dateien + Plan-/Kandidaten-/Reihenfolge-Outputs) deterministisch +- DET-2 ZWEI_RUN_IDENTISCH (nicht-vakuum): zwei unabhängige Läufe über demselben committeten Baum → identische Bundle-States bis auf `at`; die Assertion vergleicht echte Content-Hashes (nicht nur Vorhandensein) +- DET-3 ZWEI_RUN_ABWEICHUNG: künstlich divergenter Lauf → wird als AD-16-Klassifikationsdefekt klassifiziert und textuell benannt (kein Rauschen) +- DET-4 AT_GAP_AUSNAHME: zeigt, dass `generated.at`-Wanduhr-Gap die einzige benannte Ausnahme ist (übrige Teile byte-identisch) +- DET-5 EM_DASH: Term mit Em-Dash `—` normalisiert auf dieselbe canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen +- DET-6 KOLLAPS: Läufe (`a--b`), führende (`-x`), trailende (`x-`) → Kollaps auf genau ein `-` + Trim +- DET-7 MATCH_SCOPE: Stufe-a-matcht ganze Wörter über Body, exklusive Frontmatter (Substring-/Frontmatter-Treffer ausgeschlossen) +- DET-8 ORPHAN: neu committete Evidenz ohne Ziel-Pfad-Treffer → unzugeordnet, `log.md`-verwaist protokolliert, kein Banner/keine Mutation + +(Code-/Zahlgenauigkeiten: Szenario-Labels sind Fixierung der I/O-Matrix; die Implementierung trägt die harten Assertionen in der Sandbox.) + +## Verification + +**Commands (re-executierbar, ab Workspace-Root):** +1. `bash _bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh` — expected: DET-1..DET-8 harte PASS/Fail, Zwei-Run-Identität nicht-vakuum, Exit 0. +2. `grep -n "§5.14\|Revision 3.3" schema/compiler.md` — liefert §5.14-Sektion + Revisionslog-Eintrag; `grep -n "Determinismus-Vertrag & Agent-Instruktions-Validator" schema/compiler.md` — die §5.14-Überschrift wortgleich (inkl. §5.13-Seam-Satz in §5.14-Intro). +3. Read-only (AD-3): `git status --porcelain` zeigt keinen Change an `schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`/`raw/`. `schema/canonical-terms.md` unverändert (append-only-Registry unangetastet). +4. Validator-Lauf: alle `wiki/`-Dateien SUCCESS (unverändert, keine Inhalts-Mutation). +5. Auf den **`wiki/`-Scope begrenzt** (`git status --porcelain -- wiki/`): ausschließlich `wiki/log.md` (dieser Eintrag) — Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt; `sprint-status.yaml`/`deferred-work.md`/`sandbox-3-8/` liegen außerhalb `wiki/` und sind nicht Teil der Diff-Probe. + +**Zu beachten (beim step-04-Review):** (a) §0-Phasen-Listentext, §5.13-Phasen-Disziplin und §6/§6.5 müssen textuell **unverändert** bleiben — §5.14 verweist auf sie (Fugen-Identität); (b) der `generated.at`-Wanduhr-Gap **bleibt verhaltens-seitig unverändert** (A0-20-Konvention); §5.14 definiert nur seine Behandlung im Bundle-State-Vergleich (Ausnahmemenge) — ein Wechsel des `generated.at`-Verhaltens wäre Ask-First; (c) die vorhandene §8-Revisionslog-Nummer ist **3.2** (Story 3.7); **Revision 3.3 ist für Story 3.8 frei** (grep-verifiziert: keine 3.3 im Revisionslog); (d) kein neuer §7-Bullet ersetzt einen bestehenden — der Determinismus-Bullet wird **ergänzt** (Verankerungs-Verweis), die bestehenden Story-Bullets bleiben unverändert. + +## Suggested Review Order + + + +**§5.14-Determinismus-Vertrag (Kern, Einstieg)** + +- [compiler.md:365](../../schema/compiler.md#L365) — §5.14-Überschrift, Intro mit §5.13-Seam und AD-3-Schutzliste inkl. `adapters/`. +- [compiler.md:369](../../schema/compiler.md#L369) — Pkt. 1 Bundle-State-Definition: committete Baum-Projektion, `generated.at` als benannte Ausnahme (A0-20), FT-10/AD-17h/AC-1. +- [compiler.md:370](../../schema/compiler.md#L370) — Pkt. 2 Zwei-Run-Bestätigungs-Mechanik: zweimal über denselben committeten Git-State, Run-A↔Run-B-Abgleich (Beispiel `git diff`), keine Wanduhr-Steuerung. +- [compiler.md:374](../../schema/compiler.md#L374) — Pkt. 3 Ausnahme-Menge: allein der `generated.at`-Wanduhr-Gap; alle übrigen Bestandteile byte-identisch (kein stiller Ausschluss). +- [compiler.md:375](../../schema/compiler.md#L375) — Pkt. 4 Abweichungs-Klassifikation: jede Differenz außerhalb der Ausnahme = AD-16-Klassifikationsdefekt, kein Rauschen (NFR-4, Zustands-Restaurations-Invariante). +- [compiler.md:376](../../schema/compiler.md#L376) — Pkt. 5 Normalisierungs-/Match-/Orphan-Schließung: Verankerung auf §3.2-Pkt.-1b / §5.10-Pkt.-8, Erhebungen vollständig pinbar. + +**§3.2/§5.10-Lückenschließung (deterministische Regel-Ergänzungen)** + +- [compiler.md:54](../../schema/compiler.md#L54) — §3.2-Pkt.-1b „Geschlossene Determinismus-Lücken": Em-Dash-Kollaps-Klasse `[-–— _]`, Kollaps-Reichweite (ein `-` + Trim), Match-Scope Stufe a (ganze Wörter, Body-exklusiv). +- [compiler.md:56](../../schema/compiler.md#L56) — §3.2-Pkt.-2a operative Stufe-a-Mechanik: `rg -l`/`grep -rl`-Sweep + deterministischer Scope-Filter (zweistufig, tool-portabel), Mehrfach-Term-Vereinigung. +- [compiler.md:302](../../schema/compiler.md#L302) — §5.10-Pkt.-8 Erhaltungs-Invariante & Determinismus-Vertrag: Reconcile-Orphan-Regel (Zuwachs gg. Baseline, datumsgruppierter `log.md`-Eintrag, kein Banner, AD-16-Default). + +**§7/§8-Nachweis** + +- [compiler.md:476](../../schema/compiler.md#L476) — Revisionslog Revision 3.3: §5.14-Verankerung, §7-Determinismus-Vorbehalt aufgelöst, §8-AD-17h-Normreferenz auf §5.14-Anker, Abschlussklausel (AD-3/D-3/keine neue §7-Klasse). + +**Sandbox-Beweis (mechanische Bestätigung)** + +- [run-sandbox.sh:152](../../_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh#L152) — DET-1..DET-8-Szenarien (Bundle-State, Zwei-Run-identisch nicht-vakuum, Zwei-Run-Abweichung, `at`-Gap, Em-Dash, Kollaps, Match-Scope, Orphan); Läufe Exit 0 mit 8 harten PASS-Assertionen. + +**Story-Protokoll/Defers (Peripherie, zuletzt)** + +- [log.md:4](../../wiki/log.md#L4) — Story-3.8-Eintrag: Verankerung, Sandbox-Nachweis, Erhaltungs-Invariante, Validator-Verdikt; Revision 3.3. +- [deferred-work.md:492](../../_bmad-output/implementation-artifacts/deferred-work.md#L492) — aufgegriffene/geschlossene „Home: Story 3.8"-Defers (7 `### Aufgegriffen` + 1 `### Aufgegriffen (teilweise)`, append-only ab Zeile 492). +- [sprint-status.yaml:61](../../_bmad-output/implementation-artifacts/sprint-status.yaml#L61) — Key `3-8-determinismus-…` auf `review` (Review-Start-Flip Step-04); `done`-Transition im Step-05. diff --git a/_bmad-output/implementation-artifacts/sprint-status.yaml b/_bmad-output/implementation-artifacts/sprint-status.yaml index 7aa6830..9ed6a84 100644 --- a/_bmad-output/implementation-artifacts/sprint-status.yaml +++ b/_bmad-output/implementation-artifacts/sprint-status.yaml @@ -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-20-2026 08:56 +last_updated: 08-20-2026 09:05 project: wow20 project_key: NOKEY tracking_system: file-system @@ -58,7 +58,7 @@ development_status: 3-5-leasing-dirty-tree-schutz-für-konkurrierende-producer-umsetz: done 3-6-lease-staleness-recovery-basis-absichern: done 3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell: done - 3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato: backlog + 3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato: review epic-3-retrospective: optional epic-4: backlog diff --git a/schema/compiler.md b/schema/compiler.md index 01b41c3..bfe1efd 100644 --- a/schema/compiler.md +++ b/schema/compiler.md @@ -38,7 +38,7 @@ Bestätigung (Story 1.4): schema/validator.md (mechanische Prüfung, kein L 1. Vor der Anlage prüfen, ob die erkannte Wissenseinheit **bereits als Concept** im Bundle existiert (deterministisch: Dateikollision über den relativen OKF-Pfad, AD-7a). 2. **Update-Routing (statt Kollision-Hold; Story 3.1):** Existiert bereits ein Concept mit dem Ziel-Pfad, wird **nicht** stumm überschrieben und **kein** Duplikat angelegt — die erkannte Wissenseinheit wird als **Update-Kandidat** im **bestehenden Concept-Pfad** aktualisiert (Erweitern/Präzisieren/Korrigieren gemäß §5.9; FR-6). Die Mutationsmechanik für Updates spezifiziert §5.9; der Kollisions-Hold-Schutzprinzip („nicht stumm überschreiben") bleibt als Grundsatz der Erhaltung erhalten (AD-16-Default: bestehende Provenienz/Inhalte werden nie ohne Beleg entfernt). Der **Neu-Anlage-Pfad** dieser Instruktion bleibt für Wissenseinheiten, deren Ziel-Pfad **nicht** belegt ist (§5.1/§5.7). - **Kandidatenliste (betroffen-Bestimmung):** Vor jeder Mutation erhebt der Producer die Menge der betroffenen Concepts als **nachvollziehbare Kandidatenliste** (relative OKF-Pfade ohne `.md`) mit **textuell-deterministischen Mitteln** (AD-13): (a) Term-/Konzept-Überschneidung zwischen der neuen Evidenz und den bestehenden Concept-Bodies via `grep`/`ripgrep` über `wiki/` (z. B. `rg -l '' -g '!log.md' wiki/` bzw. GNU-grep-Form `grep -rl '' --exclude=log.md wiki/`); (b) `index.md`-Traversal (Bundleroot- und Area-`index.md`-Dateien, gewurzelte Erreichbarkeit Root → Area → Concept, §5.8) der dadurch betroffenen Bereiche; (c) Link-Following aus bereits betroffenen Concepts (§5.6-Pin) auf weitere Concept-Pfade — **mit besuchter Menge** (ein bereits besuchter Concept-Pfad wird nicht erneut besetzt; keine Schleife bei zyklischen Links). Die Erhebung folgt der feinkörnigen, verbindlichen Mechanik in **§3.2 Relevanzbestimmung (Story 3.2)** — Term-Ziehverfahren (deterministisch aus der neuen Evidenz abgeleitet, kanonischer Schreibweisen-Resolver `schema/canonical-terms.md`, mehrere Terme je Einheit), dreistufige Erhebung mit `log.md`-Exklusion (die Candidate-Liste ist auf Concept-Pfade definiert, `log.md` ist kein Kandidat) und Determinismus-Vertrag (AD-17h/A0-19) — **Erhebung nach §3.2**. Die Kandidatenliste wird textuell festgehalten (Pre-Run-Reconcile-Check-Block, §5.9 Pkt. 6). Keine Embeddings/Vector-Suche (AD-13); §5.9 bindet die Erhebung an die in §3.2 genannten deterministischen Mittel. + **Kandidatenliste (betroffen-Bestimmung):** Vor jeder Mutation erhebt der Producer die Menge der betroffenen Concepts als **nachvollziehbare Kandidatenliste** (relative OKF-Pfade ohne `.md`) mit **textuell-deterministischen Mitteln** (AD-13): (a) Term-/Konzept-Überschneidung zwischen der neuen Evidenz und den bestehenden Concept-Bodies via `grep`/`ripgrep` über `wiki/` (z. B. `rg -l '' -g '!log.md' wiki/` bzw. GNU-grep-Form `grep -rl '' --exclude=log.md wiki/`); (b) `index.md`-Traversal (Bundleroot- und Area-`index.md`-Dateien, gewurzelte Erreichbarkeit Root → Area → Concept, §5.8) der dadurch betroffenen Bereiche; (c) Link-Following aus bereits betroffenen Concepts (§5.6-Pin) auf weitere Concept-Pfade — **mit besuchter Menge** (ein bereits besuchter Concept-Pfad wird nicht erneut besetzt; keine Schleife bei zyklischen Links). Die Erhebung folgt der feinkörnigen, verbindlichen Mechanik in **§3.2 Relevanzbestimmung (Story 3.2)** — Term-Ziehverfahren (deterministisch aus der neuen Evidenz abgeleitet, kanonischer Schreibweisen-Resolver `schema/canonical-terms.md`, mehrere Terme je Einheit), dreistufige Erhebung mit `log.md`-Exklusion (die Candidate-Liste ist auf Concept-Pfade definiert, `log.md` ist kein Kandidat) und Determinismus-Vertrag (AD-17h/A0-19) — **Erhebung nach §3.2**. Die Kandidatenliste wird textuell festgehalten (Pre-Run-Reconcile-Check-Block, §5.9 Pkt. 6). Keine Embeddings/Vector-Suche (AD-13); §5.9 bindet die Erhebung an die in §3.2 genannten deterministischen Mittel; **der Stufe-a-Match-Scope (ganze Wörter über den Body, exklusive YAML-Frontmatter, §3.2-Pkt.-1b-Schließung/§5.14 Pkt. 5) gilt für die Stufe-a-Form hier unverändert**. Löst eine erkannte Wissenseinheit auf **keinen** bestehenden Concept-Pfad auf (kein Update-Kandidat), wird sie als **neue** Einheit über den Neu-Anlage-Pfad (§5.1/§5.7, §3-Pkt.-1/-2-Kollisionsprüfung ist damit erstbestanden) behandelt. 3. Der Run prüft zusätzlich, ob `wiki/index.md` als Bundleroot existiert (V-1-Vorbedingung des Validators); fehlt sie, darf kein Concept erzeugt oder aktualisiert werden (Run-FAIL, Vertrag §2). @@ -48,11 +48,12 @@ Diese Sektion ist der **einzige Instruktions-Ort** der feinkörnigen, **textuell 1. **Term-Ziehverfahren (deterministisch):** Die Candidate-Terme werden deterministisch aus der neuen Evidenz (committete `raw/`-Dateien, §1 Pkt. 1/2) abgeleitet — nicht freie LLM-Auswahl: - **(a) Bedeutungstragende Token-Folgen:** Der Producer benennt die bedeutungstragenden Fachbegriffe der Wissenseinheit gemäß der §2-Interpretation (fachliche Signifikanz; kein Stoppwort-Abgleich nötig, aber auch kein freies Urteil). Der Umfang „bedeutungstragend" ist die Auswahl derjenigen Begriffe, die das erkannte Thema identifizieren — als Token-Folgen über eine sprachliche Einheit hinweg zulässig (z. B. `quanten-protocol-schlüssel`). - - **(b) Normalisierung über den kanonischen Schreibweisen-Resolver:** Jeder gezogene Term wird durchgängig normalisiert: (i) lowercasing; (ii) Binde-Varianten-Kollaps `[-–_ ]` → `-` (En-Dash `–`, Bindestrich `-`, Unterstrich `_`, Leerzeichen — jedes Vorkommen wird in einen einzelnen Bindestrich kollabiert); (iii) Auflösung über die committete, append-only Registry **`schema/canonical-terms.md`** (ein Eintrag = canonische Form + erlaubte Schreibvarianten; der Resolver ist damit Bestandteil des Git-States und die Auflösung pinbar). **Genau eine canonische Form je Semantik** (A0-18). **Kein stiller Ausschluss:** ist eine Variante nicht in der Registry auflösbar, wird der Term **wie notiert** verwendet (Kollaps-normalisiert) — niemals still verworfen. + - **(b) Normalisierung über den kanonischen Schreibweisen-Resolver:** Jeder gezogene Term wird durchgängig normalisiert: (i) lowercasing; (ii) Binde-Varianten-Kollaps `[-–— _]` → `-` (En-Dash `–`, Em-Dash `—`, Bindestrich `-`, Unterstrich `_`, Leerzeichen — jedes Vorkommen wird in einen einzelnen Bindestrich kollabiert; die Kollaps-Reichweite und die übrigen Schließungen definiert der Append-Block weiter unten — **maßgeblich für den Kollaps ist die geschlossene Kollaps-Klasse `[-–— _]`**); (iii) Auflösung über die committete, append-only Registry **`schema/canonical-terms.md`** (ein Eintrag = canonische Form + erlaubte Schreibvarianten; der Resolver ist damit Bestandteil des Git-States und die Auflösung pinbar). **Genau eine canonische Form je Semantik** (A0-18). **Kein stiller Ausschluss:** ist eine Variante nicht in der Registry auflösbar, wird der Term **wie notiert** verwendet (Kollaps-normalisiert) — niemals still verworfen. - **(c) Mehrere Terme je Einheit erlaubt:** Eine Wissenseinheit kann mehrere bedeutungstragende Terme tragen; die Candidate-Liste ist dann die **Vereinigung** der Treffer über alle Terme, bereinigt über die besuchte Menge (Pkt. 3c — ein Pfad nur einmal). - **Bekannte Determinismus-Lücke (aufgezeichnet, nicht still hinzugefügt):** Die Kollaps-Klasse `[-–_ ]` deckt den Em-Dash `—` **nicht** ab (nur En-Dash `–`). Em-Dash-Varianten fallen damit nicht unter den Kollaps — eine erkannte Synonym-Lücke, die **Story 3.8** als offene Determinismus-Frage übergeben ist (s. `deferred-work.md`; nicht stillschweigend in §3.2 ergänzt). + - **Geschlossene Determinismus-Lücken (Story 3.8; deterministische Regel-Ergänzungen, §5.14):** (a) **Em-Dash in der Kollaps-Klasse** — die Kollaps-Klasse ist um den Em-Dash `—` **ergänzt** (`[-–— _]` → `-`): En-Dash `–`, Em-Dash `—`, Bindestrich `-`, Unterstrich `_` und Leerzeichen kollabieren identisch auf **genau einen** Bindestrich — eine Schreibvariante mit Em-Dash (z. B. `wissen — relevanz`) erhält damit dieselbe canonische Form wie ihre En-Dash-/Bindestrich-/Unterstrich-/Leerzeichen-Variante (kein stiller Ausschluss, keine unterschiedliche canonische Form je Separator; §5.14-Abweichungs-Klassifikation). (b) **Kollaps-Reichweite (deterministisch):** jedes Separator-Vorkommen wird auf **genau ein `-`** kollabiert; Läufe (`a--b`) kollabieren auf ein `-` (`a-b`); führende (`-x` → `x`) und trailende (`x-` → `x`) Separatoren werden getrimmt. (c) **Match-Scope der Stufe a (Pkt. 2a):** Stufe a matcht **ganze Wörter** über den **Body** des Concepts, **exklusive YAML-Frontmatter** — Substring-Treffer und Frontmatter-Treffer (z. B. in `sources[].resource`/`generated.by`) liefern **keine** Kandidaten (deterministischer Stufe-a-Scope, §5.14; fixiert das §3.2-Pkt.-2a-grep ohne Wortgrenzen-/Frontmatter-Klausel). Die Schließung erhebt **keinen** neuen Prädikat-/Format-/Frontmatter-Key und ändert **keinen** bestehenden §3.2-Wortlaut (append-only-Regel-Ergänzung; AD-3, D-3). 2. **Term-übergreifende Erhebung über `wiki/` (drei Stufen):** Der Producer erhebt die betroffenen Concept-Pfade in **drei textuell-deterministischen Stufen** (a → b → c). Ab der Workspace-Root: - - **(a) Stufe a — grep/ripgrep über `wiki/`:** `rg -l '' -g '!log.md' wiki/` (rgs native Glob-Exklusions-Syntax — `--exclude` ist kein rg-Flag; das GNU-grep-Äquivalent ist `grep -rl '' --exclude=log.md wiki/`, §5.6-Scan-Scope-Konvention). `` = jeder gezogene Term aus Pkt. 1 nach Normalisierung. Beide Formen exkludieren `log.md` **strukturell** (unabhängig von dessen Inhalt) — die Candidate-Liste bleibt auf Concept-Pfade definiert. + - **(a) Stufe a — grep/ripgrep über `wiki/`:** `rg -l '' -g '!log.md' wiki/` (rgs native Glob-Exklusions-Syntax — `--exclude` ist kein rg-Flag; das GNU-grep-Äquivalent ist `grep -rl '' --exclude=log.md wiki/`, §5.6-Scan-Scope-Konvention). `` = jeder gezogene Term aus Pkt. 1 nach Normalisierung. Beide Formen exkludieren `log.md` **strukturell** (unabhängig von dessen Inhalt) — die Candidate-Liste bleibt auf Concept-Pfade definiert. **Match-Scope (Pkt.-1b-Schließung, §5.14 Pkt. 5):** beide Formen erfüllen den Stufe-a-Match-Scope der geschlossenen Determinismus-Lücke — **ganze Wörter** über den **Body** (exklusive YAML-Frontmatter); Substring- und Frontmatter-Treffer (z. B. in `sources[].resource`/`generated.by`) liefern **keine** Kandidaten. Konsequent als **zweistufige, tool-portable Mechanik**: (1) **Sweep** mit der Formel je `` (Substring-/dateiweite Suche — die Formel ist ein trichiger Erhebungsschritt, keine Scope-Filterung); (2) **deterministischer Scope-Filter** über die so gefundenen Pfade: der Producer prüft je Pfad, ob `` als **ganzes Wort** im **Body** (Zeilen **nach der zweiten `---`-Zeile** — dem schließenden Frontmatter-Limit; die Frontmatter-Zeilen davor sind **nie Treffer-Ziel**) vorkommt — tool-portabel (z. B. rg `-w` über den Body bzw. GNU `grep -w`/`\b` nach `awk`-Frontmatter-Strip) — und verwirft Substring- und Frontmatter-only-Treffer deterministisch. `` ist je Erhebung ein **einzelner** normalisierter Term (Pkt. 1); werden **mehrere Terme** je Einheit gezogen (Pkt. 1c), wird die Formel je Term ausgeführt und die Candidate-Liste ist die **Vereinigung** der Treffer, bereinigt über die besuchte Menge (Pkt. 3c) und in Zuwachs-Sicht-Ordnung (Pkt. 3b). - **(b) Stufe b — `index.md`-Traversal:** Für die in Stufe a getroffenen Bereiche (und die Bundleroot) folgt der Producer der gewurzelten Erreichbarkeit Root → Area → Concept (§5.8): trifft ein Term nur `wiki/index.md` oder eine Area-`index.md` (nicht einen Concept-Body), so sind alle **darunter gewurzelten Concept-Pfade** Treffer der Stufe b (TRAVERSAL_REACH_ONLY). Fehlende Bundleroot → Run-FAIL (V-1, §3 Pkt. 3, besteht fort). - **(c) Stufe c — Link-Following mit besuchter Menge:** Aus bereits als betroffen erhobenen Concepts folgt der Producer die Concept-Links (§5.6-Pin) auf weitere Concept-Pfade — file-relativ auflösen (§5.7 Pkt. 4), **jeder bereits besuchte Concept-Pfad wird nicht erneut besucht** (besuchte Menge): Zyklen (A → B → A) enden, die Candidate-Liste bleibt endlich (LINK_FOLLOWING_ZYKLUS). 3. **Candidate-Liste (Ausgabe) + Determinismus-Vertrag:** @@ -298,7 +299,7 @@ Diese Sektion ist der **Instruktions-Ort der Synthese-Dimension** (AD-4, FR-7): 5. **Reflektierter Wissensstand (FR-7 AC-4, NFR-7):** Der Body trägt **integrierte, je Aussage provenance-tags versehene Aussagen** — **keine per-Source-Zusammenfassungs-Struktur** (keine Blöcke „Quelle A: … / Quelle B: …"). **Reflektiertheits-Selbsttest (textuell deterministisch, grepbasiert):** es existiert **keine** Zeile, die einen Quell-Label abschnittsstrukturiert — das Muster ist ein Zeilenanfangs-Label „`Quelle