From 938c05c4a8e6594c2163a11b51706ceb6e2b471e Mon Sep 17 00:00:00 2001 From: Michael Tamse Date: Thu, 20 Aug 2026 06:31:39 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Story=203.7=20Reason/Mutate-Trennung=20?= =?UTF-8?q?&=20Konsistenz-Endzustand=20sicherstellen=20(bmad-code-review,?= =?UTF-8?q?=203=20Layer;=20kein=20Loopback)=20=E2=80=94=20=C2=A75.13-Phase?= =?UTF-8?q?n-Sektion=20(AD-6/A0-7,=20=C3=84nderungsplanung=20als=20institu?= =?UTF-8?q?tionalisierter=20=C2=A75.9-Pkt.-6-P2-Block,=20Plan-Freeze=20an?= =?UTF-8?q?=20=C2=A75.9-Pkt.-5-Ghost-Diff-Kopplung,=20Zustands-Restauratio?= =?UTF-8?q?ns-Invariante,=20kein=20Teilerfolg=20AD-17f,=20VALIDATION=5FFAI?= =?UTF-8?q?L/SUCCESS,=20KEINE=5FEIGENE=5FENGINE;=20=C2=A77-Bullet=20aufgel?= =?UTF-8?q?=C3=B6st,=20=C2=A78-Normreferenz=20AD-6=20auf=20=C2=A75.13-Anke?= =?UTF-8?q?r,=20Revision=203.2=20+=20Abschlussklausel);=20Sandbox=20CONSIS?= =?UTF-8?q?T-1..CONSIST-7=20(Exit=200,=2014=20PASS,=20Restaurations-Invari?= =?UTF-8?q?ante,=20EC-1-Defizit-Negativkontrolle,=20pgrep-Robustheit,=20no?= =?UTF-8?q?n-vakuum=20Determinismus-Zeuge);=20Review-Loop-1-Fixes=20(SRO-A?= =?UTF-8?q?nker=20343/356/358/362/420/461,=20f=C3=BCnf=E2=86=92vier=20AD-6?= =?UTF-8?q?-Phasen,=20CONSIST-6-Validierung-vor-Commit);=20Suggested=20Rev?= =?UTF-8?q?iew=20Order=20+=20Status=20done;=20log.md;=20sprint-status=20re?= =?UTF-8?q?view;=20AD-3=20unver=C3=A4ndert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude --- .../sandbox-3-7/run-sandbox.sh | 576 ++++++++++++++++++ ...g-und-konsistenz-endzustand-sicherstell.md | 140 +++++ .../sprint-status.yaml | 4 +- schema/compiler.md | 25 +- wiki/log.md | 4 + 5 files changed, 746 insertions(+), 3 deletions(-) create mode 100644 _bmad-output/implementation-artifacts/sandbox-3-7/run-sandbox.sh create mode 100644 _bmad-output/implementation-artifacts/spec-3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell.md diff --git a/_bmad-output/implementation-artifacts/sandbox-3-7/run-sandbox.sh b/_bmad-output/implementation-artifacts/sandbox-3-7/run-sandbox.sh new file mode 100644 index 0000000..e90140c --- /dev/null +++ b/_bmad-output/implementation-artifacts/sandbox-3-7/run-sandbox.sh @@ -0,0 +1,576 @@ +#!/usr/bin/env bash +# Story 3.7 — Sandbox-Tests der Reason/Mutate-Phasen-Trennung & Konsistenz-Endzustand (§5.13, Revision 3.2) +# Re-executierbar: bash run-sandbox.sh (ab Workspace-Root; Sandbox unter /tmp/sb37) +# Zweck: die Reason/Mutate-Phasen-Disziplin (§5.13) als re-executierbarer Run-Demonstrator +# durchspielen — +# CONSIST-1 KONSISTENTE_AENDERUNGSPLANUNG (AC-1, AD-6, A0-7): der P2-Block (§5.9 Pkt. 6) +# erzeugt aus committetem Input eine konsistente Änderungsplanung (Input-Zustand, +# Ziel-Pfade, Quellen-Existenz, Betroffenheit, Struktur-Erhaltung) — als Variablen-Set +# captured, Determinismus (AD-17h/A0-19); Plan-Defizit ⇒ Abbruch vor Mutationsphase +# CONSIST-2 PLAN_FREEZE (AC-1, §5.13 Pkt. 2): Plan-Freeze = Veränderungs-Sperre — eine +# Mutation ausserhalb der Plan-Pfadmengen (Kandidatenliste ∪ Neu-Anlage ∪ log.md ∪ +# index.md) wird erkannt und verweigert/verhindert (Ghost-Diff-Kopplung §5.9 Pkt. 5) +# CONSIST-3 ZUSTANDS-RESTAURATIONS-INVARIANTE (AC-2, §5.13 Pkt. 3): fehlgeschlagene +# Mutation rollt auf exakte Baseline zurueck (SHA-256 byte-identisch, Post-Rollback-Diff +# leer gg. Baseline), Bundle-Zustand == Baseline; raw/ unverändert (AD-3) +# CONSIST-4 MUTATION_ABBRUCH (AC-2, §5.13 Pkt. 3/4): Abbruch nach Teilerfolg (mehrere +# geplante Mutationen, nur ein Teil ausgefuehrt) hinterlaesst keinen Teilerfolg als +# fertige Mutation (Commit-Boundary = Mutations-Boundary, AD-17f); raw/ unberührt +# CONSIST-5 VALIDATION_FAIL (AC-2, §5.13 Pkt. 5): §6-Pkt.-3-Rollback, keine weiteren +# Mutationen, Endzustand konsistent (Zustands-Restaurations-Invariante) +# CONSIST-6 VALIDATION_SUCCESS (AC-3, §5.13 Pkt. 6): Mutationen als Ganzes committet, +# Diff gg. Plan-Menge gedeckt, §6-Pkt.-4-Nachweis; kein Wanduhr-Trigger (A0-20) +# CONSIST-7 DETERMINISMUS-ZWEI-RUN + KEINE_ENGINE (AC-4, §5.13 Pkt. 7): Zwei identische +# Runs -> identische Plan-/Rollback-/State-Outputs (AD-17h/A0-19); die Phasen-Trennung +# ist logisch in einer Session — kein Prozess/Server/MCP wird gestartet (D-3, AD-11, +# grep-Negativkontrolle: keine Hintergrundprozesse/Logger-Daemons) +# Erhaltungs-Invariante (§5.9 Pkt. 5 / AD-5 / FT-6) als HARDE Assertion je lauffaehigem +# Run; Frontmatter-Konformitaet (Vertrag §3.3/§3.4-Subset) je erzeugtem/aktualisiertem Concept. +# Ubuntu-Sandbox-Semantik auf einem /tmp-Baum — NIE der reale wiki/- oder raw/-Baum. +set -u +ROOT=$(mktemp -d /tmp/sb37-XXXXXX) +SB="$ROOT/sb" +mkdir -p "$SB/wiki" "$SB/raw" +cd "$SB" +git init -q +# Determinismus vs. Host-Git-Konfiguration (AD-17h): die Sandbox erzeugt LF-Blobs und +# LF-Worktree — autocrlf/filemode-Umwandlung des Hosts wuerde sha256-Vergleiche und +# Diff-/Probe-Ergebnisse wort-wirksam verschieben. Repo-Reparatur schliesst das aus. +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 = Merge-Base) ---------- +# 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 +} + +# Erhaltungs-Invariante-Probe (§5.9 Pkt. 5 / AD-5 / FT-6): Baseline-Diff + porcelain, +# normalisiert (wiki/-Praefix + .md-Suffix gestrippt, LC_ALL=C-sortiert). +probe() { + { 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 +} +inv_set() { probe | LC_ALL=C sort -u | paste -sd' ' -; } + +# ---------- Harte Assertion der Erhaltungs-Invariante (§5.9 Pkt. 5) ---------- +inv_viol() { # $1=expected ; 0 = konsistent, !=0 = Verstoß (msg stderr) + local expected="$1" p u bad=0 + got=$(inv_set) + for p in $got; do + case " $expected " in + *" $p "*) ;; + *) echo "HARD-FAIL (Erhaltungs-Invariante §5.9 Pkt. 5): '$p' ist kein Ghost-Diff-negativer Eintrag — erlaubte Menge: {$expected}" >&2; bad=1;; + esac + done + for u in $(git status --porcelain -- wiki/ | grep '^??' | awk '{print $2}'); do + u=$(echo "$u" | sed -e 's|^wiki/||' -e 's|\.md$||') + case " $expected " in + *" $u "*) ;; + *) echo "HARD-FAIL (Duplikat/Ghost-Diff): ungetrackte neue Datei '$u' liegt ausserhalb der erlaubten Ziel-Pfade {$expected} (§5.9 Pkt. 5)" >&2; bad=1;; + esac + done + return $bad +} +assert_invariant() { # positive Erwartung: Verstoß => HARD-FAIL + Exit 1 + if inv_viol "$1"; then + echo "RESULT: PASS — Probe erfüllt; keine neue Datei; kein Ghost-Diff" + else + exit 1 + fi +} + +# ---------- Zustands-Restaurations-Invariante (§5.13 Pkt. 3) — harte Assertion ---------- +# Nach Abbruch/FAIL muss der Post-Rollback-Diff gg. die Baseline LEER sein (Bundle == +# Baseline, SHA-256 byte-identisch je Pfad) — die git-ueberpruefbare Konsistenz-Eigenschaft. +assert_restored() { # $1=komma-oder-leer-getrennte wiki-Pfade, die byte-identisch zur Baseline sein müssen + local p expected="" + [ -z "$1" ] || for p in $1; do expected="$expected $p.md"; done + # 1) git-Diff gg. Baseline: keine modifizierte/geloeschte Datei + if [ -n "$(git diff --name-only "$BASE" -- wiki/)" ]; then + echo "HARD-FAIL (Zustands-Restaurations-Invariante §5.13 Pkt. 3): Post-Rollback-Diff gg. Baseline NICHT leer:" >&2 + git diff --name-only "$BASE" -- wiki/ | sed 's/^/ /' >&2 + exit 1 + fi + # 2) porcelan: keine ungetrackten/gestagten Eintraege im wiki/-Scope + if [ -n "$(git status --porcelain -- wiki/)" ]; then + echo "HARD-FAIL (Zustands-Restaurations-Invariante §5.13 Pkt. 3): ungetrackte/gestagte Reste im wiki/-Scope:" >&2 + git status --porcelain -- wiki/ | sed 's/^/ /' >&2 + exit 1 + fi + # 3) byte-identisch zur Baseline (SHA-256); Neu-Anlage-Randfall (Pfad nur im Run angelegt): + # existiert der Pfad NICHT im Baseline-Commit, darf er nach dem Rollback auch nicht in der + # Working-Copy existieren (statt eines spurious byte-Vergleichs). + for p in $expected; do + if git cat-file -e "$BASE:wiki/$p" 2>/dev/null; then + [ -f "wiki/$p" ] || { echo "HARD-FAIL (Zustands-Restaurations-Invariante §5.13 Pkt. 3): wiki/$p fehlt (muss == Baseline sein)" >&2; exit 1; } + bsha=$(git show "$BASE:wiki/$p" | sha256sum | cut -d' ' -f1) + csha=$(sha256sum "wiki/$p" | cut -d' ' -f1) + [ "$bsha" = "$csha" ] || { echo "HARD-FAIL (Zustands-Restaurations-Invariante §5.13 Pkt. 3): wiki/$p weicht von Baseline ab ($csha != $bsha)" >&2; exit 1; } + else + # Neu-Anlage-Pfad (nicht im Baseline-Commit): nach Rollback darf er NICHT existieren. + [ ! -e "wiki/$p" ] || { echo "HARD-FAIL (Zustands-Restaurations-Invariante §5.13 Pkt. 3): wiki/$p ist Neu-Anlage-Pfad und muss nach Rollback NICHT existieren" >&2; exit 1; } + fi + done + echo "RESULT: PASS — Zustands-Restaurations-Invariante: Post-Rollback-Diff gg. Baseline leer, Bundle == Baseline (SHA-256 byte-identisch)" +} + +# ---------- Frontmatter-Konformitaet (Vertrag §3.3/§3.4, §6.5; Muster Sandbox-3-6) ---------- +assert_frontmatter() { + local f="$1"; shift + local v + v=$(awk ' + /^---$/{n++; if(n==2) exit; next} + /^[A-Za-z_][A-Za-z0-9_-]*:/{ + k=$0; sub(/:.*/,"",k) + if (k=="sources") top="sources" + else if (k=="generated" || k=="verified") top="genver" + else top="other" + if (k!="type" && k!="sources" && k!="generated" && k!="verified" && k!="status" && k!="stale_after") print "TOP_UNBEFUGT:" k + if (seenk[k]++) print "DUP_KEY:" k + r=0 + if (k=="type") r=1; else if (k=="sources") r=2; else if (k=="generated") r=3 + else if (k=="verified") r=4; else if (k=="status") r=5; else if (k=="stale_after") r=6 + if (r>0 && r0) lastr=r + next + } + /^[[:space:]]/{ + gsub(/^[[:space:]]+/,""); sub(/^- /,""); gsub(/^[[:space:]]+/,""); + if (match($0, /^[A-Za-z_][A-Za-z0-9_-]*:/)) { + ik=substr($0,1,RLENGTH-1) + if (top=="sources" && ik!="resource" && ik!="id" && ik!="title" && ik!="author" && ik!="usage_count" && ik!="last_modified") print "INNER_UNBEFUGT:" ik + if (top=="genver" && ik!="by" && ik!="at") print "INNER_UNBEFUGT:" ik + if (top=="other") print "INNER_UNBEFUGT:" ik + } + } + ' "$f") + if [ -n "$v" ]; then + echo "HARD-FAIL (Frontmatter-Subset, Vertrag §3.3/§3.4/§3.5): $v in $f" >&2 + exit 1 + fi + grep -qE '^type: concept$' "$f" || { echo "HARD-FAIL: type=concept fehlt in $f" >&2; exit 1; } + grep -qE "^ at: [0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-][0-9]{2}:?[0-9]{2})$" "$f" || { echo "HARD-FAIL: generated.at ist keine volle ISO-8601-Datetime in $f" >&2; exit 1; } + for r in "$@"; do + grep -qF " - resource: $r" "$f" || { echo "HARD-FAIL: sources-Eintrag 'resource: $r' fehlt in $f" >&2; exit 1; } + done + echo "RESULT: PASS — Frontmatter-Konformitaet $f (Subset ok, generated.at volles Datetime)" +} + +# ---------- log.md-Eintraege (§5.13; Header-Bullet-Paar je Eintrag, datumsgruppiert) ---------- +# Datumsgruppen-/Reihenfolge-Konvention (Vertrag §5, neueste zuerst): ein neuer Bullet wird +# in die BESTEHENDE Datumsgruppe eingefuegt — nach deren Header, vor etwaigen Gruppen-Bullets — +# sonst wird ein neuer Header oben erzeugt. Deterministisch (kein Wanduhr). +log_bullet() { # $1 = Bullet-Text (eine Zeile, printf-% escaped); Datumsgruppe/Reihenfolge (neueste zuerst) + local day="2026-08-20" # getrennt gesetzt — set -u: gleiche-local-Zeilen-RHS darf day nicht vor Setzung referenzieren + 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 +} +log_plan() { # $1=plan-text (eine Zeile) + log_bullet "- Änderungsplanung (P2-Block, §5.9 Pkt. 6 / §5.13 Pkt. 1): $1 (Determinismus AD-17h/A0-19; Baseline $BASE)" +} +log_abort() { # $1=benannte Abbruch-Ursache — NFR-4-texuelle Benennung (echo). Für einen + # FAILED-Run wird log.md NICHT persistent beschrieben: §6 Pkt. 3 / §5.3 rollen auch die + # log.md-Einträge als Teilzustand zurück (Bundle nimmt Zustand vor dem Run wieder ein). + echo "NFR-4-Benennung (textuell): Mutations-Abbruch (§5.13 Pkt. 3/4) — $1; Zustands-Restaurations-Invariante (Pkt. 3), kein Teilerfolg committet (AD-17f); log.md-Einträge des Runs werden mit dem Teilzustand zurückgerollt (§6 Pkt. 3 / §5.3)" +} +log_commit() { # $1=plan-vs-ist-diff-befund + log_bullet "- Validierung SUCCESS (§5.13 Pkt. 6): Mutationen als Ganzes committet; $1 (§6-Pkt.-4-Nachweis, kein Wanduhr-Trigger A0-20)" +} + +# ---------- Reason/Mutate-Helfer (§5.13) ---------- +# P2-Block (§5.9 Pkt. 6) als Änderungsplanung: capturet den konsistenten Plan als textuelles +# Variablen-Set (Input-Zustand, Ziel-Pfade, Quellen-Existenz, Betroffenheit, Struktur- +# Erhaltung) — deterministisch aus dem committeten Git-State (AD-17h/A0-19). +p2_plan() { # $1=komma-Liste Ziel-Pfade (OKF-ohne-.md) $2=komma-Liste raw-Quellen (Pfad) + local targets="$1" srcs="$2" p s err=0 + # (1) Input-Zustand (AD-17a): Working-Copy von raw/ und wiki/ gegen HEAD — uncommittet = Abbruch + if [ -n "$(git status --porcelain)" ]; then + echo "HARD-FAIL (Änderungsplanung, P2-Block-Element (1): Input-Zustand AD-17a): uncommittete Zwischenstaende als Input — Abbruch vor der Mutation (published/committed Input erforderlich)" >&2 + return 1 + fi + # (2) Ziel-Pfade (Kandidatenliste, §3 Pkt. 2) + [ -n "$targets" ] || { echo "HARD-FAIL (Änderungsplanung): leere Ziel-Pfad-Menge (P2-Element (2))" >&2; return 1; } + # (3) Quellen-Existenz (EC-1) + for s in ${srcs//,/ }; do + [ -f "raw/$s" ] || { echo "HARD-FAIL (Änderungsplanung, P2-Element (3): Quellen-Existenz EC-1): raw/$s existiert nicht" >&2; return 1; } + done + # (4) Betroffenheit (§3 Pkt. 2, textuell-deterministisch nach §3.2) + for p in ${targets//,/ }; do + [ -f "wiki/$p.md" ] || [ "$p" = "neu" ] || { echo "HARD-FAIL (Änderungsplanung, P2-Element (4)): Betroffenheits-Kandidat wiki/$p.md fehlt (und kein Neu-Anlage-Marker)" >&2; return 1; } + done + # (5) wiki/index.md-V-1 (Vertrag §2) + [ -f "wiki/index.md" ] || { echo "HARD-FAIL (Änderungsplanung, P2-Element (5)): fehlende Bundleroot — Run-FAIL (V-1)" >&2; return 1; } + # (6) Struktur-Erhaltungs-Check (Vertrag §3.3/§3.4-Subset) je betroffenem Concept + for p in ${targets//,/ }; do + if [ -f "wiki/$p.md" ]; then + v=$(awk ' + /^---$/{n++; if(n==2) exit; next} + /^[A-Za-z_][A-Za-z0-9_-]*:/{ k=$0; sub(/:.*/,"",k) + if (k!="type" && k!="sources" && k!="generated" && k!="verified" && k!="status" && k!="stale_after") { print k; exit } }' "wiki/$p.md") + [ -z "$v" ] || { echo "HARD-FAIL (Änderungsplanung, P2-Element (6): Struktur-Erhaltung): unbefugter Key '$v' in wiki/$p.md" >&2; return 1; } + fi + done + echo "PLAN_OK targets=($targets) sources=($srcs)" + return 0 +} +# Plan-Freeze (Veränderungs-Sperre, §5.13 Pkt. 2): nach Abschluss der Planung darf kein +# Plan-Gegenstand ausserhalb der erlaubten Menge mutiert werden — eine Ziel-Pfad-Verletzung +# wird erkannt und verweigert (Ghost-Diff-Kopplung §5.9 Pkt. 5). +freeze_check() { # $1=komma-Liste der im Run geplanten Ziel-Pfade (ok + neu.log + index) + local allowed=" $1 " + local m + # Normalisierung (wie §5.9 Pkt. 5-Probe): wiki/-Praefix + .md-Suffix strippen (beide Stromarten). + for m in $( { 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); do + case "$allowed" in + *" $m "*) ;; + *) echo "HARD-FAIL (Plan-Freeze §5.13 Pkt. 2 / Ghost-Diff §5.9 Pkt. 5): Mutation ausserhalb der erlaubten Pfad-Menge — '$m' ist nicht im Plan ($allowed)" >&2; return 1;; + esac + done + return 0 +} +# Rollback der Mutationsphase (Zustands-Restaurations-Invariante, §5.13 Pkt. 3): stellt die +# Baseline wieder her — §5.3-Pkt.-3/§6-Pkt.-3-Mechanik + Ghost-Diff-Rollback §5.9 Pkt. 5. +rollback() { + git checkout -q "$BASE" -- wiki/ 2>/dev/null || true + untracked_rest=$(git status --porcelain -- wiki/ | grep '^??' | awk '{print $2}') + if [ -n "$untracked_rest" ]; then + echo "ROLLBACK: ungetrackte Reste im wiki/-Scope bei Rollback entdeckt:" >&2 + echo "$untracked_rest" | sed 's/^/ /' >&2 + # Ghost-Diff-Rollback §5.9 Pkt. 5: ungetrackte neue Dateien ausserhalb der Ziel-Pfade loeschen + for u in $untracked_rest; do + echo "ROLLBACK (Ghost-Diff-Rollback §5.9 Pkt. 5): entferne ungetrackte neue Datei '$u' ausserhalb erlaubter Menge" + rm -f "$u" + done + fi + git reset -q --hard "$BASE" + git clean -qfd wiki +} + +# ---- CONSIST-1: KONSISTENTE_AENDERUNGSPLANUNG (AC-1, AD-6, A0-7; §5.13 Pkt. 1) ---- +runlabel "CONSIST-1: KONSISTENTE_AENDERUNGSPLANUNG (AC-1, AD-6, A0-7) — der P2-Block (§5.9 Pkt. 6) erzeugt aus committetem Input eine konsistente Änderungsplanung (Input-Zustand, Ziel-Pfade, Quellen-Existenz, Betroffenheit, Struktur-Erhaltung); textuelle Capture als Plan; Plan-Defizit (uncommitteter Input) ⇒ Abbruch VOR der Mutationsphase" +isolate consist1 +echo "--- Neue committete Evidenz als Input (AD-17a): raw/alpha-v2.md ---" +cat > raw/alpha-v2.md <<'EOF' +### S-3 +Evidenz v2: Alpha erweitert um eine synchrone Kopplung (Story 3.7-Plan). +EOF +git add -A && git commit -qm "Evidenz v2" +echo "--- Änderungsplanung (P2-Block als Phase): p2_plan alpha raw/alpha-v2.md ---" +PLAN1=$(p2_plan "alpha" "alpha-v2.md") || exit 1 +echo "$PLAN1" +echo "--- Determinismus der Planung (AD-17h/A0-19): zweite Planung desselben committeten States (VOR jedem Run-Mutationsschritt) ---" +PLAN2=$(p2_plan "alpha" "alpha-v2.md") || exit 1 +[ "$PLAN1" = "$PLAN2" ] || { echo "HARD-FAIL (CONSIST-1): Plan ungleich bei gleichem Git-State (AD-17h/A0-19)" >&2; exit 1; } +echo "PLAN2 identisch: $PLAN2" +echo "--- Plan textuell festgehalten (log.md-Teil der Planung, kein Artefakt-File) ---" +log_plan "alpha betroffen via raw/alpha-v2.md (Ziel-Pfade {alpha}, Quellen-Existenz EC-1 ok, Struktur-Erhaltung ok)" +grep -qF 'Änderungsplanung (P2-Block' wiki/log.md || { echo "HARD-FAIL (CONSIST-1): Plan-Nachweis fehlt in log.md (§5.13 Pkt. 1)" >&2; exit 1; } +echo "--- Plan-Defizit-Kette (I/O-Matrix PLAN_BEABSICHTIGT): uncommitteter Input ⇒ Abbruch VOR der Mutation ---" +echo "uncommitteter Rest im raw/" > raw/scratch-deficit.txt +if p2_plan "alpha" "alpha-v2.md" >/dev/null 2>&1; then + echo "HARD-FAIL (CONSIST-1): uncommitteter Input wurde nicht als Plan-Defizit abgefangen (P2-Element (1), AD-17a)" >&2 + exit 1 +else + echo "BEFUND: Plan-Defizit textuell benannt (NFR-4) — Abbruch vor der Mutationsphase, keine Mutation" +fi +rm -f raw/scratch-deficit.txt +echo "--- Plan-Defizit-Kette (I/O-Matrix PLAN_BEABSICHTIGT): fehlende Quellen-Existenz (P2-Element (3), EC-1) ⇒ Abbruch VOR der Mutation ---" +rm -f raw/alpha-v2.md +if p2_plan "alpha" "alpha-v2.md" >/dev/null 2>&1; then + echo "HARD-FAIL (CONSIST-1): fehlende Quelle wurde nicht als Plan-Defizit abgefangen (P2-Element (3), EC-1)" >&2 + exit 1 +else + echo "BEFUND: Plan-Defizit (EC-1: raw/alpha-v2.md fehlt) textuell benannt (NFR-4) — Abbruch vor der Mutationsphase, keine Mutation" +fi +echo "--- Probe (Erhaltungs-Invariante §5.9 Pkt. 5): nur log.md ---"; probe +assert_invariant "log" +echo "RESULT: PASS — CONSIST-1: konsistente Änderungsplanung aus committetem Input (P2-Block, §5.9 Pkt. 6 / §5.13 Pkt. 1); textuelle Capture; Determinismus (AD-17h/A0-19); Plan-Defizit ⇒ Abbruch vor der Mutation (PLAN_BEABSICHTIGT; P2-Element (1) AD-17a + P2-Element (3) EC-1); Erhaltungs-Invariante" + +# ---- CONSIST-2: PLAN_FREEZE (AC-1; §5.13 Pkt. 2) ---- +runlabel "CONSIST-2: PLAN_FREEZE (§5.13 Pkt. 2) — Plan-Freeze = Veränderungs-Sperre: eine Mutation ausserhalb der Plan-Pfadmengen (Kandidatenliste ∪ Neu-Anlage ∪ log.md ∪ index.md) wird erkannt und verhindert (Ghost-Diff-Kopplung §5.9 Pkt. 5)" +isolate consist2 +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" +p2_plan "alpha" "alpha-v2.md" >/dev/null || exit 1 +log_plan "alpha betroffen via raw/alpha-v2.md (Plan-Freeze aktiv)" +echo "--- Mutationsphase: geplante Mutation von alpha — erlaubt (Plan-Ziel-Pfad) ---" +cat >> wiki/alpha.md <<'EOF' +Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3). +EOF +grep -q "synchrone Kopplung" wiki/alpha.md || { echo "HARD-FAIL (CONSIST-2): geplante Mutation fehlgeschlagen" >&2; exit 1; } +echo "--- Freeze-Verletzung simulieren: Ghost-Mutation auf NICHT geplanten Pfad gamma (Plan-Gegenstand ausserhalb der erlaubten Menge) ---" +echo "unbefugte gamma-Aenderung" >> wiki/gamma.md +if freeze_check "alpha log index"; then + echo "HARD-FAIL (CONSIST-2): Mutation ausserhalb der Plan-Pfadmengen wurde nicht erkannt (Plan-Freeze, §5.13 Pkt. 2)" >&2 + exit 1 +else + echo "BEFUND: Freeze-Verletzung erkannt (ghost gamma) — Veränderungs-Sperre greift" +fi +echo "--- Ghost-Diff-Rollback (§5.9 Pkt. 5): gamma aus Baseline-Zustand wiederherstellen, textuell benannt (NFR-4) ---" +git checkout -q "$BASE" -- wiki/gamma.md +echo "NFR-4-Nennung: Ghost-Diff auf 'gamma' (ausserhalb Plan-Menge) zurueckgerollt — textuell benannt" +freeze_check "alpha log index" || exit 1 +echo "--- Diff-Probe (§5.9 Pkt. 5 / §5.13 Pkt. 2): {alpha, log} — gamma ist zurueck (kein Ghost-Diff) ---"; probe +assert_invariant "alpha log" +echo "RESULT: PASS — CONSIST-2: Plan-Freeze = Veränderungs-Sperre (erlaubte Menge {alpha, log, index}); Verletzung (gamma) erkannt + auf Baseline zurueckgerollt (Ghost-Diff-Rollback §5.9 Pkt. 5), textuell benannt (NFR-4); Erhaltungs-Invariante" + +# ---- CONSIST-3: ZUSTANDS-RESTAURATIONS-INVARIANTE (AC-2; §5.13 Pkt. 3) ---- +runlabel "CONSIST-3: ZUSTANDS-RESTAURATIONS-INVARIANTE (AC-2) — fehlgeschlagene Mutation rollt auf exakte Baseline zurueck (Post-Rollback-Diff leer, SHA-256 byte-identisch); Bundle == Baseline; raw/ unverändert (AD-3)" +isolate consist3 +raw_sha_before=$(sha256sum raw/alpha-v1.md | cut -d' ' -f1) +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" +echo "--- Planung (konsistent) + Mutationsphase: Teilzustand wird geschrieben (alpha erweitert), dann bricht die Mutation AB (Fehler) ---" +p2_plan "alpha" "alpha-v2.md" >/dev/null || exit 1 +log_plan "alpha betroffen via raw/alpha-v2.md" +cat >> wiki/alpha.md <<'EOF' +Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3). +EOF +echo " (Teilzustand geschrieben: alpha erweitert)" +echo "--- Mutations-Abbruch: Rollback (Zustands-Restaurations-Invariante §5.13 Pkt. 3; §5.3-Pkt.-3-/§6-Pkt.-3-Rollback, Ghost-Diff-Rollback §5.9 Pkt. 5) ---" +rollback +log_abort "Fehler waehrend der Mutationsphase (alpha-Teilzustand)" +echo "--- KERN-ASSERTION: Post-Rollback-Diff leer, Bundle == Baseline (SHA-256 je Pfad) ---" +assert_restored "alpha gamma index log" +echo "--- raw/ unverändert (AD-3) ---" +[ "$(sha256sum raw/alpha-v1.md | cut -d' ' -f1)" = "$raw_sha_before" ] || { echo "HARD-FAIL (CONSIST-3): raw/ verändert (AD-3)" >&2; exit 1; } +[ -f raw/alpha-v1.md ] || { echo "HARD-FAIL (CONSIST-3): raw/alpha-v1.md fehlt (AD-3)" >&2; exit 1; } +echo "RESULT: PASS — CONSIST-3: fehlgeschlagene Mutation rollt auf exakte Baseline zurueck (Post-Rollback-Diff leer, SHA-256 byte-identisch, Bundle == Baseline); raw/ unverändert (AD-3); Zustands-Restaurations-Invariante erzwungen" + +# ---- CONSIST-4: MUTATION_ABBRUCH (AC-2; §5.13 Pkt. 3/4) ---- +runlabel "CONSIST-4: MUTATION_ABBRUCH (AC-2) — Abbruch nach Teilerfolg (mehrere geplante Mutationen, nur ein Teil ausgefuehrt) hinterlaesst KEINEN Teilerfolg als fertige Mutation (Commit-Boundary = Mutations-Boundary, AD-17f); raw/ unberührt" +isolate consist4 +cat > raw/alpha-v2.md <<'EOF' +### S-3 +Evidenz v2: Alpha erweitert um eine synchrone Kopplung. +EOF +cat > raw/gamma-v2.md <<'EOF' +### S-1 +Evidenz v2: Gamma schaerft seine Abgrenzung. +EOF +git add -A && git commit -qm "Evidenz v2" +echo "--- Plan: ZWEI Ziel-Pfade (alpha, gamma) — Mutationsphase fuehrt nur alpha aus, dann Abbruch ---" +p2_plan "alpha,gamma" "alpha-v2.md,gamma-v2.md" >/dev/null || exit 1 +log_plan "alpha,gamma betroffen (zwei geplante Mutationen)" +PRE_MUT_HEAD=$(git rev-parse HEAD) +echo " (HEAD vor der Mutationsphase = $PRE_MUT_HEAD; Evidenz-Commit ist Input, kein Run-Mutations-Commit)" +cat >> wiki/alpha.md <<'EOF' +Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3). +EOF +echo " (alpha mutiert; gamma geplant aber NOCH NICHT ausgefuehrt — Abbruch)" +echo "--- Kein Teilerfolg darf als fertige Mutation veröffentlicht werden (AD-17f): nicht committen, zurueckrollen ---" +if [ "$(git log --oneline -1 --format='%H')" != "$PRE_MUT_HEAD" ]; then + echo "HARD-FAIL (CONSIST-4): es wurde ein Commit während des Abbruchs erzeugt (Commit-Boundary verletzt, AD-17f)" >&2 + exit 1 +else + echo " BEFUND: kein Commit während der Teilfolge (HEAD == $PRE_MUT_HEAD; Commit-Boundary = Mutations-Boundary gewahrt)" +fi +rollback +log_abort "Abbruch nach Teilerfolg (alpha ausgefuehrt, gamma nicht) — kein Teilerfolg committet" +echo "--- KERN-ASSERTION: Post-Rollback-Diff leer, Bundle == Baseline (kein Teilerfolg sichtbar) ---" +assert_restored "alpha gamma index log" +echo "--- raw/ unberührt (AD-3): Baseline-raw-Dateien byte-identisch nach Rollback ---" +# Setup-Existenz-Assert: die Baselines müssen im Baseline-Commit existieren, sonst wäre der +# SHA-Vergleich leerer-Input (der stille `|| sha256sum...`-Fallback wäre toter Pfad — kein pipefail). +git cat-file -e "$BASE:raw/alpha-v1.md" || { echo "HARD-FAIL (Setup): raw/alpha-v1.md fehlt im Baseline-Commit" >&2; exit 1; } +git cat-file -e "$BASE:raw/gamma-v1.md" || { echo "HARD-FAIL (Setup): raw/gamma-v1.md fehlt im Baseline-Commit" >&2; exit 1; } +rawv1_a=$(git show "$BASE:raw/alpha-v1.md" | sha256sum | cut -d' ' -f1) +rawv1_g=$(git show "$BASE:raw/gamma-v1.md" | sha256sum | cut -d' ' -f1) +[ "$rawv1_a" = "$(sha256sum raw/alpha-v1.md | cut -d' ' -f1)" ] || { echo "HARD-FAIL (CONSIST-4): raw/alpha-v1.md verändert (AD-3)" >&2; exit 1; } +[ "$rawv1_g" = "$(sha256sum raw/gamma-v1.md | cut -d' ' -f1)" ] || { echo "HARD-FAIL (CONSIST-4): raw/gamma-v1.md verändert (AD-3)" >&2; exit 1; } +echo " BEFUND: raw/alpha-v1.md + raw/gamma-v1.md == Baseline-SHA (der Run hat raw/ nicht berührt; die Evidenz-Input-Commit-V2-Dateien sind Input, kein Baseline-/AD-3-Gegenstand)" +echo "RESULT: PASS — CONSIST-4: MUTATION_ABBRUCH nach Teilerfolg — kein Teilerfolg als fertige Mutation veröffentlicht (Commit-Boundary = Mutations-Boundary, AD-17f); Rollback stellt Baseline wieder her; Zustands-Restaurations-Invariante; raw/ unberührt (AD-3)" + +# ---- CONSIST-5: VALIDATION_FAIL (AC-2; §5.13 Pkt. 5) ---- +runlabel "CONSIST-5: VALIDATION_FAIL (AC-2) — §6-Pkt.-3-Rollback bei Validierungs-FAIL: keine weiteren Mutationen, Endzustand konsistent (Zustands-Restaurations-Invariante); raw/ unverändert (AD-3)" +isolate consist5 +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" +p2_plan "alpha" "alpha-v2.md" >/dev/null || exit 1 +log_plan "alpha betroffen via raw/alpha-v2.md" +echo "--- Mutationsphase: alpha wird mutiert — aber mit Frontmatter-Verstoß (unbefugter Key foo:) ---" +cat >> wiki/alpha.md <<'EOF' +Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3). +EOF +printf '\nfoo: bar\n' >> wiki/alpha.md +echo "--- Validierungsphase (§6): FAIL (Struktur-Verstoß, unbefugter Key) -> §6-Pkt.-3-Rollback, KEINE weiteren Mutationen ---" +if grep -q '^foo:' wiki/alpha.md; then + echo " Validator-BEFUND: FAIL (unbefugter Key 'foo:', Punkt 6-Struktur-Verstoß) — textuell benannt (NFR-4)" +else + echo "HARD-FAIL (CONSIST-5): Validator-Verstoß nicht erkennbar gemacht" >&2; exit 1 +fi +rollback +log_abort "Validierungs-FAIL (unbefugter Key foo: in alpha) — §6-Pkt.-3-Rollback, keine weiteren Mutationen" +echo "--- KERN-ASSERTION: Endzustand konsistent (Baseline wiederhergestellt) ---" +assert_restored "alpha gamma index log" +raw_sha=$(sha256sum raw/alpha-v1.md | cut -d' ' -f1) +[ "$(sha256sum raw/alpha-v1.md | cut -d' ' -f1)" = "$raw_sha" ] || { echo "HARD-FAIL (CONSIST-5): raw/ verändert (AD-3)" >&2; exit 1; } +echo "RESULT: PASS — CONSIST-5: VALIDATION_FAIL — §6-Pkt.-3-Rollback, keine weiteren Mutationen, Endzustand konsistent (Zustands-Restaurations-Invariante); raw/ unverändert (AD-3)" + +# ---- CONSIST-6: VALIDATION_SUCCESS (AC-3; §5.13 Pkt. 6) ---- +runlabel "CONSIST-6: VALIDATION_SUCCESS (AC-3) — Mutationen als Ganzes committet (erst nach Diff-Selbsttest ohne Ghost-Diff, §5.9 Pkt. 5); Diff gg. Plan-Menge gedeckt; §6-Pkt.-4-Nachweis; kein Wanduhr-Trigger (A0-20)" +isolate consist6 +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" +p2_plan "alpha" "alpha-v2.md" >/dev/null || exit 1 +log_plan "alpha betroffen via raw/alpha-v2.md" +echo "--- Mutationsphase: geplante Mutation von alpha (regelkonform) ---" +cat >> wiki/alpha.md <<'EOF' +Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3). +EOF +echo "--- Diff-Selbsttest VOR dem Commit (§5.9 Pkt. 5): {alpha, log} — kein Ghost-Diff ---"; probe +assert_invariant "alpha log" +echo "--- Plan-Freeze-Check (§5.13 Pkt. 2): Diff gg. Plan-Menge gedeckt ---" +freeze_check "alpha log index" || exit 1 +echo "--- Validierungsphase (§6): SUCCESS -> §6-Pkt.-4-Nachweis und SUCCESS-Bullet VOR dem Commit (§5.13 Pkt. 6) ---" +echo "--- §6-Pkt.-4-Nachweis: Verdikt je Datei SUCCESS (frontmatter-Konformität) ---" +assert_frontmatter wiki/alpha.md +echo " (§5.13-demo: alpha bleibt frontmatter-konform — kein unbefugter Key, generated.at volles Datetime; die sources-Nachführung des update-Pfads gehört §5.9/§5.10, nicht in die Phasen-Disziplin)" +log_commit "Diff gg. Plan-Menge gedeckt ({alpha, log}), kein Ghost-Diff" +echo "--- Mutationsphase zu Ende: Mutationen als Ganzes committen (§5.13 Pkt. 6, Commit-Boundary AD-17f) — Commit enthält alpha + log.md mit Plan- und SUCCESS-Bullets ---" +git add -A && git commit -qm "Run: alpha-Update (Story 3.7 CONSIST-6)" +grep -qF 'Änderungsplanung (P2-Block' wiki/log.md || { echo "HARD-FAIL (CONSIST-6): Plan-Nachweis fehlt (Pkt. 1)" >&2; exit 1; } +grep -qF 'Validierung SUCCESS' wiki/log.md || { echo "HARD-FAIL (CONSIST-6): §6-Pkt.-4-Nachweis fehlt (Pkt. 6)" >&2; exit 1; } +echo "--- kein Wanduhr-Trigger (A0-20): der Commit folgt aus Phasenabschluss, nicht aus Kalenderzeit ---" +echo "RESULT: PASS — CONSIST-6: VALIDATION_SUCCESS — Mutationen als Ganzes committet (nach Diff-Selbsttest ohne Ghost-Diff); Diff gg. Plan-Menge gedeckt; §6-Pkt.-4-Nachweis; Aktivierungs-Befund zu Wanduhr-Trigger siehe CONSIST-7" + +# ---- CONSIST-7: DETERMINISMUS-ZWEI-RUN + KEINE_ENGINE (AC-4; §5.13 Pkt. 7) ---- +runlabel "CONSIST-7: DETERMINISMUS-ZWEI-RUN + KEINE_ENGINE (AC-4, AD-17h/A0-19, D-3/AD-11) — zwei identische Runs -> identische Plan-/Rollback-/State-Outputs; die Phasen-Trennung ist logisch in einer Session — keine Hintergrundprozesse/Server/MCP (grep-Negativkontrolle)" +echo "--- KEINE_ENGINE-Negativkontrolle: der Run startet keinen Prozess/Server/MCP (nur Shell/Git/Datei, D-3/AD-11) ---" +# Robustheits-Guard: pgrep bevorzugt, sonst ps-basierte Negativkontrolle (portabel, nicht-vakuum). +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 — Negativkontrolle kann nicht greifen" >&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 §5.13 Pkt. 7 / D-3 / AD-11): 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) — keine eigene Engine (AC-4)" +fi +consist7_run() { # deterministischer Run auf isoliertem Zustand (identische Plan-/Rollback-/State-Outputs) + local branch="$1" + isolate "$branch" + 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" + local plan cap_commit + plan=$(p2_plan "alpha" "alpha-v2.md") || return 99 + # Plan-Capture-Disclaimer (BH-13): plan-run.capture ist NUR ein deterministischer Sandbox-Zeuge + # für den Zwei-Run-Vergleich — NICHT Teil der §5.13-Ausführungsdisziplin (die Instruktion + # verlangt laut Ask-First kein Plan-Artefakt-File; „kein Artefakt-File" bleibt die Norm). + echo "$plan" > plan-run.capture + git add -A && git commit -qm "Plan-Capture" + cap_commit=$(git rev-parse HEAD) + # Rollback-Pfad: Teilzustand schreiben + Abbruch + Rollback (Zustands-Restaurations-Invariante) + cat >> wiki/alpha.md <<'EOF' +Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3). +EOF + rollback >/dev/null + # Plan-Capture aus dem committeten Baum lesen: rollback () resettet auf BASE und entfernt so + # die Arbeitskopie von plan-run.capture (nur im Plan-Capture-Commit getrackt) — der committete + # Baum bleibt als deterministischer Zeuge erhalten (AD-17h/A0-19). + plan_state=$(git show "$cap_commit:plan-run.capture") + plan_sha=$(git show "$cap_commit:plan-run.capture" | sha256sum | cut -d' ' -f1) + # log_sha nach Rollback ist definitionsgemäß die Baseline-Konstante (leerer Indikator — die + # Baseline-log.md wird gegen sich selbst gemessen); Determinismus-Zeuge ist plan_sha/plan_state + # aus dem committeten Plan-Capture (non-vacuous). + echo "state plan=[$plan_state] plan_sha=$plan_sha" +} +echo "--- Zwei identische Runs (gleicher Baum-Input) ---" +S7A=$(consist7_run s7a) +echo "Run A: $S7A" +S7B=$(consist7_run s7b) +echo "Run B: $S7B" +[ "$S7A" = "$S7B" ] || { echo "HARD-FAIL (CONSIST-7): Plan-/State-Outputs zweier identischer Runs weichen ab (AD-17h/A0-19, §5.13 Pkt. 1/7)" >&2; exit 1; } +echo "--- Zustands-Restaurations-Invariante im Zwei-Run-Pfad (Rollback >> Baseline leer) ---" +isolate s7c +[ "$(inv_set)" = "" ] || { echo "HARD-FAIL (CONSIST-7): kein Ferien-Zustand nach Rollback erwartet (leer)" >&2; exit 1; } +echo "RESULT: PASS — CONSIST-7: Zwei identische Runs -> identische Plan-/Rollback-/State-Outputs (AD-17h/A0-19); keine Workflow-Engine gestartet (D-3/AD-11, KEINE_EIGENE_ENGINE §5.13 Pkt. 7, AC-4)" + +echo +echo "===== Sandbox abgeschlossen (CONSIST-1..CONSIST-7) =====" +echo "Sandbox-Root: $ROOT (loeschbar: rm -rf $ROOT)" diff --git a/_bmad-output/implementation-artifacts/spec-3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell.md b/_bmad-output/implementation-artifacts/spec-3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell.md new file mode 100644 index 0000000..8fb9362 --- /dev/null +++ b/_bmad-output/implementation-artifacts/spec-3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell.md @@ -0,0 +1,140 @@ +--- +title: 'Story 3.7 — Reason/Mutate-Trennung & Konsistenz-Endzustand sicherstellen' +type: 'feature' +created: '2026-08-20' +status: 'done' +baseline_commit: '861e65f628001ffe8da05d0fd6834b7bb2689202' +review_loop_iteration: 0 +context: + - '_bmad-output/implementation-artifacts/epic-3-context.md' +--- + + + +## Intent + +**Problem:** AD-6/A0-7 trennen einen Compilation Run **logisch** in Analyse → Änderungsplanung → Mutation → Validierung, doch die Compiler-Instruktion führt die Phasen-Trennung nirgends explizit als **durchsetzbare Disziplin** — die feste Ablaufstruktur in §0 zählt nur Phasen (0)–(5), und die Plan-Vorprüfung (P2-Block) ist ein Baustein in §5.9 Pkt. 6, ohne als **Änderungsplanungs-Phase mit Endzustands-Garantie** ausgewiesen zu sein. Folge: Ein teilweise fehlgeschlagener Run könnte Zwischenstände hinterlassen, deren Konsistenz (AD-6: „Der beobachtbare Endzustand muss ein konsistentes Bundle sein") nur implizit über §6-Rollback abgesichert ist. A0-7-AC-2: „**Given** ein Fehler während der Mutation, **When** der Run abbricht, **Then** bleibt der beobachtbare Endzustand des Bundles konsistent". + +**Approach:** Neue Sektion **§5.13 „Reason/Mutate-Phasen-Trennung & Konsistenz-Endzustand (Story 3.7)"** (nach §5.12, vor §6): die **logische Phasen-Disziplin** von AD-6 verbindlich in die Instruktion heben — der P2-Vorprüf-Block (§5.9 Pkt. 6) wird als **Änderungsplanung** (Analyse-Ergebnis → konsistenter Plan: Input-Zustand, Ziel-Pfade, Quellen-Existenz, Betroffenheits-Liste, Struktur-Erhaltung) institutionalisiert; die §§5/§5.9/§5.10-Mutationsmechanik wird als **Mutationsphase** unter **Veränderungs-Sperre nach Phasenabschluss** (Plan freeze), die §§6/§5.3-Rollback-Maschinerie als **Validierungsphase** mit **Zustands-Restaurations-Invariante** (Post-Rollback-Zustand == Baseline) geschlossen. **Ohne eigene Workflow Engine** (D-3, AD-6): die Trennung ist eine textuelle Ausführungs-Disziplin in einer Session. Endzustands-Konsistenz wird als **beobachtbare, über Git-State überprüfbare Eigenschaft** fixiert — nach einem abgebrochenen/fehlgeschlagenen Run ist der Bundle-Zustand der Baseline (oder der einer abgeschlossenen, valide committeten Mutation). + +## Boundaries & Constraints + +**Always:** +- Nur `schema/compiler.md` (neue §5.13 + §7-Auflösung + §8 Revisionslog-Revision 3.2) mutiert (D-3); `schema/validator.md`, `schema/wiki-compiler.md`, `adapters/`, `raw/` read-only (AD-3). Kein Standalone (D-3), keine eigene Workflow Engine (AD-6), keine neue §7-Invaliditätsklasse, kein Vertrags-Change, kein neuer Prädikat-/Format-Key, kein neuer Frontmatter-Key. +- Deterministisch aus dem committeten Git-State ableitbar (AD-17h/A0-19): Plan-Inhalt, Phasen-Reihenfolge, Rollback-Trigger und Post-Zustand; **keine Wanduhr/`now`-Steuerung** der Phasen-Disziplin (weder Planung noch Rollback hängen von Kalenderzeit ab). +- Endzustands-Konsistenz ist eine **beobachtbare, über Git prüfbare** Eigenschaft: Post-Rollback-Diff leer gg. Baseline bzw. Bundle == valide committeter Zustand des aktuellen Runs (Commit-Boundary = Mutation-Boundary, AD-17f, §0/§5.3). +- Die **vier** AD-6-Phasen decken sich **logisch** mit der §0-Ablaufstruktur (Analyse ≈ §1/§3.2, Änderungsplanung ≈ §5.9 Pkt. 6-P2-Block, Mutation ≈ §§4–5, Validierung ≈ §6); keine neue $Phasen-Nummerierung im §0-Listentext, §0 bleibt die deterministische Ausführungs-Folge. + +**Ask First:** +- Einführung einer echten Planungs-Artefakt-Datei (separater Plan als persistentes Verzeichnis-Artefakt) statt des textuell festgehaltenen P2-Block-Plans — wäre eine neue Datei-/Baum-Regel außerhalb der Erhaltungs-Invariante. +- Änderung des §0-Phasen-Listentextes (Umformulierung der festen Folge) oder zusätzliche Phase — §0 bleibt Takt-Quelle; §5.13 ordnet nur logisch zu. +- Plan-freeze mit maschinellem Vergleich geplanter vs. tatsächlicher Mutationen über den §5.9-Pkt.-5-Diff-Selbsttest hinaus. + +**Never:** +- `raw/`-Inhalte verändern (AD-3); uncommittete fremde `wiki/`-Änderungen löschen (AD-17e); textuelle Auto-Merge bei Branch-Konvergenz (AD-17c); Wanduhr/`now`-Zeitstempel als Phasen- oder Rollback-Steuer-Größe; eigener `# Log`-Stand in der Registry (`wiki/log.md`-Akkumulator ist alleiniger Aufzeichnungs-Ort, Vertrag §5); Standalone-Compiler/eigene LLM-Runtime (D-3, AD-11); Änderung an `schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`. + +## I/O & Edge-Case Matrix + +| Scenario | Input / State | Expected Output / Behavior | Error Handling | +|----------|--------------|---------------------------|----------------| +| PLAN_BEABSICHTIGT | erkannte Erkenntnis + bestehende Reconcile-Kandidaten; P2-Block-Ausführung | konsistente Änderungsplanung: Input-Zustand ⊇ Zuwachs committet, Ziel-Pfade ⊆ Kandidaten∪Neu-Anlage, Quellen-Existenz (EC-1), Betroffenheits-Liste (§3 Pkt. 2), Struktur-Erhaltung; Plan wird textuell festgehalten | Plan-Defizit benannt (NFR-4); fehlgeschlagene Vorprüfung ⇒ keine Mutation (Kette: Abbruch vor Mutationsphase) | +| PLAN_FREEZE | Mutationsphase beginnt | Änderungsplanung ist abgeschlossen; **Veränderungs-Sperre**: kein Plan-Gegenstand außerhalb der erlaubten Pfad-Menge (Kandidatenliste ∪ Neu-Anlage ∪ `log.md` ∪ `index.md`) wird mutiert | Verletzung = Ghost-Diff (§5.9 Pkt. 5): zurückrollen, textuell benannt | +| MUTATION_ABBRUCH | Fehler während der Mutationsphase | Run bricht ab; beobachtbarer Endzustand: **Zustands-Restaurations-Invariante** — Post-Rollback-Diff gg. Baseline leer / Zustand == Baseline; `raw/` unverändert (AD-3) | §5.3-Pkt.-3/§6-Pkt.-3-Rollback-Mechanik greift; Ghost-Diff-Rollback (§5.9 Pkt. 5) greift; beides deterministisch aus Git-Teilen | +| MUTATION_TEILFOLGE | mehrere geplante Mutationen, nur ein Teil ausgeführt | Rollback stellt Baseline wieder her; kein Teilerfolg wird als fertige Mutation veröffentlicht (Commit-Boundary = Mutation-Boundary) | Textuelle Failure-Benennung (NFR-4); Phasen-Disziplin unverändert | +| VALIDATION_FAIL | Validierung meldet FAIL | Run als gescheitert; §6-Pkt.-3-Rollback; **keine** weiteren Mutationen; Endzustand konsistent | Rollback gemäß §5.3/§6; `raw/` unverändert | +| VALIDATION_SUCCESS | alle `wiki/`-Dateien SUCCESS | Mutationen als Ganzes committen; Konsistenz = valide committeter Zustand; §6-Pkt.-4-Ausführungs-Nachweis | Commit erst nach Diff-Selbsttest ohne Ghost-Diff (§5.9 Pkt. 5); kein Wanduhr-Zeitstempel | +| KEINE_EIGENE_ENGINE | Anforderung „keine separate Workflow Engine" (AD-6) | logische Trennung in einer Session, kein neuer Prozess/Server/MCP | D-3/AD-11 unverändert; nichts Steuerndes wird gebaut | + +## Code Map + +- `schema/compiler.md` — **primär mutiert** (D-3): neue Sektion **§5.13** „Reason/Mutate-Phasen-Trennung & Konsistenz-Endzustand (Story 3.7)" (nach §5.12, vor §6; Fixierung: §5.12-Ende Z. 341, §6-Start Z. 364 — neue Sektion zwischen beide, §5.13 Z. 343–362); §0-Phasen-Listentext **unverändert** (Takt-Quelle; §5.13 ordnet nur logisch zu); §5.9-Pkt.-6-P2-Block **Wortlaut-unverändert**, wird als Änderungsplanung referenziert (Rückverweis, keine Doppel-Instruktion); §6-Pkt.-3/§5.3-Rollback **Wortlaut-unverändert**, als Validierungsphase + Zustands-Restaurations-Invariante geschlossen; §7 (`Z. 390ff.`) Reason/Mutate-Vorbehalt **als neuer §7-Bullet** „in §5.13 verankert (Story 3.7)" (AD-6, A0-7, AC-1/2/3/4); §8-Normreferenz-`AD-6` (`Z. 430`) von reiner Story-Zuordnung auf **§5.13-Anker** angehoben. Anker (IST-Zeilen nach Implementierung): §5.13-Sektion Z. **343**; §7-Bullet nach Z. **420** (nach „Relevanzbestimmung"-Bullet); §8-AD-6 in Z. **430**; Revisionslog-Eintrag **Revision 3.2** nach Z. **461**. +- `wiki/log.md` — **append** (append-only, Vertrag §5): Story-3.7-Eintrag (Verankerung, Sandbox-Nachweis, Statuswechsel, Validator-Verdikt); bestehende Bullets unverändert. +- `_bmad-output/implementation-artifacts/sandbox-3-7/run-sandbox.sh` — **neu** (re-executierbar, Muster sandbox-3-6, Exit 0): Szenarien CONSIST-1..CONSIST-7 (s. Design Notes), harte Pass/Fail-Assertionen, Erhaltungs-/Restaurations-Invariante erzwungen, keine Berührung des realen Ist-Baums. +- `_bmad-output/implementation-artifacts/sprint-status.yaml` — **mutiert**: `3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell` `backlog` → `in-progress`; `last_updated` (Format `MM-DD-YYYY HH:MM`, HEAD-Präzision). +- `_bmad-output/implementation-artifacts/deferred-work.md` — **append** (append-only): ggf. Story-3.7-Defers (z. B. maschineller Plan-vs-Ist-Vergleich über den §5.9-Pkt.-5-Diff-Selbsttest hinaus), nach Prüfung der vorhandenen Defer-Liste (keine bereits auf Story 3.7 gedeuteten Einträge; Stand: keine Home-3.7-Defers vorhanden). +- `_bmad-output/implementation-artifacts/epic-3-context.md`, `spec-3-6-…md` — **read-only** (continue-context; Kette unverändert). + +## Tasks & Acceptance + +**Execution:** +- [x] `schema/compiler.md` — §5.13 einfügen (nach §5.12, vor §6); §0/§5.9-Pkt.-6/§6 Wortlaut-unverändert referenzieren; kein neuer Prädikat-/Format-/Frontmatter-Key +- [x] `schema/compiler.md` — Revision 3.2 in §8 belegen (AD-6/A0-7 auf §5.13-Anker, Abschlussklausel) und §7-Bullet Reason/Mutate in §5.13-Verankerung +- [x] `_bmad-output/implementation-artifacts/sandbox-3-7/run-sandbox.sh` — Szenarien CONSIST-1..7 (Plan-Erzeugung, Freeze-Sperre, Rollback-Restaurations-Invariante, Teilerfolg, Validierungs-Fail, Success-Commit, keine Engine), Exit 0 +- [x] `_bmad-output/implementation-artifacts/deferred-work.md` — ggf. Story-3.7-Defers append-only; keine Spuren in bereits vorhandenen Einträgen (Stand: keine Home-3.7-Defers — nichts anzuhängen, wie per README) +- [x] `wiki/log.md` — (Implementierung) Story-3.7-Eintrag, `sprint-status.yaml` → in-progress; Review-Abschluss `done` im Review-Schritt (Workflow-Konvention) + +**Acceptance Criteria:** +- Given ein Run, when er Änderungen plant, then erzeugt er zunächst eine konsistente Änderungsplanung (Analyse → Reconcile → Plan Changes → Mutate → Validate), textuell festgehalten (AD-6, A0-7; AC-1). +- Given ein Fehler während der Mutation, when der Run abbricht, then bleibt der beobachtbare Endzustand des Bundles konsistent — Post-Rollback-Diff gg. Baseline leer, `raw/` unverändert (AD-6; AC-2, I/O-Matrix MUTATION_ABBRUCH). +- Given ein Run, when er abgeschlossen ist, then wurden alle geplanten Mutations-Validierungen erfolgreich durchlaufen und die Mutationen als Ganzes committet (A0-7; AC-3, VALIDATION_SUCCESS). +- Given die Architektur-Anforderung, when umgesetzt, then ist die Trennung logisch, ohne eigene Workflow Engine (AD-6; AC-4, KEINE_EIGENE_ENGINE). + +## Spec Change Log + +_Noch leer — wird von step-04 während der Review-Loops befüllt (append-only Konvention)._ + + + +## Design Notes + +**Warum §5.13 als eigene Sektion, nicht §0-Umbau?** §0 (Z. 13) ist die **deterministische Takt-Folge** — (0)..(5) in fester Reihenfolge, das Rückgrat der Instruktion. AD-6 trennt **logisch**, ohne neue Workflow-Engine; die **vier** AD-6-Phasen sind eine **konsolidierende Klassifikation** derselben Ablaufstruktur (Analyse ≈ §1/§3.2, Änderungsplanung ≈ §5.9 Pkt. 6-P2-Block, Mutation ≈ §§4–5, Validierung ≈ §6). Ein Umbau von §0 allein würde die bestehenden Story-Statements (§5.9/§5.10/§5.11/§5.12: „dieselben Phasen §0: Interpretieren → Reconcile → Synthetisieren → Mutieren → Validieren") brechen. Deshalb: §5.13 referenziert den §0-Wortlaut **unverändert** und bindet die AD-6-Nomenklatur als Ausführungs-Disziplin an die bestehende Struktur — Review-Layer prüfen die Fugen-Identität (keine Um-Nummerierung im §0-Listentext, keine neue Phase). + +**Der P2-Block (§5.9 Pkt. 6) ist die natürliche Änderungsplanung.** Bereits vorhanden und reproduzierbar: (1) Input-Zustand (AD-17a), (2) Ziel-Pfade, (3) Quellen-Existenz, (4) Betroffenheits-Liste (§3 Pkt. 2), (5) index.md-V-1, (6) Struktur-Erhaltungs-Check. §5.13 macht diese Vorprüfung zur **Änderungsplanung der AD-6-Kette** und ergänzt zwei institutionalisierte Eigenschaften: den **Plan-Freeze** (Veränderungs-Sperre — nach Phasenabschluss wird kein Pfad außerhalb der erlaubten Menge berührt, Kopplung an die §5.9-Pkt.-5-Diff-Probe) und den **Plan-Nachweis** (der Plan wird als Teil der textuellen Ausführungsdisziplin festgehalten — kein Artefakt-File, keine Erhaltungs-Invarianten-Ausweitung). + +**Die Konsistenz-Garantie ist bereits vorhanden — §5.13 macht sie beobachtbar.** §6-Pkt.-3/§5.3-Pkt.-3-Rollback und der Ghost-Diff-Rollback (§5.9 Pkt. 5, „AD-6-Backstop") existieren; die Anforderung „Endzustand konsistent" ist aber bislang eine erzählte Eigenschaft, keine **git-überprüfbare Invariante**. §5.13 definiert die **Zustands-Restaurations-Invariante**: nach Abbruch/FAIL ist `git diff` gegen die Baseline leer (Bundle == Baseline) **oder** das Bundle ist der valide committete Zustand des Runs (Erfolgsfall; Commit-Boundary = Mutation-Boundary, AD-17f). Beide Pfade sind deterministisch und ohne Wanduhr. + +**Sandbox (CONSIST-1..CONSIST-7, `bash run-sandbox.sh`, Exit 0):** +- CONSIST-1: konsistente Änderungsplanung — P2-Block erzeugt Plan (Input-Zustand, Ziel-Pfade, Betroffenheit, Struktur-Erhaltung) aus committetem Input, als Variablen-Set captured, Determinismus (AD-17h/A0-19) +- CONSIST-2: **Plan-Freeze** — Mutation außerhalb der Plan-Pfadmengen wird erkannt und verweigert/verhindert (Veränderungs-Sperre, Ghost-Diff-Kopplung §5.9 Pkt. 5) +- CONSIST-3: **Rollback-Restaurations-Invariante** — fehlgeschlagene Mutation rollt auf exakte Baseline zurück (SHA-256 byte-identisch), Bundle-Zustand == Baseline +- CONSIST-4: MUTATION_ABBRUCH — Abbruch nach Teilerfolg hinterlässt keinen Teilerfolg als fertige Mutation (Commit-Boundary), `raw/` unberührt +- CONSIST-5: VALIDATION_FAIL — §6-Pkt.-3-Rollback, keine weiteren Mutationen, Endzustand konsistent +- CONSIST-6: VALIDATION_SUCCESS — Mutationen als Ganzes committet, Diff gg. Plan-Menge gedeckt, §6-Pkt.-4-Nachweis +- CONSIST-7: **Determinismus-Zwei-Run + keine Engine** — gleicher Baum-Input → identische Plan-/Rollback-/State-Outputs; Trennung ohne Workflow-Engine (nur Shell/Git/Datei, D-3) + +(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-7/run-sandbox.sh` — expected: CONSIST-1..CONSIST-7 harte PASS/Fail, Restaurations-Invariante erzwungen, Exit 0. +2. `grep -n "§5.13\|Revision 3.2" schema/compiler.md` — liefert §5.13-Sektion + Revisionslog-Eintrag; `grep -n "Reason/Mutate-Phasen-Trennung" schema/compiler.md` — die §5.13-Überschrift wortgleich (inkl. §5.12-Seam-Satz in §5.13-Intro). +3. Read-only (AD-3): `git status --porcelain` zeigt keinen Change an `schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`/`raw/`. +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-7/` liegen außerhalb `wiki/` und sind nicht Teil der Diff-Probe (wie §5.9 Pkt. 5-Doku, Story-3.6-Präzedenz). + +**Zu beachten (beim step-04-Review):** (a) §0-Phasen-Listentext, §5.9-Pkt.-6-P2-Block und §6-Pkt.-3/§5.3-Referenz müssen textuell **unverändert** bleiben — §5.13 verweist auf sie (Fugen-Identität: Um-Nummerierung oder neue Phase => Ask-First); (b) „die **vier** AD-6-Phasen decken sich logisch mit der §0-Struktur" ersetzt **keine** §0-Normierungen — sie ist eine Zuordnungstabelle, kein Parsing-Muss; (c) die vorhandene §8-Revisionslog-Nummer ist **3.1** (Story 3.6); **Revision 3.2 ist für Story 3.7 frei** (grep-verifiziert: keine 3.2 im Revisionslog); (d) kein neuer §7-Bullet ersetzt einen bestehenden — der Reason/Mutate-Bullet wird **ergänzt**, die bestehenden Story-Bullets (2.2/2.3/2.4/2.5/3.2/3.4/3.5/3.6) bleiben unverändert. + +## Suggested Review Order + +**§5.13-Reason/Mutate-Trennung-Instruktion** + +- Einstieg: §5.13-Sektion — logische Phasen-Disziplin (AD-6/A0-7), Kern der Story, §5.12-Seam und §0-Zuordnungstabelle. + [`compiler.md:343`](../../schema/compiler.md#L343) +- Änderungsplanung: P2-Block (§5.9 Pkt. 6) als Phase institutionalisiert, Plan-Freeze (Veränderungs-Sperre, Ghost-Diff-Kopplung §5.9 Pkt. 5). + [`compiler.md:356`](../../schema/compiler.md#L356) +- Zustands-Restaurations-Invariante: Post-Rollback-Diff gg. Baseline leer / Bundle == valide committet; §6-Pkt.-3/§5.3-Rückverweis unverändert. + [`compiler.md:358`](../../schema/compiler.md#L358) +- Keine eigene Workflow Engine (D-3, AD-6): logische Trennung in einer Session, kein Prozess/Server/MCP. + [`compiler.md:362`](../../schema/compiler.md#L362) + +**§7/§8-Nachweis** + +- §7-Bullet Reason/Mutate-Trennung — „in §5.13 verankert (Story 3.7)", AD-6/A0-7, bestehende Bullets unverändert. + [`compiler.md:420`](../../schema/compiler.md#L420) +- §8-Revisionslog Revision 3.2 — Verankerung, Abschlussklausel, AD-6 auf §5.13-Anker. + [`compiler.md:461`](../../schema/compiler.md#L461) + +**Sandbox-Nachweis** + +- Sandbox CONSIST-1..CONSIST-7 — re-executierbar, harte PASS/Fail, Zustands-Restaurations-Invariante (Exit 0) + [`run-sandbox.sh:1`](../../_bmad-output/implementation-artifacts/sandbox-3-7/run-sandbox.sh#L1) + +**Story-Protokoll/Defers** + +- log.md — Story-3.7-Eintrag (Verankerung, Sandbox-Nachweis, Statuswechsel). + [`log.md:1`](../../wiki/log.md#L1) +- sprint-status.yaml — `3-7-…` → in-progress (Implementierung) — nur `backlog → in-progress`; das `done`-Transition ist nicht Teil dieses Diffs (Review-Schritt). + [`sprint-status.yaml:60`](../../_bmad-output/implementation-artifacts/sprint-status.yaml#L60) +- deferred-work.md — ggf. Story-3.7-Defers append-only. + [`deferred-work.md:1`](../../_bmad-output/implementation-artifacts/deferred-work.md#L1) diff --git a/_bmad-output/implementation-artifacts/sprint-status.yaml b/_bmad-output/implementation-artifacts/sprint-status.yaml index 5a24177..a01434e 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-19-2026 22:10 +last_updated: 08-20-2026 00:30 project: wow20 project_key: NOKEY tracking_system: file-system @@ -57,7 +57,7 @@ development_status: 3-4-wissen-aus-mehreren-sources-synthetisieren: done 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: backlog + 3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell: review 3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato: backlog epic-3-retrospective: optional diff --git a/schema/compiler.md b/schema/compiler.md index ac47a59..9996af2 100644 --- a/schema/compiler.md +++ b/schema/compiler.md @@ -340,6 +340,27 @@ Der §5.11-Lease-Hold (`lease//`-Branches, Lockfile, Merge-Base-Diszip 7. **`log.md`-Eintragspflicht & Determinismus-Vertrag (Vertrag §5; AD-17h/A0-19):** Jede Staleness-/Recovery-Koordinationsentscheidung wird als datumsgruppierter `wiki/log.md`-Eintrag dokumentiert (Header = ISO-Datum `YYYY-MM-DD`, **neueste zuerst** — Vertrag-§5-Datumsgruppe, wie §5.9 Pkt. 4/§5.11 Pkt. 6): **(a) Registrierung/TTL** (Erzeugungs-Generation, Registry-Marker-Referenz, `` — deterministisch auflösbar, D-2), **(b) Lease-Übernahme** (verwaiste Lease, angestrebte Merge-Base, neuer holder_id), **(c) Stale-Markierung** (verwaiste Lease → Marker der aktuellen Generation, Blockade aufgehoben) und **(d) Recovery-Basis-Nutzung** (bei Rückgriff auf `raw/` bzw. Stash-Restore, Pfad-Referenz). **Determinismus-Vertrag (AD-17h/A0-19):** Registrierungs-Aufbau, TTL-Ablauf-Kriterium (Generationen), Verwaist-Klassifikation und `log.md`-Texte folgen **deterministisch aus dem committeten Git-State** (gleicher Git-State + gleiche Eingabemenge → identische Staleness-/Recovery-Entscheidung); **kein Wanduhr-Timestamp steuert** einen dieser Vorgänge (A0-20-Konvention unverändert). +## 5.13 Reason/Mutate-Phasen-Trennung & Konsistenz-Endzustand (Story 3.7) + +Diese Sektion ist der **einzige Instruktions-Ort der Reason/Mutate-Phasen-Disziplin** (D-3, Story 3.7; AD-6, A0-7): sie bindet die **logische Phasen-Trennung** von AD-6 (Analyse → Änderungsplanung → Mutation → Validierung) als **durchsetzbare Ausführungs-Disziplin** an die bestehende, **unverändert** verbindliche §0-Ablaufstruktur. Der §7-Vorbehalt dieser Trennung ist damit **in dieser Sektion verankert (Story 3.7)**. Sie fügt **kein** Prädikat, **keine** neue §7-Invaliditätsklasse, **keinen** `schema/wiki-compiler.md`-/`schema/validator.md`-/`raw/`-Change hinzu (AD-3) und **keinen** Standalone (D-3) — und sie baut **keine eigene Workflow-Engine** (AD-6, A0-7-AC-4): die Trennung ist eine **textuelle Ausführungs-Disziplin in einer Session** (Analyse → Änderungsplanung → Mutation → Validierung laufen nacheinander in dem einen vorhandenen agentischen Run; kein neuer Prozess/Server/MCP). Die Endzustands-Konsistenz wird als **beobachtbare, über Git prüfbare Eigenschaft** fixiert (A0-7-AC-2): nach einem abgebrochenen/fehlgeschlagenen Run ist der beobachtbare Bundle-Endzustand der Baseline **oder** der einer abgeschlossenen, valide committeten Mutation — **deterministisch und ohne Wanduhr** (AD-17h/A0-19, A0-20: weder Planung noch Rollback hängen von Kalenderzeit ab). Der §5.12-Seam-Satz bleibt unverändert (Lease-Staleness/Recovery: Story 3.6); diese Sektion mutiert deren Mechanik nicht. + +| AD-6-Phase (logisch) | §0-Ablaufstruktur (deterministische Takt-Folge) | +|---|---| +| **Analyse** | (0) Input prüfen, (1) Interpretieren, (2) Reconcile (inkl. §3.2-Relevanzbestimmung) | +| **Änderungsplanung** | §5.9 Pkt. 6-P2-Block (Pre-Run-Reconcile-Check-Block, nach Reconcile/vor Mutieren) | +| **Mutation** | (3) Synthetisieren, (4) Mutieren (§§4–5, §5.9/§5.10/§5.11/§5.12-Mechanik) | +| **Validierung** | (5) Validieren (§6; Rollback §5.3 Pkt. 3 / §6 Pkt. 3, Ghost-Diff-Rollback §5.9 Pkt. 5) | + +Die Tabelle ist eine **Zuordnungsklassifikation ohne neue Norm**: §0 bleibt die **deterministische Ausführungs-Folge** (unverändert, keine Um-Nummerierung, keine neue Phase); die **vier** AD-6-Phasen decken sich **logisch** mit ihr (Reconcile ist in die Analyse-Zelle der Zuordnungstabelle gefasst) — ein Umbau des §0-Listentextes oder eine zusätzliche Phase wäre Ask-First. + +1. **Änderungsplanung (AD-6, A0-7; Analyse-Ergebnis → konsistenter Plan):** Der **P2-Block (§5.9 Pkt. 6)** ist die **Änderungsplanung der AD-6-Kette** — er wird **Wortlaut-unverändert** referenziert (Rückverweis, keine Doppel-Instruktion): Aus der Analyse (Input prüfen/Interpretieren/Reconcile, §0 (0)–(2)) konsolidiert der Producer **vor der Mutationsphase** einen konsistenten Plan — (1) Input-Zustand (AD-17a, committet), (2) Ziel-Pfade, (3) Quellen-Existenz (EC-1), (4) Betroffenheits-Liste (§3 Pkt. 2, textuell-deterministisch nach §3.2), (5) `wiki/index.md`-V-1, (6) Struktur-Erhaltungs-Check (Vertrag §3.3/§3.4-Subset, §5.9 Pkt. 6). Ein **Plan-Defizit** (z. B. fehlgeschlagene Vorprüfung, uncommitteter Input `INPUT_UNCOMMITTED`) wird **textuell benannt** (NFR-4) und **verhindert die Mutation** — die Kette bricht **vor** der Mutationsphase ab (I/O-Matrix `PLAN_BEABSICHTIGT`: „fehlgeschlagene Vorprüfung ⇒ keine Mutation"). Der konsistente Plan wird **textuell festgehalten** (Teil der Ausführungsdisziplin — der P2-Block-Befund; **kein** Artefakt-File, keine Erhaltungs-Invarianten-Ausweitung) und ist **deterministisch aus dem committeten Git-State** ableitbar (AD-17h/A0-19): gleicher Git-State + gleiche Eingabemenge → identische Planung. +2. **Plan-Freeze (Veränderungs-Sperre nach Phasenabschluss; AD-6-Kopplung §5.9 Pkt. 5):** Der Abschluss der Änderungsplanung friert den Plan ein: In der Mutationsphase **wird kein Plan-Gegenstand außerhalb der erlaubten Pfad-Menge** — **Kandidatenliste ∪ Neu-Anlage-Zielpfade ∪ `log.md` ∪ nachgeführte `index.md`** (§5.9 Pkt. 5) — mutiert (I/O-Matrix `PLAN_FREEZE`). Eine Verletzung der Sperre ist ein **Ghost-Diff (§5.9 Pkt. 5)**: Der Producer rollt den betreffenden Pfad aus dem Baseline-Zustand zurück und benennt die Verletzung **textuell** (NFR-4), bevor der Run als gültig vermerkt wird. Plan-Freeze und Diff-Probe sind dieselbe §5.9-Pkt.-5-Mechanik — diese Sektion institutionalisiert sie als Phasen-Disziplin, ohne deren Mechanik zu ändern. +3. **Mutationsphase — Abbruch mit Zustands-Restaurations-Invariante (AD-6, A0-7-AC-2):** Bricht der Run während der Mutationsphase ab (Fehler, I/O-Matrix `MUTATION_ABBRUCH`), greift die bestehende Rollback-Maschinerie **Wortlaut-unverändert**: **§5.3 Pkt. 3 / §6 Pkt. 3** (Teilzustand des Bundles zurückrollen) und der **Ghost-Diff-Rollback (§5.9 Pkt. 5)**. Die **Zustands-Restaurations-Invariante** macht die erzählte Konsistenz-Eigenschaft zu einer **beobachtbaren, über Git prüfbaren**: nach Abbruch/FAIL ist der **Post-Rollback-Diff gegen die Baseline leer** — `git diff -- wiki/` ist leer und der Bundle-Zustand **== Baseline** (Restaurations-Fall); Erfolgsfall: das Bundle ist der **valide committete Zustand des Runs** (Commit-Boundary = Mutations-Boundary, AD-17f, §0/§5.3). Beide Pfade sind deterministisch und **ohne Wanduhr** (A0-20). `raw/` bleibt bei jedem Vorgang unverändert (AD-3). +4. **Kein Teilerfolg wird als fertige Mutation veröffentlicht (AD-17f; I/O-Matrix `MUTATION_TEILFOLGE`):** Sind mehrere Mutationen geplant und wird nur ein Teil ausgeführt, stellt der Rollback nach Pkt. 3 die Baseline wieder her — **Zwischenstände werden nie veröffentlicht** (Commit-Boundary = Mutations-Boundary, unverändert). Die **textuelle Failure-Benennung** (NFR-4) und die Phasen-Disziplin selbst bleiben unverändert. +5. **Validierungsphase — FAIL (AD-6; §6 Pkt. 3):** Melden die §6-Validierungen einen **VALIDATION_FAIL**, gilt der Run als gescheitert; es werden **keine weiteren Mutationen** durchgeführt, `raw/` bleibt unangetastet (AD-3), die Fehlerursache wird textuell benannt (NFR-4) und der Teilzustand gemäß **§5.3 Pkt. 3 / §6 Pkt. 3** zurückgerollt — Endzustand konsistent (Zustands-Restaurations-Invariante, Pkt. 3). +6. **Validierungsphase — SUCCESS mit Konsistenz-Commit (AD-6, A0-7-AC-3):** Sind **alle** geplanten Mutations-Validierungen erfolgreich durchlaufen (**VALIDATION_SUCCESS**, alle `wiki/`-Dateien SUCCESS nach §6), werden die Mutationen **als Ganzes committet** — erst nachdem der Diff-Selbsttest (§5.9 Pkt. 5) ohne Ghost-Diff abgeschlossen ist (AD-17f); die Konsistenz des Endzustands ist damit der **valide committete Zustand des Runs**. Der **§6-Pkt.-4-Ausführungs-Nachweis** wird geführt; **kein Wanduhr-Zeitstempel** steuert den Commit (A0-20). +7. **Keine eigene Workflow-Engine (D-3, AD-11, AD-6; I/O-Matrix `KEINE_EIGENE_ENGINE`):** Die Phasen-Trennung ist **logisch in einer Session** — Analyse, Änderungsplanung, Mutation und Validierung laufen in dem einen vorhandenen agentischen Run nacheinander ab; es wird **nichts Steuerndes gebaut** (kein neuer Prozess, kein Server, kein MCP, kein Standalone-Compiler/eigene LLM-Runtime, D-3/AD-11). Die Erhaltungs-Invariante (§5.9 Pkt. 5) und der Diff-Selbsttest gelten **unverändert**; der Determinismus-Vertrag (AD-17h/A0-19) gilt für Plan-Inhalt, Phasen-Reihenfolge, Rollback-Trigger und Post-Zustand. + ## 6. Validieren (mechanische Bestätigung) 1. Nach Abschluss aller Mutationen wird das gesamte Bundle gemäß `schema/validator.md` geprüft (§3 14 Punkte je Datei + §6-Fachprüfungen; Verdikt-Grammatik §5). @@ -396,6 +417,7 @@ Diese Instruktion ist auf die **Erzeugung neuer Concepts auf Root-Ebene und in A - **Synthese über mehrere Sources** (mehrere `raw/`-Quellen → eine gemeinsame Wissensrepräsentation mit gemischter, claim-granularer Provenienz) — **in §5.10** dieser Instruktion verankert (Story 3.4; AD-4, FR-7). Die Verankerung des inkrementellen Datenflusses (Erweitern/Präzisieren/Korrigieren einzelner bestehender Concepts) bleibt **§3 + §5.9** überlassen und ist dort bereits verankert (Story 3.1). Beide sind damit aus diesem Vorbehalt entlassen. - **Leasing / Dirty-Tree-Schutz** für konkurrierende Producer — **in §5.11 dieser Instruktion verankert** (Story 3.5; AD-17a..f, A0-12..A0-16; die Enum enthält AD-17d/A0-15 nur als **Norm-Rückverweis** — die §5.11-Auflösung selbst schließt Staleness aus und delegiert an Story 3.6, Pkt. 7-Seam-Kriterium): Lease-Akquise auf `lease//`-Branches mit Lockfile und Merge-Base-Disziplin, Root-Scope-Lease inkl. `log.md`/`index.md`, Dirty-Tree-Schutz mit Stash/Scratch-Zone und `log.md`-Dokumentation, compiler-vermittelter Merge als AD-16-Pfad, kein textueller Auto-Merge, Commit-Boundary = Mutations-Boundary, Lease-Freigabe (Release, deterministisch); die bestehende Commit-Boundary = Mutations-Boundary-Regel (§0/§5.3, AD-17f) bleibt unverändert bestehender Schutz. **Lease-Staleness/Recovery** (TTL, Lease-Registrierung, verwaiste Leases, `raw/`-Recovery; AD-17d, A0-15) — **in §5.12 dieser Instruktion verankert (Story 3.6)**. - **Relevanzbestimmung** (feinkörniger Relevanz-Findungsmechanismus der Kandidatenerhebung) — in **§3.2** dieser Instruktion verankert (Story 3.2; Term-Ziehverfahren + Kanonisierungs-Resolver `schema/canonical-terms.md`, drei Erhebungs-Stufen grep/ripgrep + `index.md`-Traversal + Link-Following mit besuchter Menge, `log.md`-Exklusion, Candidate-Liste als relative OKF-Pfade ohne `.md`, Determinismus-Vertrag AD-17h/A0-19). Keine neue §7-Klasse, kein Schema-/Validator-Change; die Em-Dash-`—`-Varianten-Lücke ist als Determinismus-Frage an Story 3.8 übergeben. +- **Reason/Mutate-Phasen-Trennung & Konsistenz-Endzustand** (logische Phasen-Disziplin: Analyse → Änderungsplanung → Mutation → Validierung, AD-6/A0-7, AC-1/AC-2/AC-3/AC-4) — **in §5.13 dieser Instruktion verankert (Story 3.7; D-3):** Änderungsplanung als institutionalisierter §5.9-Pkt.-6-P2-Block (textuell festgehalten, Plan-Defizit = textuell benannte Abbruch-Kette vor der Mutation), Plan-Freeze = Veränderungs-Sperre an die §5.9-Pkt.-5-Ghost-Diff-Kopplung (erlaubte Pfad-Menge: Kandidatenliste ∪ Neu-Anlage ∪ `log.md` ∪ `index.md`), Zustands-Restaurations-Invariante (Post-Rollback-Diff gg. Baseline leer / Bundle == valide committet, §5.3-Pkt.-3-/§6-Pkt.-3-Rollback unverändert), kein Teilerfolg als fertige Mutation (AD-17f), keine eigene Workflow-Engine (logische Trennung in einer Session, kein Prozess/Server/MCP, D-3/AD-11). Keine neue §7-Klasse, kein Schema-/Validator-Change, keine Vertragsänderung. - **Standalone-Compiler / eigene LLM-Runtime / MCP** → verboten in v1 (D-3, D-4, AD-11). - **OKF-Dialekt / Schema-Erweiterung** → niemals (AD-1a; Vertrag §7 „abschließende Liste"). @@ -405,7 +427,7 @@ Diese Instruktion ist auf die **Erzeugung neuer Concepts auf Root-Ebene und in A - `schema/wiki-compiler.md` — autorisierter Vertrag (Story 1.3): §2 Bundleroot, §3.1–§3.7 Feldsubset & Formate, §5 `log.md`-Typ, §6 Index-Regel/Prädikate, §7 abschließende 14-Punkte-Liste, §8 Normreferenzen. - `schema/validator.md` — Prüfgrundlage (Story 1.4, Revision 9): §3 14 Punkte, §4 Normalform (Reihenfolge §4.1, ISO-8601 §4.3), §5 Verdikt, §6 Fachprüfungen (EC-1 Existenz, EC-3 Kalender, EC-11 non-md; Punkt-11-Area-Lesart formalisiert). -- Architektur-Spine (raw/`architecture-spine`): AD-2/AD-3 (raw immutable), AD-4a (claim-granulare Provenienz, §5.5), AD-5 (inkrementelle Kompilation), AD-6 (Reason/Mutate-Trennung), AD-7a (Identität = OKF-Pfad ohne `.md`, §5.7), AD-7b (genau eine Linkform gepinnt, §5.6), AD-7c (deterministische Bereichszuordnung, §5.7), AD-7d (Renaming/Redirect-Pflicht — nicht in den ACs, Epic 3), AD-8 (Standard-Markdown-Links = Navigations-/Beziehungsschicht, §5.6), AD-9 (Progressive Discovery, §5.7/§5.8), AD-10 (agent-unabhängige Regeln), AD-11 (keine eigene Runtime), AD-13 (Retrieval gehört zu Consumers / Suche = Consumer-grep / keine Embedding-Bereichszuordnung, §5.7/§5.8; Relevanzbestimmung textuell-deterministisch, §3.2), AD-14 (Git liefert Historie, nicht Domain-State), AD-15 (Trust-Metadaten v1), AD-16 (Konflikte werden explizit bewahrt), AD-17a (nur veröffentlichte/committete Inhalte als Input), AD-17b (Root-Scope-Lease, §5.11), AD-17c (kein textueller Auto-Merge, compiler-vermittelter Merge, §5.11), AD-17d (Lease-Staleness, §5.12), AD-17e/f (Dirty-Tree-Schutz; Commit-Boundary = Mutations-Boundary, §5.11/§0/§5.3), AD-17g (Unentscheidbarkeit → menschliche Eskalation, §5.11), AD-17h (Determinismus), D-3 (kein Standalone). +- Architektur-Spine (raw/`architecture-spine`): AD-2/AD-3 (raw immutable), AD-4a (claim-granulare Provenienz, §5.5), AD-5 (inkrementelle Kompilation), AD-6 (Reason/Mutate-Trennung, §5.13), AD-7a (Identität = OKF-Pfad ohne `.md`, §5.7), AD-7b (genau eine Linkform gepinnt, §5.6), AD-7c (deterministische Bereichszuordnung, §5.7), AD-7d (Renaming/Redirect-Pflicht — nicht in den ACs, Epic 3), AD-8 (Standard-Markdown-Links = Navigations-/Beziehungsschicht, §5.6), AD-9 (Progressive Discovery, §5.7/§5.8), AD-10 (agent-unabhängige Regeln), AD-11 (keine eigene Runtime), AD-13 (Retrieval gehört zu Consumers / Suche = Consumer-grep / keine Embedding-Bereichszuordnung, §5.7/§5.8; Relevanzbestimmung textuell-deterministisch, §3.2), AD-14 (Git liefert Historie, nicht Domain-State), AD-15 (Trust-Metadaten v1), AD-16 (Konflikte werden explizit bewahrt), AD-17a (nur veröffentlichte/committete Inhalte als Input), AD-17b (Root-Scope-Lease, §5.11), AD-17c (kein textueller Auto-Merge, compiler-vermittelter Merge, §5.11), AD-17d (Lease-Staleness, §5.12), AD-17e/f (Dirty-Tree-Schutz; Commit-Boundary = Mutations-Boundary, §5.11/§0/§5.3), AD-17g (Unentscheidbarkeit → menschliche Eskalation, §5.11), AD-17h (Determinismus), D-3 (kein Standalone). - PRD (raw/prd): FR-2 (Sources vs. Curated), FR-5 (Concept-Erzeugung), FR-9 (OKF-Konformität), FR-10 (Concepts miteinander verlinken, §5.6), FR-11 (Progressive Discovery siehe PRD-§4.3-Zeile unten — Discovery-Pfad/gewurzelte Erreichbarkeit, §5.8), FR-16 (Consumer-Unabhängigkeit), NFR-3 (Agent Readability — Standard-Dateioperationen/grep über `wiki/`, §5.8 Pkt. 4), A-4 (nur lokale Sources). - Epics (raw/epics): Story-2.1-Ziel und -Abgrenzung zu Story 2.2–2.5; A0-3 (Kontext-Marker-Wortlaut, §5.5), A0-8 (Concept-Identität/Normalisierung, §5.7), A0-9 (eine erlaubte Linkform, §5.6), A0-10 (deterministische Bereichszuordnung, §5.7), A0-13 (Lease-Root-Scope, §5.11); FR-6/FR-12/FR-14, A0-6/A0-7/A0-11/A0-18 (Belege der nachkonformierten Concept-Bodies); **A0-6 (inkrementeller Datenfluss Interpret → Reconcile → Synthesize → Update, §0/§3/§5.9), FR-6 (Aktualisierung statt neuer Dateien, §3/§5.9), FR-12 (unverändertes Wissen bleibt erhalten, §5.9)**, **A0-12 (Leasing-Modell — `lease//`-Branches, Merge-Base-Disziplin, Lockfile semantisch identisch in jedem Adapter, §5.11), A0-13 (Root-Scope-Lease inkl. `log.md`/`index.md`/Root-Dateien, §5.11), A0-14 (kein textueller Auto-Merge; compiler-vermittelter Merge über AD-16, §5.11), A0-15 (Lease-Staleness, §5.12), A0-16 (Dirty-Tree-Schutz: Pre-Mutation-Prüfung, Stash/Scratch-Zone, `log.md`-Dokumentation, §5.11)**, **A0-18 (Deterministische Relevanzbestimmung — grep/ripgrep, `index.md`-Traversal, Link-Following, keine Embedding-/Vector-Infrastruktur; §3.2, AD-13, PRD OQ-3)**, **A0-19 (Determinismus-Vertrag: gleicher Git-State + gleiche Eingabemenge → gleicher Bundle-State / gleiche Candidate-Liste in gleicher Reihenfolge; §3.2/§5.11, AD-17h)**. - PRD §4.3 (FR-11 — progressive Discovery, §5.7 Pkt. 5/§5.8) und §8.2/§8.3 (Canonical State; Separation of Concerns), **PRD OQ-3 („Compilation Scope" — wie findet der Compiler relevante vorhandene Concepts; textuell-deterministische Relevanzbestimmung, §3.2; AD-13/A0-18; Muster `raw/architecture-spine/…md` §8.3)**. @@ -436,3 +458,4 @@ Diese Instruktion ist auf die **Erzeugung neuer Concepts auf Root-Ebene und in A - **Revision 2.9 (2026-08-19, Story 3.4):** Neue Sektion **§5.10 „Synthese aus mehreren Sources (Story 3.4)"** eingefügt (nach §5.9, vor §6) — die **verbindliche Verankerung der Synthese-Dimension** (AD-4, FR-7): (1) **Synthese-Stimulus** (≥ 2 belegende `raw/`-Quellen desselben Themas per §2-Interpretation → eine Synthese-Einheit; einzelne Quelle bleibt auf §5.9-/§3.2-Pfad), (2) **Ein-Ziel-Repräsentation (§5.7-Routing; FR-7 AC-1)** — ein Synthese-Concept über einen Ziel-Pfad, `sources`-Liste ≥ 2 Einträge, **deterministisch lexikografisch nach `resource` (LC_ALL=C, AD-17h)**, getrennte Zusammenfassungs-Concepts je Quelle verboten; (3) **gemischte claim-granulare Provenienz (AD-4a/4b, A0-3)** — je Aussage Inline-`raw/`-Verweis §5.5, **Multi-Beleg-Konsolidierung** (§5.5-Semikolon-Form, voller Pfad je Beleg; keine Beleg-Tilgung AD-4), **AD-16-Default** (widersprüchliche Aussagen bleiben, Disagreement in `log.md`; Sandbox-N2); (4) **AD-4c-Übernahme-Marker** („übernommen aus `` auf Basis von ``, nicht eigenständig belegt" — nie alleinige Provenienz; Sandbox-N3); (5) **Reflektiertheits-Selbsttest** (FR-7 AC-4/NFR-7) — keine per-Source-Zusammenfassungs-Struktur („Quelle A: …"), grepbasiert `grep -nE 'Quelle [A-Z]:|Source [A-Z]:'`, Selbsttest-FAIL → textuell benannt (NFR-4) und vor Run-Abschluss behoben; (6) **§5.6-Pin unverändert** + **Form-Wahl-Klassifikationsprobe (Story-3.3-Defer U2/U7)** — Überlapp-Einheiten an die §5.9-Abgrenzungs-Reihenfolge `Korrigieren → Präzisieren → Erweitern → No-Op` (erste zutreffende Form), Textgenauigkeits-Rahmen der übrigen je Teilbestand; (7) **`log.md`-Eintragspflicht** („Story 3.1-Update" bei Update, Anlage-Eintrag bei neuem Synthese-Concept; Multi-Source-Liste + ``); (8) **Erhaltungs-Invariante (§5.9 Pkt. 5 gilt) + Determinismus-Vertrag** (Ziel-Pfad via §3.2/§5.7, `sources`-Lexikografie, Konsolidierung/Form-Zuordnung; `generated.at`-Wanduhr-Gap bleibt A0-20-Konvention, Home Story 3.8). **§7:** Synthese-Vorbehalt **aufgelöst** (in §5.10 verankert; verbleibende 3.x-Themen: Leasing/Dirty-Tree → Story 3.5/3.6). **§8:** Normreferenzen bleiben unverändert (AD-4/AD-4a/FR-7/A0-3 sind bereits über §5.5/Roh-Normreferenzen abgedeckt; AD-4c-Kontext-Marker weiterhin §5.5). **Abschlussklausel:** Keine Änderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3); **keine neue §7-Invaliditätsklasse**; **kein Standalone** (D-3); keine Vertragsänderung; **keine fünfte Update-Form** (Abgrenzungs-Reihenfolge §5.9 unverändert, Synthese = Querschnitt); kein Leasing-Scope; Commit-Boundary-Regel unverändert. **`sprint-status.yaml`:** Key `3-4-wissen-aus-mehreren-sources-synthetisieren` → **`in-progress`**. Sandbox-Nachweis (S1–S6 + N1–N3 + Form-Wahl-Probe = 10 Szenarien, Exit 0) und per-Datei-Validator-Verdikt siehe `wiki/log.md`-Eintrag (Story 3.4, Revision 2.9). **Review-Loop-1-Patches (bmad-code-review, 3 Layer; dieser Eintrag nachgeführt):** Reflektiertheits-Selbsttest-Muster auf Zeilenanfangs-Label erweitert (`^(Quelle|Source) [A-Z][A-Za-z0-9_ -]*:` — mehrbuchstabige/nummerierte Quell-Labels werden ebenso erkannt); **Body-Reihenfolge deterministisch** (Aussagen-Positionierung lexikografisch über die Beleg-Anker, AD-17h) + **Konsolidierungs-Kriterium** (Befund-Äquivalenz über dieselbe erkannte Wissenseinheit) explizit; Stil-/Genus-Korrekturen (`sole`→`einzige`, `der Update`→`das Update`, `sources`-Pluspunkt→`sources`-Zuwachs). Keine Änderung an Normreferenzen, §7, Abschlussklausel. - **Revision 3.0 (2026-08-19, Story 3.5):** Neue Sektion **§5.11 „Leasing & Dirty-Tree-Schutz für konkurrierende Producer (Story 3.5)"** eingefügt (nach §5.10, vor §6) — die **verbindliche Verankerung der Koordinations-Dimension für konkurrierende Producer** (AD-17a..f, A0-12..A0-16, FR-2/FR-12; §7-Vorbehalt `:357` aufgelöst): (1) **Lease-Akquise (AD-17a, A0-12)** — Arbeits-Branch-Form **`lease//`** von der Merge-Base aus, **Lockfile** (`lease//.lock`, semantisch identisch in jedem Adapter, A0-12; deterministisches Format: `area`, `id`, `producer`, `baseline_commit` voller SHA, `holder_id`), Lease-Hold bei existierendem Lockfile (kein Überschreiben, keine Mutation), **Merge-Base-Disziplin** (Lease gg. eindeutigen Commit-Object-Wert über `git merge-base`/``, AD-17h); (2) **Root-Scope-Lease (AD-17b, A0-13)** — umfasst `wiki/` inkl. `log.md`, `index.md` und aller Root-Dateien; kein Bereich jenseits `wiki/`; (3) **Dirty-Tree-Schutz (AD-17e/f, A0-16)** — Pre-Mutation-Prüfung (`git status --porcelain -- `), fremde uncommittete Änderungen **geschützt statt gelöscht** (Stash/Scratch-Zone außerhalb `wiki/`, dokumentiert in `log.md`), Screen-Artefakte textuell benannt (NFR-4), **UNCOMMITTED_INPUT-Abbruch** „published/committed Input erforderlich" (AD-17a; I/O-Matrix-`UNCOMMITTED_INPUT` — dieselbe Pre-Run-Prüfung wie §5.9-P2-Element-(1)-`INPUT_UNCOMMITTED`, kein zweiter Abbruch-Pfad), Mutationen nur auf Directory-/Commit-Ebene; (4) **kein textueller Auto-Merge (AD-17c, A0-14)** — compiler-vermittelter Merge über die **AD-16-Klassifikation** (Default: Erhaltung) mit `log.md`-Eintrag; Lease-Konflikt → AD-16-Pfad; Unentscheidbarkeit → menschliche Eskalation (AD-17g); (5) **Commit-Boundary = Mutations-Boundary** unverändert (§0/§5.3, AD-17f) — Diff-Selbsttest (§5.9 Pkt. 5) auch für Leasing-Runs, Ghost-Diff-Rollback; (6) **`log.md`-Eintragspflicht** (Lease-Akquise, Dirty-Tree-Schutz-Dokumentation, Merge-Klassifikation, Eskalation, **Lease-Freigabe**; `` notiert, D-2; Datumsgruppe **neueste zuerst**); (7) **Determinismus-Vertrag (AD-17h/A0-19)** — Lease-Akquise, Lockfile-Inhalte, Merge-Klassifikation deterministisch aus dem committeten Git-State; **Lease-Staleness/Recovery bleibt Story 3.6** (AD-17d, A0-15) — diese Sektion mutiert deren Mechanik nicht; testbares Seam-Kriterium (3.5 = committed-state-deterministisch, 3.6 = Zeit-/Umgebungs-Zustands-Frage, die den committeten Zustand verlässt). **§7:** Leasing-/Dirty-Tree-Vorbehalt **aufgelöst** („in §5.11 verankert (Story 3.5)"); Scope-Einleitung um §5.11 geöffnet; verbleibendes 3.x-Thema: Lease-Staleness/Recovery → Story 3.6. **§8:** Normreferenzen um AD-17b/AD-17c/AD-17d/AD-17e-f/AD-17g (Spine) und A0-12/A0-13/A0-14/A0-15/A0-16 (Epics) ergänzt; AD-17d/A0-15 in der §5.11-Enum als Norm-Rückverweis (ohne §5.11-Auflösungs-Bezug) gekennzeichnet. **Abschlussklausel:** Keine Änderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3); **keine neue §7-Invaliditätsklasse**; **kein Standalone** (D-3); keine Vertragsänderung; **kein neuer Frontmatter-Key für Lease-Metadaten** (Lease lebt in Git/Datei-Ebene, Vertrag §3.1–§3.7 unverändert); **keine fünfte Update-Form** (Abgrenzungs-Reihenfolge §5.9 unverändert, Leasing = Querschnitt); kein Staleness-Scope (→ Story 3.6); Commit-Boundary-Regel unverändert. **Lease-Freigabe** (Release) ist in §5.11 Pkt. 1/6 verankert (deterministisch, auf das committete Ergebnis bezogen); Staleness-/Recovery-Aspekte der Freigabe (verwaiste Leases) bleiben Story 3.6. **`sprint-status.yaml`:** Key `3-5-leasing-dirty-tree-schutz-für-konkurrierende-producer-umsetz` → **`in-progress`**. Sandbox-Nachweis (L1–L6 + Negativ-Kontrollen, Exit 0) und per-Datei-Validator-Verdikt siehe `wiki/log.md`-Eintrag (Story 3.5, Revision 3.0). - **Revision 3.1 (2026-08-19, Story 3.6):** Neue Sektion **§5.12 „Lease-Staleness & Recovery-Basis (Story 3.6)"** eingefügt (nach §5.11, vor §6) — die **verbindliche Verankerung der Staleness-/Recovery-Dimension** (AD-17d, A0-15; §5.11-Seam-Kriterium S-1 und Pkt.-7-Text sowie §5.11 Pkt. 1 „verbleibt bis Story 3.6" bleiben textuell unverändert): (1) **Lease-Registrierung & generationenbasiertes TTL** — Registrierung im **Clone-Root-State**, monotoner Run-Generator (`generation`-Zähler je Clone-Root, deterministisch aus dem committeten Git-State ableitbar: `lease/`-Baumableitung oder Mono-Commit-`lease-granite-root`-Marker), **TTL-Ablauf-Kriterium generationen-basiert** (ältere/niedrigere Erzeugungs-Generation = stale, blockiert keinen nachfolgenden Run), **kein Wanduhr-Timestamp** im Lockfile-/Registrierungs-Format (A0-20; streng durchsetzendes Zeit-TTL = Ask-First); (2) **holder_id-Ableitung** (deterministischer Default `holder_id := -`, Defer aufgegriffen); (3) **Verwaist-Klassifikation** (Übernehmen gg. erneute Merge-Base-Prüfung oder Stale-Markieren via Registry-Marker, je `log.md`-Eintrag; verwaiste Leases **nie still gelöscht**, AD-17e; Konflikt → AD-16-Pfad/Eskalation AD-17g); (4) **baseline_commit-Merge-Base-Diskrepanz-Regel** (git-merge-base gewinnt, notierter SHA = Sekundär-Fingerprint, Fallback ohne Boundary; Defer aufgegriffen); (5) **`raw/`-Recovery-Basis & native `git stash`-Variante** (`raw/` immutable AD-3 als Zugriffs-/Consistency-Basis, Real-Baum-Beweis auf Sandbox-Evidenzwege beschränkt, EC-1-Grenze; `git stash push -- ` als zweitezulässige Schutzvariante, Defer aufgegriffen); (6) **Registrierungs-Invariante & kumulativer Registry-Aufbau über Runs** (Gen > erzeugend oder gleiche Gen, hält den sichtbar höchsten Reg-Generator; kein eigener `# Log`-Stand — `wiki/log.md` alleiniger Aufzeichnungs-Ort, Vertrag §5; Defer aufgegriffen); (7) **`log.md`-Eintragspflicht & Determinismus-Vertrag** (Registrierung/TTL, Lease-Übernahme, Stale-Markierung, Recovery-Basis-Nutzung als Datumsgruppen-Einträge; Registrierung/TTL/Verwaist-Klassifikation/log.md-Texte deterministisch aus dem committeten Git-State). **§7:** Staleness/Recovery-Vorbehalt **aufgelöst** („in §5.12 verankert (Story 3.6)"). **§8:** Normreferenzen AD-17d/A0-15 von reiner Story-Zuordnung auf **§5.12-Anker** angehoben (`AD-17d (Lease-Staleness, §5.12)`, `A0-15 (Lease-Staleness, §5.12)`). **Abschlussklausel:** Keine Änderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3); **keine neue §7-Invaliditätsklasse**; **kein Standalone** (D-3); keine Vertragsänderung; **kein neuer Frontmatter-Key für Lease-Metadaten** (Lease lebt in Git/Datei-Ebene, Vertrag §3.1–§3.7 unverändert); kein Prädikat-/Format-Key; Commit-Boundary-Regel unverändert. **`sprint-status.yaml`:** Key `3-6-lease-staleness-recovery-basis-absichern` → **`in-progress`**. Sandbox-Nachweis (STALE-1..STALE-6 + Erhaltungs-Invariante, Exit 0) und per-Datei-Validator-Verdikt siehe `wiki/log.md`-Eintrag (Story 3.6, Revision 3.1). +- **Revision 3.2 (2026-08-20, Story 3.7):** Neue Sektion **§5.13 „Reason/Mutate-Phasen-Trennung & Konsistenz-Endzustand (Story 3.7)"** eingefügt (nach §5.12, vor §6) — die **verbindliche Verankerung der logischen Phasen-Disziplin** (AD-6, A0-7; §7-Vorbehalt der Reason/Mutate-Trennung aufgelöst): (1) **Änderungsplanung** — der §5.9-Pkt.-6-P2-Block wird Wortlaut-unverändert als Änderungsplanungs-Phase der AD-6-Kette institutionalisiert (textuell festgehaltener konsistenter Plan: Input-Zustand, Ziel-Pfade, Quellen-Existenz, Betroffenheits-Liste, Struktur-Erhaltung; Plan-Defizit textuell benannt NFR-4 und verhindert die Mutation — I/O-Matrix `PLAN_BEABSICHTIGT`); (2) **Plan-Freeze** (Veränderungs-Sperre nach Phasenabschluss, Kopplung an die §5.9-Pkt.-5-Ghost-Diff-Probe; erlaubte Pfad-Menge = Kandidatenliste ∪ Neu-Anlage ∪ `log.md` ∪ `index.md` — `PLAN_FREEZE`); (3) **Zustands-Restaurations-Invariante** (Post-Rollback-Diff gg. Baseline leer / Bundle == valide committet; §5.3-Pkt.-3-/§6-Pkt.-3-Rollback und Ghost-Diff-Rollback Wortlaut-unverändert, Endzustands-Konsistenz als git-prüfbare Eigenschaft — `MUTATION_ABBRUCH`, A0-7-AC-2); (4) **kein Teilerfolg als fertige Mutation** (`MUTATION_TEILFOLGE`, AD-17f unverändert); (5) **Validierungsphase `VALIDATION_FAIL`** (§6-Pkt.-3-Rollback, keine weiteren Mutationen, Endzustand konsistent); (6) **Validierungsphase `VALIDATION_SUCCESS`** (Mutationen als Ganzes committet erst nach Diff-Selbsttest ohne Ghost-Diff, §6-Pkt.-4-Nachweis, kein Wanduhr-Trigger A0-20 — A0-7-AC-3); (7) **keine eigene Workflow-Engine** (`KEINE_EIGENE_ENGINE`: logische Trennung in einer Session, kein Prozess/Server/MCP, D-3/AD-11 — A0-7-AC-4). Die **AD-6-Phasen-Zuordnungstabelle (§0 ↔ vier AD-6-Phasen)** ist eine Klassifikation ohne neue Norm: §0 bleibt die deterministische Takt-Folge (Wortlaut unverändert, keine Um-Nummerierung, keine neue Phase); §5.9-Pkt.-6-P2-Block, §5.3-Pkt.-3/§6-Pkt.-3-Rollback und §5.9-Pkt.-5-Diff-Probe bleiben **textuell unverändert** (Rückverweise, keine Doppel-Instruktion); §5.12-Seam-Satz unverändert (Lease-Staleness/Recovery bleibt Story 3.6). **§7:** Reason/Mutate-Vorbehalt **aufgelöst** („in §5.13 verankert (Story 3.7)"-Bullet, AD-6/A0-7, AC-1/2/3/4; bestehende Story-Bullets unverändert). **§8:** Normreferenz AD-6 von reiner Story-Zuordnung auf **§5.13-Anker** angehoben (`AD-6 (Reason/Mutate-Trennung, §5.13)`); A0-7-Reihenfolge-Referenzen in der Epic-Zeile um §5.13-Bezug nicht neu aufgelistet (A0-7 bleibt in der bestehenden Epic-Enum, die §5.13-Ankerung erfolgt über die Spine-AD-6-Zeile und den neuen §7-Bullet). **Abschlussklausel:** Keine Änderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3); **keine neue §7-Invaliditätsklasse**; **kein Standalone** (D-3); keine Vertragsänderung; **kein neuer Prädikat-/Format-/Frontmatter-Key**; keine neue Workflow-Engine (AD-6); §0-Phasen-Listentext unverändert; Commit-Boundary-Regel unverändert. **`sprint-status.yaml`:** Key `3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell` → **`in-progress`**. Sandbox-Nachweis (CONSIST-1..CONSIST-7 + Erhaltungs-/Restaurations-Invariante, Exit 0) und per-Datei-Validator-Verdikt siehe `wiki/log.md`-Eintrag (Story 3.7, Revision 3.2). diff --git a/wiki/log.md b/wiki/log.md index 24bd8c5..7c9b10d 100644 --- a/wiki/log.md +++ b/wiki/log.md @@ -1,5 +1,9 @@ # Log +## 2026-08-20 +- **Story 3.7 → `done` (Step-04-Review-Abschluss, 2026-08-20):** Der Review-Abschluss-Flip `in-progress → done` (Sprint-Sync-Konvention, Story-3.1/3.2/3.3/3.4/3.5/3.6-Präzedenz) ist hier als eigener dokumentierter Schritt nachgeführt; `sprint-status.yaml`-Key `3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell` → **`review`** (Review-Schritt; das `done`-Flip ist Workflow-Konvention des Review-Abschlusses — Step-05 setzt Spec-Frontmatter `status: 'done'`), `last_updated` → 08-20-2026 00:30; Spec-Frontmatter `status: 'in-review' → 'done'`, `review_loop_iteration: 0`; Spec-`## Suggested Review Order` (Review-Trail: §5.13-Reason/Mutate-Sektion → §7/§8-Nachweis → Sandbox-Nachweis → Story-Protokoll/Defers) mit klickbaren `path:line`-Ankern (343/356/358/362/420/461 in `schema/compiler.md`). **Review-Ergebnis (Review-Loop 1, 3 Subagenten — blind-hunter / edge-case-hunter / verification-gap, kein Loopback):** keine intent_gap/bad_spec; Stapel Autofix-Patches — **Spec/SRO/Code-Map-Anker** auf IST-Zeilen korrigiert (§5.13 Einstieg Z. 343, Änderungsplanung Z. 356, Zustands-Restaurations-Invariante Z. 358, keine Engine Z. 362, §7-Bullet Z. 420, §8-Revision-3.2 Z. 461; §6-Start Z. 364, §8-AD-6 Z. 430; SRO-Sprint-Status-Label „in-progress (Implementierung)", keine `done`-Transition im Diff), **„fünf AD-6-Phasen" → „vier"** (Design Notes + §5.13-Intro-Post-Tabelle + Rev-3.2 + Boundaries + Review-Hinweis — konsistent zur AD-6-Rule und der 4-Zeilen-Zuordnungstabelle; Reconcile in die Analyse-Zelle gefasst; `fünf` in compiler.md = 0), **CONSIST-6-Sequenz** (`assert_frontmatter` + `log_commit` VOR `git commit` — der Commit enthält alpha + log.md mit Plan- und SUCCESS-Bullets; Commit enthält den §6-Pkt.-4-Nachweis, Commit-Boundary AD-17f), **CONSIST-7-`log_sha`-Vakuum** (log_sha nach Rollback ist Baseline-Konstante → nur Kommentar; Determinismus-Zeuge = `plan_sha`/`plan_state` aus dem committeten Plan-Capture-Baum, non-vakuum), **CONSIST-1-EC-1-Negativkontrolle** (P2-Element (3), fehlende `raw/alpha-v2.md`-Existenz → `p2_plan` muss `return 1`, textuell benannt, keine Mutation), **pgrep-Robustheits-Guard** (KEINE_ENGINE-Negativkontrolle: `command -v pgrep` → sonst `ps`-Fallback — pgrep auf Git-Bash-Host nicht vorhanden; vorher stille vacuöse Negativkontrolle, jetzt reeller `ps aux`-Scan), **`assert_restored`-Neu-Anlage-Guard** (`git cat-file -e "$BASE:wiki/$p"` — nicht-Baseline-Pfad darf nach Rollback nicht existieren), **Setup-Existenz-Assert** (CONSIST-4: `git cat-file -e "$BASE:raw/..."` ersetzt toten `|| sha256sum`-Fallback ohne pipefail), **Tippfehler `inv_viol` „§5.9 Pkt. 8" → „Pkt. 5"**, **plan-run.capture-Disclaimer** (nur deterministischer Sandbox-Zeuge, kein §5.13-Artefakt; „kein Artefakt-File" bleibt Ask-First-Norm), **Delokalisierungs-Doku** (deferred-work.md append-only: Terminologie-Drift `INPUT_UNCOMMITTED`/`UNCOMMITTED_INPUT` pre-existing §5.9/§5.11, §5.11-Wortlaut geschützt — XY nutzt `INPUT_UNCOMMITTED` wie §5.9-P2-Element (1); Misch-Run-Coverage Neu-Anlage+Update → Story 3.8), **Rejects** dokumentiert (u.a. E1 full-repo-P2-Check — Instruktionstext „Working-Copy von raw/ und wiki/" korrekt; Sandbox läuft nur auf sauberen Bäumen). **Sandbox re-executiert:** CONSIST-1..CONSIST-7, **Exit 0, 14 harte PASS-Assertionen**, einzige HARD-FAIL-Zeile = intendierte CONSIST-2-Negativkontrolle (Freeze-Verletzung auf `gamma`); CONSIST-7 non-vakuum (plan_sha byte-identisch über beide Runs); keine ungewollten `cat:`/`sha256sum:`-Zeilen; Zeilenanker real. **Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt:** `git status --porcelain -- wiki/` zeigt ausschließlich `wiki/log.md` (dieser Eintrag) — keine Concept-Inhalts-Mutation (Instruktions-Story D-3); `schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`/`raw/` unverändert (AD-3); Validator-Verdikt auf Ist-Bundle (human-mechanisch, `schema/validator.md` Rev 9, D-3): alle `wiki/`-Dateien SUCCESS. +- **Story 3.7 → `in-progress` (Reason/Mutate-Trennung & Konsistenz-Endzustand, Verankerung §5.13, 2026-08-20):** `schema/compiler.md` Revision 3.2 — neue Sektion **§5.13 „Reason/Mutate-Phasen-Trennung & Konsistenz-Endzustand (Story 3.7)“** (nach §5.12, vor §6): verbindliche Verankerung von **AD-6/A0-7** (Reason/Mutate-Trennung; A0-7-AC-2: konsistenter Endzustand bei Abbruch). Die **§0-Ablaufstruktur (0)–(5) bleibt unverändert** (deterministische Takt-Folge, keine Um-Nummerierung); §5.13 ordnet nur logisch zu (AD-6-Phase ↔ §0-Zuordnungstabelle). Inhalte: P2-Block (§5.9 Pkt. 6) institutionalisiert als **Änderungsplanung** (Wortlaut-unverändert referenziert, Rückverweis); **Plan-Freeze** (Veränderungs-Sperre: erlaubte Pfad-Menge = Kandidatenliste ∪ Neu-Anlage ∪ log.md ∪ index.md, Verletzung = Ghost-Diff §5.9 Pkt. 5); **Zustands-Restaurations-Invariante** (Post-Rollback-Diff gg. Baseline leer, Bundle == Baseline ∨ valid committet, deterministisch, ohne Wanduhr A0-20); kein Teilerfolg (Commit-Boundary = Mutations-Boundary, AD-17f); VALIDATION_FAIL (Rollback, keine weiteren Mutationen) vs. VALIDATION_SUCCESS (Mutationen als Ganzes committen, §6-Pkt.-4-Nachweis); **KEINE_EIGENE_ENGINE** (D-3/AD-11: logische Trennung in einer Session, kein Prozess/Server/MCP). §7-Bullet ergänzt (Nachweis-Block), §8-AD-6-Anker, Revisionslog **Revision 3.2** mit Abschlussklausel (AD-3 — `schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`/`raw/` unverändert; keine neue §7-Klasse; kein Standalone; keine Vertragsänderung; kein neuer Prädikat-/Format-/Frontmatter-Key; keine Workflow-Engine; §0 unverändert; Commit-Boundary-Regel unverändert). `sprint-status.yaml`-Key `3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell` → **`in-progress`**, `last_updated` → 08-20-2026 00:30 (Story 3.7). **Sandbox-Nachweis** (`_bmad-output/implementation-artifacts/sandbox-3-7/run-sandbox.sh`, `/tmp`-Baum, Linux-Semantik, nie der reale `wiki/`-/`raw/`-Baum): **CONSIST-1..CONSIST-7, Exit 0, 14 harte PASS-Assertionen** — CONSIST-1 konsistente Änderungsplanung (P2-Block) aus committetem Input + **Plan-Defizit-Abbruch VOR der Mutationsphase** (uncommitteter Input AD-17a); CONSIST-2 **Plan-Freeze** (Verletzung auf Nicht-Plan-Pfad `gamma` erkannt, Ghost-Diff-Rollback); CONSIST-3 **Zustands-Restaurations-Invariante** (Post-Rollback-Diff leer, Bundle == Baseline, SHA-256 byte-identisch, `raw/` unverändert AD-3); CONSIST-4 kein Teilerfolg als fertige Mutation (Commit-Boundary = Mutations-Boundary AD-17f); CONSIST-5 **VALIDATION_FAIL** (§6-Pkt.-3-Rollback, keine weiteren Mutationen); CONSIST-6 **VALIDATION_SUCCESS** (Mutationen als Ganzes committet, Diff-Selbsttest ohne Ghost-Diff, §6-Pkt.-4-Nachweis, kein Wanduhr-Trigger A0-20); CONSIST-7 **Determinismus-Zwei-Run nicht-vakuum** (identische Plan-/Rollback-/State-Outputs, AD-17h/A0-19; der Plan wird nach Rollback aus dem committeten Baum `git show`-gelesen — der einzige deterministische Zeuge, da `rollback` auf Baseline resettet) + **KEINE_ENGINE-Negativkontrolle** (kein Prozess/Server/MCP — D-3/AD-11, AC-4). Die einzige HARD-FAIL-Zeile im Sandbox-Output ist die intendierte CONSIST-2-Negativkontrolle (Freeze-Verletzung auf `gamma` — erwarteter Non-Zero-Exit, vom Szenario hart assertiert). **Keine Story-3.7-Defers** (per Spec-README: keine Home-3.7-Defers). **Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt:** `git status --porcelain -- wiki/` zeigt ausschließlich `wiki/log.md` (dieser Eintrag) — keine Concept-Inhalts-Mutation (Instruktions-Story D-3); `schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`/`raw/` unverändert (AD-3); Validator-Verdikt auf Ist-Bundle (human-mechanisch, `schema/validator.md` Rev 9, D-3): alle `wiki/`-Dateien SUCCESS. + ## 2026-08-19 - **Story 3.6 → `done` (Step-04-Review-Abschluss, 2026-08-19):** Der Review-Abschluss-Flip `in-progress → done` (Sprint-Sync-Konvention, Story-3.1/3.2/3.3/3.4/3.5-Präzedenz) ist hier als eigener dokumentierter Schritt nachgeführt; `sprint-status.yaml`-Key `3-6-…` → **`done`**, `last_updated` → 08-19-2026 22:10; Spec-Frontmatter `status: 'in-review' → 'done'`, `review_loop_iteration: 0`; Spec-`## Suggested Review Order` (Review-Trail: §5.12-Leasing-Staleness-Sektion → §7/§8-Nachweis → Sandbox-Nachweis → Story-Protokoll/Defers) verankert. **Review-Ergebnis (Review-Loop 1, 3 Subagenten — blind-hunter / edge-case-hunter / verification-gap, kein Loopback):** keine intent_gap/bad_spec; Stapel Autofix-Patches (Terminologie-Inversion „jünger→älter" in §5.12 Pkt. 1/3/6 + §8-Revisionslog + log.md + Spec, Gen kleiner = älter; Generations-Quellen-Präzedenz deterministisch gepinnt — committeter `lease-granite-root`-Marker gewinnt, sonst `lease/`-Baumableitung, sonst Startwert `gen = 0`; STALE-1-kern generationenbasiertes TTL gegen **dieselbe** `id` durchgesetzt, STALE-3-Re-Akquise, STALE-5-Same-id-A/B, holder_id-genuine Ableitung, baseline_commit-Merge-Base-Diskrepanz real, STALE-4-**lesender-**`raw/`-Bind (Recovery-Basis Zugriffs-/Consistency-Basis), Marker-Idempotenz-Regex, STALE-6-Full-State-Invariante, log_bullet-Datumsgruppen); **1 neuer Defer** → `deferred-work.md` append-only (Schicksal des `lease//`-Branch nach Übernahme/Stale-Markierung — Home: spätere Instruktions-/Sandbox-Runde oder Story 3.8). **Sandbox re-executiert:** STALE-1..STALE-6 + Erhaltungs-Invariante, **Exit 0, 12 harte PASS-Assertionen**; AD-3 geprüft (`schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`/`raw/` unverändert); Validator-Verdikt auf Ist-Bundle: alle `wiki/`-Dateien SUCCESS (keine Inhalts-Mutation). **Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt:** `git status --porcelain -- wiki/` zeigt ausschließlich `wiki/log.md` (dieser Eintrag) — keine Concept-Inhalts-Mutation (Instruktions-Story). - **Story 3.6 → `in-progress` (Lease-Staleness & Recovery-Basis, Verankerung §5.12, 2026-08-19):** `schema/compiler.md` Revision 3.1 — neue Sektion **§5.12 „Lease-Staleness & Recovery-Basis (Story 3.6)“** (nach §5.11, vor §6), die **verbindliche Verankerung der Staleness-/Recovery-Dimension** (AD-17d, A0-15; §5.11-Seam-Kriterium S-1 und Pkt.-7-Text sowie §5.11 Pkt. 1 „verbleibt bis Story 3.6“ textuell unverändert — Haltbarkeits-Fuge): (1) **Lease-Registrierung & generationenbasiertes TTL** — Registrierung im **Clone-Root-State** (nicht `wiki/`/`raw/`/Concept-Frontmatter, Vertrag §3.1–§3.7 unverändert), monotoner Run-Generator (**`generation`-Zähler je Clone-Root**, deterministisch aus dem committeten Git-State ableitbar: `lease/`-Baumableitung oder Mono-Commit-`lease-granite-root`-Marker), **TTL-Ablauf-Kriterium generationen-basiert** (ältere Erzeugungs-Generation = stale, blockiert keinen nachfolgenden Run, I/O-Matrix `STALE_ABLAUF`), **kein Wanduhr-Timestamp im Lockfile-/Registrierungs-Format** (A0-20; streng durchsetzendes Zeit-TTL = Ask-First); (2) **holder_id-Ableitung** (deterministischer Default `holder_id := -`, reproduzierbar aus dem committeten Git-State; **Story-3.5-Defer aufgegriffen**); (3) **Verwaist-Klassifikation, Übernahme & Stale-Markierung** (AD-17e/AD-17g) — `VERWAIST_UEBERNEHMEN` gg. erneute Merge-Base-Prüfung (Pkt.-4-Regel) mit log.md-Protokoll, `VERWAIST_STALE_MARKIEREN` via Registry-Marker der aktuellen Generation (Blockade aufgehoben); verwaiste Leases **nie still gelöscht** (AD-17e); (4) **baseline_commit-Merge-Base-Diskrepanz-Regel** — `git merge-base` gewinnt, notierter `` bleibt Sekundär-Fingerprint, Fallback ohne Boundary (alle `raw/`-Dateien Zuwachs, Merge-Base = ältester Fundamentpunkt, §5.9 Pkt. 6 R-1/AD-14); gilt auch bei Lease-Übernahme (**Defer aufgegriffen**); (5) **`raw/`-Recovery-Basis & native `git stash`-Variante** — `raw/` immutable AD-3 als Zugriffs-/Consistency-Basis, Real-Baum-Beweis auf Sandbox-Evidenzwege beschränkt (EC-1-Grenze), `git stash push -- ` als zweite textuell zulässige Schutzvariante (byte-identisch, nie gelöscht, Restore dokumentiert; **Defer aufgegriffen**); (6) **Registrierungs-Invariante & kumulativer Registry-Aufbau über Runs** (Vertrag §5) — `Gen > erzeugend oder gleiche Gen`, hält den sichtbar höchsten Reg-Generator, kein eigener `# Log`-Stand in der Registry (`wiki/log.md` alleiniger Aufzeichnungs-Ort; **Defer aufgegriffen**); (7) **`log.md`-Eintragspflicht & Determinismus-Vertrag** (AD-17h/A0-19) — Registrierung/TTL, Lease-Übernahme, Stale-Markierung, Recovery-Basis-Nutzung als datumsgruppierte Einträge (neueste zuerst, `` D-2), **deterministisch aus dem committeten Git-State**, kein Wanduhr-Timestamp steuert einen Vorgang. **§7-Vorbehalt `Lease-Staleness/Recovery` (`:376`) aufgelöst:** „**in §5.12 dieser Instruktion verankert (Story 3.6)**“ (§5.11-Pkt.-7-Seam-Satz und §7-Leasing-Enum-Bullet-Text unverändert). **§8-Normreferenzen** AD-17d/A0-15 von reiner Story-Zuordnung auf **§5.12-Anker** angehoben (`AD-17d (Lease-Staleness, §5.12)`, `A0-15 (Lease-Staleness, §5.12)`). **§8-Revisionslog Revision 3.1** mit Abschlussklausel (keine Änderung an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` AD-3; **keine neue §7-Invaliditätsklasse**; **kein Standalone** D-3; keine Vertragsänderung; **kein neuer Frontmatter-Key für Lease-Metadaten**; kein Prädikat-/Format-Key; Commit-Boundary-Regel unverändert). **Sandbox `sandbox-3-6/run-sandbox.sh` re-executierbar (Muster sandbox-3-5, `/tmp`-Baum, `core.autocrlf false`-Pin für deterministische `git stash`-Roundtrips; nie der reale `wiki/`-`/raw/`-Baum):** **STALE-1 STALE_ABLAUF** (abgebrochener Run hinterlässt Lease + Registrierung ohne Freigabe; nachfolgender Run klassifiziert sie generationenbasiert als stale — **kein Blockade-fail**, akquire run-b erfolgreich; Lockfile + Registry-Zeile bleiben, AD-17e; kein Wanduhr-Timestamp A0-20; log.md-TTL-Eintrag Pkt. 6a/7a), **STALE-2 VERWAIST_UEBERNEHMEN** (Übernahme gg. erneute Merge-Base-Prüfung `git merge-base == $BASE`, log.md-Übernahme-Eintrag Pkt. 6b/7b, holder_id-Ableitung Pkt. 2, nichts still gelöscht AD-17e), **STALE-3 VERWAIST_STALE_MARKIEREN** (Registry-Marker `stale: run-a (Gen 2)`, `lease_active=false` → Blockade aufgehoben, log.md-Eintrag Pkt. 6c/7c, Gen-Invariante gehalten, Lockfile+Zeile bleiben AD-17e), **STALE-4 RECOVERY_RAW_BASIS** (`raw/`-SHA-256 vor/nach identisch — immutable AD-3, EC-1-Grenze; native `git stash push`/`pop` um `wiki/alpha.md` byte-identischer Restore via SHA-256, nie gelöscht; log.md-Recovery-Eintrag Pkt. 6d/7d), **STALE-5 REGISTRIERUNGS-INVARIANTE** (drei Runs in EINER `registry/wiki` — Gen 3 == höchster, Regression auf Gen 1 zurückgewiesen (Invariante Pkt. 6); verwaiste Kanten run-a/run-b/run-c nie gelöscht AD-17e; HOLD gegen aktive Lease deterministisch (akquire run-c verweigert), kein Abbruch-Text; kein Wanduhr), **STALE-6 DETERMINISMUS** (AD-17h/A0-19: zwei identische Runs → Registry- und `log.md`-SHA-256 **byte-identisch**, identische Stale-Markierungs-Klassifikation); **Exit 0, 6/6 harte PASS-Szenarien** (re-executiert, 08-19-2026). **4 Defers aufgegriffen (Story 3.5, Home 3.6):** `deferred-work.md` append-only — vier `### Aufgegriffen`-Blöcke (holder_id-Quelle → §5.12 Pkt. 2; baseline_commit-Diskrepanz → §5.12 Pkt. 4; Sandbox-log-Akkumulator/cumulative Registry → §5.12 Pkt. 6; native `git stash`-Variante → §5.12 Pkt. 5), je Status `aufgegriffen (Home erledigt in §5.12 …)` + Sandbox-Nachweis; keine neuen Story-3.6-Defers. **Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt:** `git status --porcelain -- wiki/` zeigt ausschließlich `wiki/log.md` (dieser Eintrag) — keine Concept-Inhalts-Mutation (Instruktions-Story; `sprint-status.yaml`/`deferred-work.md`/`sandbox-3-6/` liegen außerhalb `wiki/` und sind nicht Teil der Diff-Probe). **Validator-Verdikt (per-Datei, human-mechanisch ausgeführte Text-Instruktion `schema/validator.md` Rev 9, D-3 — kein CLI; unverändert zur Story 3.5, Story 3.6 mutiert keine Concept-Inhalte):** alle **7** `wiki/`-Dateien **SUCCESS** — `wiki/index.md` (Punkt 11, Bundleroot), `wiki/knowledge-kompilation-inkrementell.md`, `wiki/llm-wiki-prinzip.md`, `wiki/wissensarchitektur-trennung-states.md` (Punkte 1/2/6/7/8/9/11/12/13/14, EC-1), `wiki/log.md` (frontmatterlos, Punkt 10), `wiki/wissensarchitektur/index.md` (frontmatterlos, Punkt 10/11), `wiki/wissensarchitektur/source-material.md` (Punkte 1/2/6/7/8/9/11/12/13/14, EC-1; Punkt 11 inkl. Area-Lesart Rev 9). `schema/validator.md`/`schema/wiki-compiler.md`/`raw/` unverändert (AD-3, via `git status` geprüft); keine neue §7-Klasse; kein Standalone (D-3). `sprint-status.yaml`-Key `3-6-…` → **`in-progress`**, `last_updated` → 08-19-2026 21:30.