feat: Story 3.7 Review-Loop-2-Patches (bmad-code-review Re-Run, 4 Layer; kein Loopback) — Nutzer D1/D2/D3 = 1/1/1; 3 decision-needed / 7 patch / 3 defer / 9 dismissed (False-Positives); Patches: D1 deferred-work-Append (zwei Delokalisierungs-Blöcke: Terminologie-Drift INPUT_UNCOMMITTED/UNCOMMITTED_INPUT pre-existing, Misch-Run-Coverage → Home Story 3.8) → log.md-Protokollwiderspruch aufgelöst; D2 sprint-status review behalten + 4 Doku-Stellen (Spec-Code-Map, SRO-Anker-Text, in-progress-Bullet, §8-Rev-3.2-Klausel); D3 p2_plan-Element-(1)-Scope git status --porcelain -- raw wiki (exakt wie §5.9 Pkt. 6); Sandbox: CONSIST-1-EC-1-Isolation (committete Löschung), CONSIST-2 Misch-Run (Neu-Anlage +delta, Duplikat-Kontrolle, Neu-Anlage-Absenz nach Voll-Rollback via assert_restored-Guard), CONSIST-5 raw-SHA gg. $BASE, CONSIST-6 gültiger Commit-Zustand (sources-Nachführung id s3 + at-Bump), rollback()-Doku (Voll-Rollback = §6-Pkt.-3-Teilzustand, AD-17e-Abgrenzung), 3 Tippfehler; Instruktion: §5.13 Pkt. 7 um generated.at-Wanduhr-Gap-Ausnahme (§5.10 Pkt. 8, A0-20, Home 3.8); Sandbox re-executiert Exit 0 (14 harte PASS, CONSIST-7 non-vakuum plan_sha byte-identisch); Defers → deferred-work.md (Label-Präzisierung, A0-20-Post-Zustand → 3.8, pre-existing-Zeitpunktswort-Fuge); Spec: Review Findings + Change Log + loop_iteration 1; log.md Review-Loop-2-Bullet; sprint-status done; AD-3 unverändert
This commit is contained in:
@@ -470,3 +470,19 @@ Noch nicht adressierte, aber real erkannte Arbeit — gesammelt aus Reviews. Ein
|
||||
- Umsetzung: `schema/compiler.md` §5.12 Pkt. 5 „`raw/`-Recovery-Basis & native `git stash`-Variante (AD-3, AD-17d/A0-15)": `git stash push -- <Pfade>` als zweite textuell zulässige Schutzvariante neben der Scratch-Zonen-Kopie (beide deterministisch im Ergebnis, byte-identisch geschützt, nie gelöscht, Restore dokumentiert).
|
||||
- Sandbox-Nachweis: STALE-4 (`git stash push`/`pop` um `wiki/alpha.md`, byte-identischer Restore via SHA-256; `raw/`-SHA-256 unverändert, AD-3) — Exit 0.
|
||||
- status: aufgegriffen (Home erledigt in §5.12 Pkt. 5)
|
||||
|
||||
## Deferred from: code review of spec-3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell (Story 3.7, 2026-08-20)
|
||||
|
||||
- CONSIST-7-Label praezisie: das Zwei-Run-Label behauptet "identische Plan-/Rollback-/State-Outputs", verglichen werden aber nur die Plan-Outputs (plan_sha/plan_state); der Rollback-/State-Nachweis (s7c) laeuft einmalig, log_sha ist dokumentierte Baseline-Konstante. Die non-vakuum-Kern-Assertion (plan_sha byte-identisch ueber beide Runs) ist real; das Label ist breiter als die Assertion. Home: Sandbox-Haertungsrunde.
|
||||
- A0-20-Post-Zustand-Negativkontrolle in der Sandbox fehlt: §5.13 Pkt. 3/7 bindet den Determinismus-Vertrag an den Post-Zustand; der dokumentierte generated.at-Wanduhr-Gap (§5.10 Pkt. 8, offene A0-20-Konvention) macht den Post-Zustand ueber unabhaengige Runs nicht byte-identisch — die Sandbox testet den Gap weder negativ noch positiv. Home: Story 3.8 (A0-20-Home).
|
||||
- Pre-existing-Zeitpunktswort-Fuge: §5.9 Pkt. 6 "am Anfang der Mutationsphase" vs. gefrorene I/O-Matrix + §5.13 "Abbruch vor der Mutationsphase" — §5.9 ist in Story 3.7 Wortlaut-unververaendert (Rueckverweis-Vertrag); die Fuge ist ohne Ask-First nicht schliessbar. Home: spaetere Instruktionsrunde.
|
||||
|
||||
### Delokalisierung: Terminologie-Drift INPUT_UNCOMMITTED/UNCOMMITTED_INPUT (Story-3.7-Review, 2026-08-20)
|
||||
|
||||
- Bezug: `schema/compiler.md` §5.9 Pkt. 6 Element (1) nennt die I/O-Matrix `INPUT_UNCOMMITTED`, §5.11 Pkt. 3 nennt dieselbe Pre-Run-Prüfung `UNCOMMITTED_INPUT` — dieselbe Prüfung, zwei Labels (pre-existing seit Story 3.1/3.5; in Story 3.6/3.7 als dieselbe §5.9-P2-Prüfung deklariert, §5.11-Wortlaut geschützt). Die Story-3.7-Sandbox (`p2_plan`-Element (1)) nutzt `INPUT_UNCOMMITTED` wie §5.9-Pkt.-6-Element (1).
|
||||
- status: delokalisiert (kein Defekt — terminologische Präferenz; Home: spätere Instruktionsrunde, falls die Labels vereinheitlicht werden)
|
||||
|
||||
### Delokalisierung: Misch-Run-Coverage Neu-Anlage+Update in der Story-3.7-Sandbox (Story-3.7-Review, 2026-08-20)
|
||||
|
||||
- Bezug: §5.9 Pkt. 2/§5.7 Misch-Runs (Neu-Anlage + Update im selben Run) sind in der CONSIST-Sandbox ab Review-Loop-2 im CONSIST-2 abgedeckt (Neu-Anlage `delta` + Update `alpha`, Plan-Freeze-Menge + Voll-Rollback, Neu-Anlage-Absenz nach Rollback); übrige Phasen-/Synthese-Misch-Formen bleiben Home Story 3.8 (Determinismus-Vertrag AD-17h als Agent-Instruktions-Validator, inkl. A0-20-Post-Zustand-Test).
|
||||
- status: delokalisiert (Home: Story 3.8)
|
||||
|
||||
@@ -148,7 +148,7 @@ assert_restored() { # $1=komma-oder-leer-getrennte wiki-Pfade, die byte-identisc
|
||||
git diff --name-only "$BASE" -- wiki/ | sed 's/^/ /' >&2
|
||||
exit 1
|
||||
fi
|
||||
# 2) porcelan: keine ungetrackten/gestagten Eintraege im wiki/-Scope
|
||||
# 2) porcelain: 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
|
||||
@@ -234,7 +234,7 @@ log_bullet() { # $1 = Bullet-Text (eine Zeile, printf-% escaped); Datumsgruppe/R
|
||||
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
|
||||
log_abort() { # $1=benannte Abbruch-Ursache — NFR-4-textuelle 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)"
|
||||
@@ -247,10 +247,12 @@ log_commit() { # $1=plan-vs-ist-diff-befund
|
||||
# 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
|
||||
p2_plan() { # $1=komma-Liste Ziel-Pfade (OKF-ohne-.md; Neu-Anlage = +name) $2=komma-Liste raw-Quellen (Pfad)
|
||||
local targets="$1" srcs="$2" p s np err=0
|
||||
# (1) Input-Zustand (AD-17a): Working-Copy von raw/ und wiki/ gegen HEAD — uncommittet = Abbruch
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
# (Scope exakt wie Instruktion §5.9 Pkt. 6 Element (1): raw/ und wiki/; Review-Loop-2-D3:
|
||||
# unscoped ganzer-Tree-Prüfung wäre straffer als die Instruktion — die Demo folgt der Instruktion.)
|
||||
if [ -n "$(git status --porcelain -- raw wiki)" ]; 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
|
||||
@@ -260,9 +262,15 @@ p2_plan() { # $1=komma-Liste Ziel-Pfade (OKF-ohne-.md) $2=komma-Liste raw-Quell
|
||||
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)
|
||||
# (4) Betroffenheit (§3 Pkt. 2, textuell-deterministisch nach §3.2): bestehende Kandidaten
|
||||
# oder geplante Neu-Anlage-Zielpfade (+Prefix; §5.13 Pkt. 2 "∪ Neu-Anlage") — Duplikat-Kontrolle:
|
||||
# ein +Pfad, der bereits existiert, ist kein Neu-Anlage.
|
||||
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; }
|
||||
case "$p" in
|
||||
+*) np="${p#+}"
|
||||
[ -f "wiki/$np.md" ] && { echo "HARD-FAIL (Änderungsplanung, P2-Element (4)): Neu-Anlage-Pfad wiki/$np.md existiert bereits (Duplikat — kein Neu-Anlage, §5.10 Pkt. 8)" >&2; return 1; } ;;
|
||||
*) [ -f "wiki/$p.md" ] || { echo "HARD-FAIL (Änderungsplanung, P2-Element (4)): Betroffenheits-Kandidat wiki/$p.md fehlt (und kein Neu-Anlage-Zielpfad +name)" >&2; return 1; } ;;
|
||||
esac
|
||||
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; }
|
||||
@@ -296,6 +304,11 @@ freeze_check() { # $1=komma-Liste der im Run geplanten Ziel-Pfade (ok + neu.log
|
||||
}
|
||||
# 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.
|
||||
# (Review-Loop-2-D5: der Voll-Rollback rollt den TEILZUSTAND DES RUNS komplett zurück (§6 Pkt. 3:
|
||||
# "das Bundle nimmt seinen Zustand vor dem Run wieder ein") — in der Sandbox sind alle
|
||||
# ungetrackten wiki/-Dateien Lauf-eigener Teilzustand; es existieren keine fremden uncommitteten
|
||||
# Änderungen (AD-17e-Schutzobjekt). Ein realer Run schützt fremde Änderungen zuvor per
|
||||
# Stash/Scratch-Zone (§5.11 Pkt. 3), bevor ein Rollback greift.)
|
||||
rollback() {
|
||||
git checkout -q "$BASE" -- wiki/ 2>/dev/null || true
|
||||
untracked_rest=$(git status --porcelain -- wiki/ | grep '^??' | awk '{print $2}')
|
||||
@@ -341,7 +354,10 @@ else
|
||||
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
|
||||
# (Review-Loop-2-Patch: die Löschung wird COMMITTET — eine uncommittierte Löschung würde
|
||||
# Element (1) (uncommitteter Input) zuerst feuern und die EC-1-Kontrolle nicht isolieren;
|
||||
# im committeten Zustand ist Element (3) der einzige Trigger.)
|
||||
git rm -q raw/alpha-v2.md && git commit -qm "Quelle entfernt"
|
||||
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
|
||||
@@ -350,26 +366,42 @@ else
|
||||
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"
|
||||
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 isoliert [untracked Datei] + P2-Element (3) EC-1 isoliert [committete Löschung]); 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)"
|
||||
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); Misch-Run (Update + Neu-Anlage): der geplante Neu-Anlage-Pfad ist erlaubter Teil der Plan-Menge (Review-Loop-2-Patch)"
|
||||
isolate consist2
|
||||
cat > raw/alpha-v2.md <<'EOF'
|
||||
### S-3
|
||||
Evidenz v2: Alpha erweitert um eine synchrone Kopplung.
|
||||
### S-4
|
||||
Evidenz v2: Delta-Thema — bisher nicht im Bundle repraesentiert.
|
||||
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)"
|
||||
p2_plan "alpha,+delta" "alpha-v2.md" >/dev/null || exit 1
|
||||
log_plan "alpha betroffen + delta neu angelegt via raw/alpha-v2.md (Plan-Freeze aktiv, Misch-Run)"
|
||||
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 "--- Mutationsphase: geplante Neu-Anlage von delta — erlaubt (Neu-Anlage im Plan, §5.13 Pkt. 2) ---"
|
||||
cat > wiki/delta.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/alpha-v2.md
|
||||
id: s1
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-20T00:00:00Z
|
||||
---
|
||||
Delta-Thema (raw/alpha-v2.md#S-4).
|
||||
EOF
|
||||
[ -f wiki/delta.md ] || { echo "HARD-FAIL (CONSIST-2): geplante Neu-Anlage 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
|
||||
if freeze_check "alpha delta 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
|
||||
@@ -378,10 +410,12 @@ 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"
|
||||
freeze_check "alpha delta log index" || exit 1
|
||||
echo "--- Voll-Rollback (Abbruch des Runs): Teilzustand {alpha, delta, log} wird komplett zurückgerollt (Zustands-Restaurations-Invariante) ---"
|
||||
rollback
|
||||
assert_restored "alpha gamma index log delta"
|
||||
echo " BEFUND: Neu-Anlage-Pfad delta existiert nach Rollback NICHT (assert_restored-Neu-Anlage-Guard) — Misch-Run-Teilerfolg ist vollständig rückgerollt"
|
||||
echo "RESULT: PASS — CONSIST-2: Plan-Freeze = Veränderungs-Sperre (erlaubte Menge {alpha, delta (Neu-Anlage), log, index}); Verletzung (gamma) erkannt + zurueckgerollt (Ghost-Diff-Rollback §5.9 Pkt. 5); Neu-Anlage-Pfad im Plan ist erlaubter Teil der Menge; Misch-Run-Voll-Rollback: Neu-Anlage nach Rollback nicht existent (Zustands-Restaurations-Invariante); 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)"
|
||||
@@ -478,8 +512,10 @@ 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; }
|
||||
# (Review-Loop-2-Patch: gg. den Baseline-Commit vergleichen — der Selbstvergleich wäre
|
||||
# tautologisch und bewiese nichts; Muster CONSIST-4.)
|
||||
rawv1_b=$(git show "$BASE:raw/alpha-v1.md" | sha256sum | cut -d' ' -f1)
|
||||
[ "$rawv1_b" = "$(sha256sum raw/alpha-v1.md | cut -d' ' -f1)" ] || { 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) ----
|
||||
@@ -492,8 +528,21 @@ 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'
|
||||
echo "--- Mutationsphase: geplante Mutation von alpha (regelkonform) — §5.9-Pkt.-2-Update-Form: Body-Erweiterung + sources-Zuwachs + generated.at-Bump ---"
|
||||
cat > wiki/alpha.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/alpha-v1.md
|
||||
id: s1
|
||||
- resource: raw/alpha-v2.md
|
||||
id: s3
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-20T00:00:00Z
|
||||
---
|
||||
Das Alpha-Protokoll definiert eine deterministische Init-Sequenz (raw/alpha-v1.md#S-1).
|
||||
Alpha verwendet ausschließlich lokale Netze (raw/alpha-v1.md#S-2).
|
||||
Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3).
|
||||
EOF
|
||||
echo "--- Diff-Selbsttest VOR dem Commit (§5.9 Pkt. 5): {alpha, log} — kein Ghost-Diff ---"; probe
|
||||
@@ -502,8 +551,8 @@ 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)"
|
||||
assert_frontmatter wiki/alpha.md "raw/alpha-v1.md" "raw/alpha-v2.md"
|
||||
echo " (§5.13-demo: der committete Zustand ist gültig — alpha frontmatter-konform (kein unbefugter Key, generated.at volles Datetime), sources-Nachführung der Update-Evidenz vollzogen (§5.9 Pkt. 2); der Body zitiert raw/alpha-v2.md#S-3 nur mit existierendem sources-Eintrag (EC-1/Punkt-3-konform))"
|
||||
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)"
|
||||
@@ -568,7 +617,7 @@ 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; }
|
||||
[ "$(inv_set)" = "" ] || { echo "HARD-FAIL (CONSIST-7): kein sauberer 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
|
||||
|
||||
+25
-4
@@ -4,7 +4,7 @@ type: 'feature'
|
||||
created: '2026-08-20'
|
||||
status: 'done'
|
||||
baseline_commit: '861e65f628001ffe8da05d0fd6834b7bb2689202'
|
||||
review_loop_iteration: 0
|
||||
review_loop_iteration: 1
|
||||
context:
|
||||
- '_bmad-output/implementation-artifacts/epic-3-context.md'
|
||||
---
|
||||
@@ -50,7 +50,7 @@ context:
|
||||
- `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/sprint-status.yaml` — **mutiert**: `3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell` `backlog` → `review` (Implementierungs-Flip `in-progress` + Review-Start-Flip `review` im selben Commit; finaler `done`-Flip im Step-05-Status-Sync); `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).
|
||||
|
||||
@@ -71,10 +71,31 @@ context:
|
||||
|
||||
## Spec Change Log
|
||||
|
||||
_Noch leer — wird von step-04 während der Review-Loops befüllt (append-only Konvention)._
|
||||
- **2026-08-20 (Step-04-Review, Review-Loop 2, bmad-code-review 4 Layer; Nutzer D1/D2/D3 = 1/1/1):** keine Änderung am `<frozen-after-approval>`-Intent (keine intent_gap/bad_spec-Verdikt). Doku-Stellen nachgeführt: Code-Map `sprint-status`-Eintrag `backlog → in-progress` → **`backlog → review`** (Impl.-Flip + Review-Start-Flip im selben Commit, D2); SRO-Anker-Text entsprechend. `### Review Findings` (3 Decision / 7 Patch / 3 Defer) angehängt; alle Decision- und Patch-Items nach der Patch-Runde abgehakt. Sandbox-Patch-Nachweise und die 3 Defers siehe `wiki/log.md`-Review-Loop-2-Bullet (2026-08-20) und `deferred-work.md`-Sektion „Deferred from: code review of … (Story 3.7, 2026-08-20)". `review_loop_iteration: 1`.
|
||||
|
||||
</frozen-after-approval>
|
||||
|
||||
### Review Findings (bmad-code-review, 2026-08-20 — Review-Loop 2, 4 Layer: blind-hunter / edge-case-hunter / verification-gap / acceptance-auditor)
|
||||
|
||||
**[Decision]** (offen — Nutzer-Entscheidung erforderlich):
|
||||
- [x] [Review][Decision] (gelöst: 1) log.md-Protokoll-Widerspruch + fehlender deferred-work-Append — das done-Bullet (log.md:4) behauptet eine „Delokalisierungs-Doku (deferred-work.md append-only: Terminologie-Drift `INPUT_UNCOMMITTED`/`UNCOMMITTED_INPUT` … Misch-Run-Coverage Neu-Anlage+Update → Story 3.8)", in `deferred-work.md` existiert aber **kein** Story-3.7-Eintrag (grep-verifiziert); das in-progress-Bullet (log.md:5) sagt „Keine Story-3.7-Defers" — die beiden Aufzeichnungen widersprechen sich. Optionen: (1) deferred-work-Append nachtragen (done-Bullet wird wahr); (2) done-Bullet umformulieren (keine Delokalisierungs-Doku behaupten, „keine Defers" bleibt wahr). [wiki/log.md:4-5]
|
||||
- [x] [Review][Decision] (gelöst: 1) sprint-status `backlog → review` im Diff vs. dokumentiertes `backlog → in-progress` — `git diff 861e65f..HEAD` zeigt Key `3-7-…` = `review`; Code-Map, SRO-Anker-Text, log.md-in-progress-Bullet und §8-Revision-3.2-Klausel dokumentieren alle `backlog → in-progress`. Optionen: (1) `review` behalten (Review-Start-Flip, File-Header-Konvention) + Dokumentation korrigieren; (2) auf `in-progress` setzen (Diff-Getreue) — der Step-04/05-Status-Sync setzt den Endwert ohnehin neu. [sprint-status.yaml:60]
|
||||
- [x] [Review][Decision] (gelöst: 1) p2_plan-Element-(1)-Scope — Wiedererwägung der dev-intern abgelehnten E1: `p2_plan` prüft unscoped `git status --porcelain` (ganzer Tree), §5.9 Pkt. 6 Element (1) scope-t auf „Working-Copy von `raw/` und `wiki/` gegen HEAD". Das done-Bullet dokumentiert die Ablehnung („Sandbox läuft nur auf sauberen Bäumen") — in den IST-Szenarien ist der Scope-Unterschied wirkungslos; bei einer Sandbox-Erweiterung (untracked-State außerhalb raw/+wiki/) würde die Demo-Funktion abbrechen, wo die Instruktion es zuließe. Optionen: (1) Scope-Fix `git status --porcelain -- raw wiki` (E1 wiedereröffnen); (2) Ablehnung aufrechterhalten (dismiss); (3) Defer an Sandbox-Härtungsrunde. [run-sandbox.sh:253]
|
||||
|
||||
**[Patch]** (offen):
|
||||
- [x] [Review][Patch] (angewendet) CONSIST-1-EC-1-Negativkontrolle nicht isoliert: `rm -f raw/alpha-v2.md` verschmutzt `raw/` (untracked deletion) → Element (1) (uncommitteter Input) feuert zuerst, Element (3) (Quellen-Existenz) wird nie allein geübt — die BEFUND-Zeile benennt EC-1, der Trigger ist aber Element (1). Fix: Löschung committen (`git rm -q` + commit), damit Element (3) am sauberen Baum isoliert feuert [run-sandbox.sh:343-350]
|
||||
- [x] [Review][Patch] (angewendet) CONSIST-5-`raw/`-SHA-Assertion tautologisch: `raw_sha=$(sha256sum raw/alpha-v1.md …)` wird mit derselben Datei verglichen — immer wahr, die AD-3-Prüfung beweist nichts. Fix: gg. `git show "$BASE:raw/alpha-v1.md"` vergleichen (Muster CONSIST-4) [run-sandbox.sh:481-482]
|
||||
- [x] [Review][Patch] (angewendet) CONSIST-6-SUCCESS-Demo committiert einen Zustand, der die §5.9-Update-Disziplin verletzt: die Body-Zeile zitiert `(raw/alpha-v2.md#S-3)`, die `sources`-Nachführung fehlt (im Kommentar als „gehört §5.9/§5.10" eingeräumt) — als Referenz-Demo eines VALIDATION_SUCCESS-Runs misleitet. Fix: Demo-Mutation um den `sources`-Eintrag ergänzen, damit der committete Zustand gültig ist [run-sandbox.sh:496-506]
|
||||
- [x] [Review][Patch] (angewendet: Doku-Block — Voll-Rollback = §6-Pkt.-3-Teilzustand, Sandbox-Abweichung begründet) `rollback()` löscht **alle** untracked `wiki/`-Dateien (`git reset --hard` + `git clean -qfd wiki`), während der Ghost-Diff-Rollback (§5.9 Pkt. 5) nur die betroffenen Pfade wiederherstellt und AD-17e fremde uncommittete Änderungen schützt (Spec-Never: „uncommittete fremde wiki/-Änderungen löschen"). In den IST-Szenarien wirkungslos, aber die demonstrierte Rollback-Mechanik widerspricht der Instruktion, die sie demonstrieren soll. Fix: `git clean` auf Nicht-erlaubte Pfade begrenzen oder die bewusste Sandbox-Abweichung dokumentieren [run-sandbox.sh:299-313]
|
||||
- [x] [Review][Patch] (angewendet: CONSIST-2 Misch-Run + `+`-Neu-Anlage in `p2_plan` + Absenz-Assertion) Neu-Anlage-Zweig ungetestet: kein Szenario übt den Plan-Freeze-Eintrag „∪ Neu-Anlage-Zielpfade"; der `assert_restored`-Neu-Anlage-Guard (`git cat-file -e "$BASE:wiki/$p"`-Negativzweig) ist toter Code. Fix: CONSIST-2 um einen geplanten Neu-Anlage-Pfad (`p2_plan` unterstützt den Marker `neu`) erweitern, Post-Rollback-Absenz asserten [run-sandbox.sh:166-169]
|
||||
- [x] [Review][Patch] (angewendet) Tippfehler: „porcelan" (Z. 151), „NFR-4-texuelle Benennung" (Z. 237), „Ferien-Zustand" (Z. 571) [run-sandbox.sh:151,237,571]
|
||||
- [x] [Review][Patch] (angewendet) §5.13 Pkt. 7: „der Determinismus-Vertrag (AD-17h/A0-19) gilt für … und Post-Zustand" ohne den dokumentierten `generated.at`-Wanduhr-Gap — §5.10 Pkt. 8 hält das Gap ausdrücklich als offene A0-20-Konvention (zwei unabhängige Runs → verschiedene `at` → Post-Zustand weicht ab). Fix: Ausnahme nachtragen („… Post-Zustand — mit dem dokumentierten `generated.at`-Wanduhr-Gap, §5.10 Pkt. 8") [schema/compiler.md:362]
|
||||
|
||||
**[Defer]**:
|
||||
- [x] [Review][Defer] CONSIST-7-Label überschätzt: „identische Plan-/Rollback-/State-Outputs" — im Zwei-Run-Vergleich werden nur Plan-Outputs (`plan_sha`/`plan_state`) verglichen; der Rollback-/State-Nachweis (s7c) läuft einmalig, `log_sha` ist dokumentierte Baseline-Konstante. Die non-vakuum-Kern-Assertion (`plan_sha` byte-identisch) ist real; das Label ist breiter als die Assertion [run-sandbox.sh:516,572] — deferred (Label-Präzisierung; Home: Sandbox-Härtungsrunde)
|
||||
- [x] [Review][Defer] A0-20-Post-Zustand-Negativkontrolle in der Sandbox fehlt: §5.13 Pkt. 3/7 bindet den Determinismus-Vertrag an den Post-Zustand, der `generated.at`-Wanduhr-Gap macht den Post-Zustand über unabhängige Runs nicht byte-identisch — die Sandbox testet den Gap weder negativ noch positiv [run-sandbox.sh:532-568] — deferred (Home: Story 3.8, A0-20-Home, §5.10-Pkt.-8-Präzedenz)
|
||||
- [x] [Review][Defer] Pre-existing-Zeitpunktswort-Fuge: §5.9 Pkt. 6 „am **Anfang der Mutationsphase**" (Z. 287) vs. gefrorene I/O-Matrix + §5.13 „Abbruch **vor** der Mutationsphase" — §5.9 ist in Story 3.7 Wortlaut-unverändert (Rückverweis-Vertrag), die Fuge ist hier nicht ohne Ask-First schließbar [schema/compiler.md:287,356] — deferred, pre-existing (Home: spätere Instruktionsrunde)
|
||||
|
||||
## 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).
|
||||
@@ -134,7 +155,7 @@ _Noch leer — wird von step-04 während der Review-Loops befüllt (append-only
|
||||
|
||||
- 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 — `3-7-…` = `review` im Diff (Implementierungs-Flip `in-progress` + Review-Start-Flip `review` im selben Commit); das `done`-Transition ist nicht Teil dieses Diffs (Step-05-Status-Sync).
|
||||
[`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)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended)
|
||||
# - Retrospective appends its action items to action_items; the status view surfaces open ones
|
||||
generated: 08-14-2026 00:00
|
||||
last_updated: 08-20-2026 00:30
|
||||
last_updated: 08-20-2026 08:56
|
||||
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: review
|
||||
3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell: done
|
||||
3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato: backlog
|
||||
epic-3-retrospective: optional
|
||||
|
||||
|
||||
Reference in New Issue
Block a user