feat: Story 3.3 Review-Loop-1-Patches (bmad-code-review, 3 Layer; kein Loopback) — Präzedenz-Reihenfolge Korrigieren→Präzisieren→Erweitern→No-Op (AD-17h), No-Op als Nicht-Form, Korrigieren-Original-Wortlaut-Erhaltung; Sandbox U1–U9 (U8/U9 Negativ-Kontrollen, volle byte-Identität, reelle S-N-Anker, -eq 1-Konsolidierung, Frontmatter-Reihenfolge/Duplikat); 5 Defers → deferred-work.md; Spec done + Suggested Review Order; Story done
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,33 @@
|
||||
|
||||
Noch nicht adressierte, aber real erkannte Arbeit — gesammelt aus Reviews. Einträge werden append-only ergänzt; bestehende Einträge werden nicht verändert.
|
||||
|
||||
## Deferred from: code review of spec-3-3-bestehende-concepts-erweitern-präzisieren-korrigieren (Story 3.3, 2026-08-19)
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/spec-3-3-bestehende-concepts-erweitern-präzisieren-korrigieren.md`
|
||||
summary: **`sprint-status.yaml last_updated`-Präzisions-Regression** — die Story-3.3-Sprint-Sync hat `last_updated` von `08-19-2026 13:14` (mit Uhrzeit, HEAD-Stand) auf reines Datum `08-19-2026` reduziert; die Pre-3.3-Konvention hielt die `HH:MM`-Granularität. Das Verhalten ist eine General-Eigenschaft des sync-sprint-status-Shared-Sub-Steps (Schritt-06), keine Story-3.3-Inhaltsentscheidung. Home: nächstes Sprint-Sync (Step-06) oder Sync-Verbesserung, die `last_updated` aus dem Zeitstempel ableitet.
|
||||
evidence: `git show HEAD:_bmad-output/implementation-artifacts/sprint-status.yaml` → `last_updated: 08-19-2026 13:14` vs. Working Tree `08-19-2026` (Step-04-Review 2026-08-19, Verification-Gap-Layer, re-executiert verifiziert).
|
||||
status: offen
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/spec-3-3-bestehende-concepts-erweitern-präzisieren-korrigieren.md`
|
||||
summary: **Frozen Story-3.1-No-Op-Bullet trägt die Typos „Schärferung" und „Formata"** — `schema/compiler.md` §5.9 Pkt. 2 (No-Op, `:267`): „keine Schärferung" (inkonsistent zur konsistenten „Schärfung" der neuen operationellen Ebene) und „keiner der drei Formata" (→ „Formate"). Beide sitzen im **frozen** Story-3.1-Text (HEAD-identisch, nicht durch Story 3.3 eingeführt), den die Story-3.3-Operationelle-Ebene operationalisiert; ein fix wäre Re-Negotiation des frozen Textes (Ask-First). Home: nächste Compiler-Instruktions-Revision, die §5.9 Pkt. 2 ohnehin berührt.
|
||||
evidence: `git show HEAD:schema/compiler.md` `:267` (frozen): „keine Schärferung, keine Ersetzung … keiner der drei Formata greift" — Step-04-Review (2026-08-19, Verification-Gap-Layer), via `git show` verifiziert.
|
||||
status: offen
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/spec-3-3-bestehende-concepts-erweitern-präzisieren-korrigieren.md`
|
||||
summary: **U6-Zwei-Run-Identitäts-Nachweis überzeichnet „auch nach Commit" und kreuzreferenziert den `generated.at`↔AD-17h-Gap nicht** — der Claim „identische SHA-256 … auch nach Commit" gilt für alpha.md (reproduzierbar `6b148dd1…`) im Worktree-/Staged-Zustand; `wiki/log.md` embeddet den random `$BASE`-SHA (`log_update`), daher weicht der log.md-Hash je Run ab (konstruktionsbedingt — der Commit ist die jeweilige Mutations-Boundary). Der at↔AD-17h-Gap (gleiche Evidenz, zwei Runs → verschiedene `at`) ist in compiler.md offen verankert. Home: Story 3.8 (Determinismus-Vertrag, AD-17h — Behandlung von `at` und des Bundle-State-Vergleichs).
|
||||
evidence: Step-04-Review (2026-08-19, Verification-Gap-Layer): Sandbox-Doppellauf — alpha.md SHA `6b148dd1…` reproduzierbar, log.md SHA je Lauf verschieden (`89b82cb2…`, `358bad3b…`); compiler.md at↔AD-17h-Hinweis (generated.at-Konvention).
|
||||
status: offen (Home: Story 3.8)
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/spec-3-3-bestehende-concepts-erweitern-präzisieren-korrigieren.md`
|
||||
summary: **Sandbox-U2-Szenario ist selbst-erfüllend und U7 misst die reale REIHENFOLGE nicht** — U2 schärft durch Hinzufügen einer neuen Faktenbehauptung (neue Stelle), die nach dem Erweitern-Kriterium Erweitern wäre, und passt nur, weil das Präzisieren-Wording hartkodiert ist; die Form-Wahl-Prozedur selbst wird nicht geprüft. U7 begründet „v2 vor v3" als „lexikografischer Tie-Break", obwohl v2/v3 verschiedene Dateien sind (Tie-Break gilt nur bei identischem Ort); der Fall „R-1-Dateiordnung ≠ lexikografische Ordnung" bleibt ungetestet. Kein Instruktions-Defekt (Abgrenzungs-Reihenfolge ist jetzt deterministisch fixiert), sondern Test-Eigenschaften-Hinweis. Home: nächste Sandbox-Erweiterung (Story 3.4/3.5) — eine Form-Wahl-Klassifikationsprobe + U7-Ordnungs-Variante mit nicht-lexikografischer R-1-Reihenfolge.
|
||||
evidence: Step-04-Review (2026-08-19, Blind-Hunter + Verification-Gap-Layer): `run-sandbox.sh` U2 (neue Faktenbehauptung via `sed`, hartkodiertes Präzisieren-Wording), U7 (Ordering-Rationale vs. `compiler.md:268` REIHENFOLGE-Definition — Zuwachs-Sicht, lexikografisch nur bei identischem Ort).
|
||||
status: offen
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/spec-3-3-bestehende-concepts-erweitern-präzisieren-korrigieren.md`
|
||||
summary: **Gemischte Normalisierungs-Politik im Sandbox-Evidenztext (Umlaute vs. Transkriptionen) ist ein Determinismus-Hazard für den Term-Abgleich** — Sandbox-Bodies nutzen Umlaut-Schreibweisen („Schlüssel", „läuft"), raw-Evidenz transkribiert („Schluessel"); die Abgrenzungskriterien beruhen auf Term-/Stellen-Abgleichen gegen §5.5-Inline-Verweise, und die §3.2-Normalisierung (lowercasing + `[-–_ ]`-Kollaps) deckt Umlaut-/Em-Dash-Divergenzen nicht. Bekannte Story-3.2-Lücke (Em-Dash, Home Story 3.8) plus Sandbox-interne Divergenzen. Home: Story 3.8 (Determinismus-Vertrag, Normalisierungs-Vollständigkeit) oder Sandbox-Vereinheitlichung in einer Folge-Story.
|
||||
evidence: Step-04-Review (2026-08-19, Verification-Gap-Layer): `run-sandbox.sh` — U1/U2/U3/U7 Body mit Umlaut-Schreibweisen vs. raw-Evidenz mit Transkriptionen; §3.2-Pkt.-1b-Kollaps-Klasse ohne Umlaut-/Em-Dash.
|
||||
status: offen (Home: Story 3.8)
|
||||
|
||||
- source_spec: `_bmad-output/implementation-artifacts/spec-1-2-sources-lokal-unter-raw-bereitstellen.md`
|
||||
summary: Checksum-/Fingerprint (SHA-256) der evtl. Git-Revision der Herkunftsquelle in `source.md` aufnehmen, damit die Provenienz reproduzierbar ist.
|
||||
evidence: Blind-Hunter-Review (Finding 1/2): `source.md`-Provenienz ist ohne Fingerprint der Quelle in einem reinen Clone nicht verifizierbar; AD-3-basiertes „neue, datierte Datei"-Schema braucht einen Maschinen-Lesbaren Stand.
|
||||
|
||||
@@ -0,0 +1,392 @@
|
||||
#!/usr/bin/env bash
|
||||
# Story 3.3 — Sandbox-Tests der operationellen Update-Formen (§5.9 Pkt. 2, Revision 2.8)
|
||||
# Re-executierbar: bash run-sandbox.sh (ab Workspace-Root; Sandbox unter /tmp/sb33)
|
||||
# Zweck: alle drei Update-Formen (Erweitern + Präzisieren + Korrigieren) + No-Op
|
||||
# durchspielen; die Erhaltungs-Invariante (§5.9 Pkt. 5) als HARDE Assertion
|
||||
# erzwingen (Diff nach Normalisierung ⊆ {betroffener Concept-Pfad, log}; keine
|
||||
# neue Datei; kein Ghost-Diff); Zwei-Run-Identität (AD-17h/A0-19);
|
||||
# Frontmatter-Konformität je mutiertem Concept (Vertrag §3.3/§3.4-Subset).
|
||||
# Linux-Sandbox-Semantik auf einem /tmp-Baum — NIE der reale wiki/-Baum.
|
||||
set -u
|
||||
ROOT=$(mktemp -d /tmp/sb33-XXXXXX)
|
||||
SB="$ROOT/sb"
|
||||
mkdir -p "$SB/wiki" "$SB/raw"
|
||||
cd "$SB"
|
||||
git init -q
|
||||
git config user.email "sandbox@test"
|
||||
git config user.name "Sandbox"
|
||||
|
||||
# ---------- Basis-Baum (committete Ausgangslage = Baseline-Commit) ----------
|
||||
# Concept alpha mit drei belegten Aussagen; Aussagen 1/2 sind fachlich korrekt,
|
||||
# Aussage 3 ist fehlerhaft (Korrigieren-Ziel des Szenarios U3). beta ist ein
|
||||
# nicht-betroffenes Kontroll-Concept (Ghost-Diff-Kontrolle, U5).
|
||||
cat > wiki/index.md <<'EOF'
|
||||
# Index
|
||||
- [Alpha](alpha.md)
|
||||
- [Beta](beta.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 verwendet deterministische-init-sequenz für den Abgleich (raw/alpha-v1.md#S-1).
|
||||
Alpha läuft ausschließlich auf isolierten Netzen (raw/alpha-v1.md#S-3).
|
||||
Alpha rotiert seine Schlüssel nie (raw/alpha-v1.md#S-2).
|
||||
EOF
|
||||
cat > wiki/beta.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/beta-v1.md
|
||||
id: s1
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-16T09:00:00Z
|
||||
---
|
||||
Beta 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 für den Abgleich.
|
||||
### S-2
|
||||
Evidenz v1: keine Rotation der Schlüssel.
|
||||
### S-3
|
||||
Evidenz v1: Alpha läuft auf isolierten Netzen.
|
||||
EOF
|
||||
cat > raw/beta-v1.md <<'EOF'
|
||||
### S-1
|
||||
Evidenz v1: Beta-Thema.
|
||||
EOF
|
||||
git add -A
|
||||
git commit -qm "Baseline"
|
||||
BASE=$(git rev-parse HEAD)
|
||||
echo "BASELINE-COMMIT: $BASE"
|
||||
echo "Sandbox-Root: $ROOT (loeschbar: rm -rf $ROOT)"
|
||||
echo
|
||||
|
||||
runlabel() { echo; echo "########## $1 ##########"; }
|
||||
# Isolation: Worktree auf BASE zuruecksetzen (kein Carry-over ueber Szenarien)
|
||||
isolate() { git checkout -q -b "$1" "$BASE" 2>/dev/null || git checkout -q "$1"; git reset -q --hard "$BASE"; git clean -qfd wiki raw; }
|
||||
|
||||
# Pkt.-5-Probe (D-1-Form): Baseline-Diff + porcelain, normalisiert
|
||||
# (wiki/-Praefix + .md-Suffix gestrippt, LC_ALL=C-sortiert; deterministisch, AD-17h)
|
||||
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) ----------
|
||||
# Erwartete erlaubte Menge = Space-getrennte normalisierte Pfade
|
||||
# (z. B. "alpha log"). Jeder Proben-Eintrag MUSS in der erlaubten Menge liegen —
|
||||
# sonst Ghost-Diff (nicht betroffener Pfad) → HARD-FAIL, Exit 1 (NFR-4/FT-6).
|
||||
assert_invariant() {
|
||||
local expected="$1" got p bad=0 rcs=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
|
||||
# Keine neue Datei (Duplikat-Kontrolle: die ??-Sicht fehlt git diff allein)
|
||||
rcs=$(git status --porcelain -- wiki/ | grep -c '^??' || true)
|
||||
[ "$rcs" -eq 0 ] || { echo "HARD-FAIL (keine neue Datei): $rcs ungetrackte neue Datei(en) unter wiki/ (Duplikat/Ghost-Diff)" >&2; bad=1; }
|
||||
if [ "$bad" -eq 0 ]; then
|
||||
echo "RESULT: PASS — Probe {$got} ⊆ erlaubte Menge {$expected}; keine neue Datei; kein Ghost-Diff"
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ---------- Frontmatter-Konformitaet je mutiertem Concept (Vertrag §3.3/§3.4, §6.5) ----------
|
||||
# $1=Datei; $2...=erwartete sources[].resource-Werte. Prueft: Top-Level-Key-Subset
|
||||
# {type,sources,generated,verified,status,stale_after}, sources-Eintrag-Key-Subset
|
||||
# (Vertrag §3.3-Innen-Ebene), type=concept, generated.at = volle ISO-8601-Datetime
|
||||
# (die erlaubten Key-Mengen sind inline im awk-Subset-Vergleich hartkodiert).
|
||||
assert_frontmatter() {
|
||||
local f="$1"; shift
|
||||
local r bad=0
|
||||
# Kontextuelle Validierung ueber awk: Top-Level-Subset {type,sources,generated,
|
||||
# verified,status,stale_after}; Innen-Ebenen je Sektion — sources: Vertrag §3.3-
|
||||
# Subset {resource,id,title,author,usage_count,last_modified}; generated/verified:
|
||||
# {by,at} (Vertrag §3.4/§3.5). Jeder andere Key = unbefugt (Punkt 6, §6.5).
|
||||
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
|
||||
# Duplikat-Prohibition: jeder Top-Level-Key hoechstens einmal (Punkt 13).
|
||||
if (seenk[k]++) print "DUP_KEY:" k
|
||||
# Canonische Reihenfolge (Vertrag §3.x Normalform: type, sources, generated,
|
||||
# verified, status, stale_after): jeder neue Key-Kandidat muss der canonichen
|
||||
# Ordnung folgen — Verstoß via Ordnungs-Rang erkannt (ORDER_VIOLATION).
|
||||
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 && r<lastr) print "ORDER_VIOLATION:" k
|
||||
if (r>0) 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)"
|
||||
}
|
||||
|
||||
# ---------- Update-Helfer (deterministisch; at gepinnt fuer Zwei-Run-Identitaet) ----------
|
||||
AT_NEW="2026-08-19T12:00:00Z"
|
||||
bump_at() { sed -i "s|^ at: .*| at: $AT_NEW|" "$1"; }
|
||||
add_source() { # $1=Datei $2=resource $3=id (Eintrag vor der generated:-Zeile einfuegen)
|
||||
sed -i "s|^generated:| - resource: $2\n id: $3\ngenerated:|" "$1"
|
||||
}
|
||||
log_update() { # $1=Concept-Pfad $2=raw-Datei
|
||||
printf '\n## 2026-08-19\n- Story 3.1-Update: %s (%s; Baseline %s)\n' "$1" "$2" "$BASE" >> wiki/log.md
|
||||
}
|
||||
|
||||
# =====================================================================
|
||||
runlabel "U1: ERWEITERN — neue belegte Aussage, bestehender Pfad wird erweitert (AC-1/FR-6)"
|
||||
isolate u1
|
||||
cat > raw/alpha-v2.md <<'EOF'
|
||||
### S-4
|
||||
Evidenz v2 (neue Aussage): Alpha-Replikation traegt einen zusaetzlichen Schluessel-Rotationszyklus.
|
||||
EOF
|
||||
git add -A; git commit -qm "Zuwachs raw/alpha-v2.md"
|
||||
echo "--- Kandidaten-Erhebung: rg -l 'schluessel-rotationszyklus' wiki/ ---"
|
||||
if command -v rg >/dev/null 2>&1; then rg -l 'schluessel-rotationszyklus' -g '!log.md' wiki/ || true
|
||||
else grep -rl 'schluessel-rotationszyklus' --exclude=log.md wiki/ || true; fi
|
||||
echo "--- UPDATE: neue Aussage als Absatz angefuegt (§5.5-Inline-Beleg), sources-Zuwachs s2, at-Bump ---"
|
||||
cat >> wiki/alpha.md <<'EOF'
|
||||
Alpha führt für die Replikation einen zusätzlichen Schlüssel-Rotationszyklus (raw/alpha-v2.md#S-4).
|
||||
EOF
|
||||
add_source wiki/alpha.md raw/alpha-v2.md s2
|
||||
bump_at wiki/alpha.md
|
||||
log_update alpha raw/alpha-v2.md
|
||||
echo "--- Struktur-Erhaltung: bestehende drei Aussagen byte-identisch erhalten? ---"
|
||||
grep -qF 'Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich (raw/alpha-v1.md#S-1).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 1 wurde beim Erweitern umgeschrieben" >&2; exit 1; }
|
||||
grep -qF 'Alpha läuft ausschließlich auf isolierten Netzen (raw/alpha-v1.md#S-3).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 2 (Netze) wurde beim Erweitern umgeschrieben" >&2; exit 1; }
|
||||
grep -qF 'Alpha rotiert seine Schlüssel nie (raw/alpha-v1.md#S-2).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 3 wurde beim Erweitern umgeschrieben" >&2; exit 1; }
|
||||
echo "RESULT: PASS — bestehende belegte Aussagen unveraendert (Struktur-Erhaltungsregel Erweitern)"
|
||||
echo "--- Probe (Pkt. 5, vor dem Commit) ---"; probe
|
||||
assert_invariant "alpha log"
|
||||
assert_frontmatter wiki/alpha.md raw/alpha-v1.md raw/alpha-v2.md
|
||||
|
||||
# =====================================================================
|
||||
runlabel "U2: PRAEZISIEREN — bestehende Aussage wird an ihr selbst geschaerft (AC-2/FR-6)"
|
||||
isolate u2
|
||||
cat > raw/alpha-v2.md <<'EOF'
|
||||
### S-1
|
||||
Evidenz v2 (Praezisierung): die deterministische-init-sequenz wird nach der initialen Synchronisation zusaetzlich rotiert.
|
||||
EOF
|
||||
git add -A; git commit -qm "Zuwachs raw/alpha-v2.md"
|
||||
echo "--- UPDATE: Aussage 1 an Position geschaerft, Beleg nachgefuehrt (Multi-Beleg §5.5); kein Satz-Umbau ---"
|
||||
sed -i 's|^Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich (raw/alpha-v1.md#S-1)\.|Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich und rotiert sie nach der initialen Synchronisation zusätzlich (raw/alpha-v1.md#S-1; raw/alpha-v2.md#S-1).|' wiki/alpha.md
|
||||
add_source wiki/alpha.md raw/alpha-v2.md s2
|
||||
bump_at wiki/alpha.md
|
||||
log_update alpha raw/alpha-v2.md
|
||||
echo "--- Struktur-Erhaltung: Aussagen 2/3 unveraendert, geschaerfte Aussage 1 an Position? ---"
|
||||
grep -qF 'Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich und rotiert sie nach der initialen Synchronisation zusätzlich (raw/alpha-v1.md#S-1; raw/alpha-v2.md#S-1).' wiki/alpha.md || { echo "HARD-FAIL: geschaerfte Aussage fehlt" >&2; exit 1; }
|
||||
grep -qF 'Alpha läuft ausschließlich auf isolierten Netzen (raw/alpha-v1.md#S-3).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 2 wurde beim Praezisieren veraendert" >&2; exit 1; }
|
||||
grep -qF 'Alpha rotiert seine Schlüssel nie (raw/alpha-v1.md#S-2).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 3 wurde beim Praezisieren veraendert" >&2; exit 1; }
|
||||
echo "RESULT: PASS — Schaerfung an der Aussage selbst, Position/Struktur erhalten, kein Satz-Umbau"
|
||||
echo "--- Probe ---"; probe
|
||||
assert_invariant "alpha log"
|
||||
assert_frontmatter wiki/alpha.md raw/alpha-v1.md raw/alpha-v2.md
|
||||
|
||||
# =====================================================================
|
||||
runlabel "U3: KORRIGIEREN — fehlerhafte Aussage abgeloest, nicht still geloescht (AC-2, AD-16-Default)"
|
||||
isolate u3
|
||||
cat > raw/alpha-v2.md <<'EOF'
|
||||
### S-2
|
||||
Evidenz v2 (Korrektur): Alpha rotiert seine Schluessel bei jeder Sitzung.
|
||||
EOF
|
||||
git add -A; git commit -qm "Zuwachs raw/alpha-v2.md"
|
||||
echo "--- UPDATE: Aussage 3 wird explizit abgeloest + Ersetzungsbeleg; keine stille Loeschung ---"
|
||||
sed -i 's|^Alpha rotiert seine Schlüssel nie (raw/alpha-v1.md#S-2)\.|Alpha rotiert seine Schlüssel nie (raw/alpha-v1.md#S-2) — überholt durch: Alpha rotiert seine Schlüssel bei jeder Sitzung (raw/alpha-v2.md#S-2).|' wiki/alpha.md
|
||||
add_source wiki/alpha.md raw/alpha-v2.md s2
|
||||
bump_at wiki/alpha.md
|
||||
log_update alpha raw/alpha-v2.md
|
||||
echo "--- AD-16-Default: alte Aussagen 1/2 textuell erhalten (keine stille Loeschung, keine flankierende Umschreibung)? ---"
|
||||
grep -qF 'Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich (raw/alpha-v1.md#S-1).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 1 wurde beim Korrigieren flankierend umgeschrieben" >&2; exit 1; }
|
||||
grep -qF 'Alpha läuft ausschließlich auf isolierten Netzen (raw/alpha-v1.md#S-3).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 2 wurde beim Korrigieren flankierend umgeschrieben" >&2; exit 1; }
|
||||
grep -qF 'Alpha rotiert seine Schlüssel nie (raw/alpha-v1.md#S-2)' wiki/alpha.md || { echo "HARD-FAIL: alte Aussage wurde still geloescht oder ihr Wortlaut verändert (AD-16, Struktur-Erhaltungsregel Korrigieren)" >&2; exit 1; }
|
||||
grep -qF 'rotiert seine Schlüssel bei jeder Sitzung (raw/alpha-v2.md#S-2)' wiki/alpha.md || { echo "HARD-FAIL: Ersetzungsbeleg fehlt" >&2; exit 1; }
|
||||
echo "RESULT: PASS — Abloesung mit Ersetzungsbeleg, Provenienz erhalten (AD-16-Default Erhaltung)"
|
||||
echo "--- Probe ---"; probe
|
||||
assert_invariant "alpha log"
|
||||
assert_frontmatter wiki/alpha.md raw/alpha-v1.md raw/alpha-v2.md
|
||||
|
||||
# =====================================================================
|
||||
runlabel "U4: NO_OP — Evidenz ist bereits vollstaendig im Body (engere Auslegung, Pkt. 2)"
|
||||
isolate u4
|
||||
cat > raw/alpha-v2.md <<'EOF'
|
||||
Evidenz v2 (Redundanz): deterministische-init-sequenz fuer den Abgleich; Alpha rotiert seine Schluessel nie.
|
||||
EOF
|
||||
git add -A; git commit -qm "Zuwachs raw/alpha-v2.md"
|
||||
echo "--- Kandidaten-Erhebung: Terme treffen alpha; die Evidenz ist bereits vollstaendig enthalten ---"
|
||||
echo "--- UPDATE: KEINE Body-Mutation, KEIN at-Bump, KEIN sources-Zusatz, KEIN log.md-Eintrag (byte-identisch) ---"
|
||||
if git status --porcelain -- wiki/ | grep -q .; then
|
||||
echo "HARD-FAIL (No-Op): Wiki-Baum ist nicht byte-identisch" >&2
|
||||
git status --porcelain -- wiki/
|
||||
exit 1
|
||||
fi
|
||||
echo "RESULT: PASS — No-Op: keine Mutation, kein at-Bump, kein sources-Zusatz, kein log.md-Eintrag (byte-identisch)"
|
||||
echo "--- Probe (leer = Ghost-Diff-negativ, leere Menge ist Teilmenge jeder erlaubten Menge) ---"; probe
|
||||
assert_invariant ""
|
||||
|
||||
# =====================================================================
|
||||
runlabel "U5: NEGATIV-KONTROLLE — Assertions-Mechanik erkennt einen Ghost-Diff (nicht vacuous)"
|
||||
isolate u5
|
||||
echo "unbefugte Mutation auf nicht-betroffenem beta" >> wiki/beta.md # simulierter Ghost-Diff
|
||||
echo "--- Probe (erwartet: beta ausserhalb der erlaubten Menge {alpha log}) ---"; probe
|
||||
if ( assert_invariant "alpha log" ) >/dev/null 2>&1; then
|
||||
echo "HARD-FAIL (Assertions-Mechanik): Ghost-Diff auf beta wurde NICHT erkannt" >&2
|
||||
exit 1
|
||||
else
|
||||
echo "RESULT: PASS — Ghost-Diff auf beta wurde erkannt (Assertions-Mechanik loest verlaesslich HARD-FAIL aus, kein Ghost-Diff kommt durch)"
|
||||
fi
|
||||
|
||||
# =====================================================================
|
||||
runlabel "U6: ZWEI-RUN-IDENTITAET (AD-17h/A0-19) — gleicher Git-State + gleiches Eingabeset -> identischer Update-Vorgang"
|
||||
# Zwei unabhaengige Runs ueber dieselbe Evidenz (Erweitern); die Ergebnisse
|
||||
# (mutierter Body + Frontmatter + Status) muessen byte-identisch sein.
|
||||
run_erweitern() { # $1 = Branchname; mutiert Worktree, dann git add -A (Staging)
|
||||
isolate "$1"
|
||||
cat > raw/alpha-v2.md <<'EOF'
|
||||
### S-4
|
||||
Evidenz v2 (neue Aussage): Alpha-Replikation traegt einen zusaetzlichen Schluessel-Rotationszyklus.
|
||||
EOF
|
||||
git add -A; git commit -qm "Zuwachs raw/alpha-v2.md"
|
||||
cat >> wiki/alpha.md <<'EOF'
|
||||
Alpha führt für die Replikation einen zusätzlichen Schlüssel-Rotationszyklus (raw/alpha-v2.md#S-4).
|
||||
EOF
|
||||
add_source wiki/alpha.md raw/alpha-v2.md s2
|
||||
bump_at wiki/alpha.md
|
||||
log_update alpha raw/alpha-v2.md
|
||||
git add -A # Staging — die Mutationen sind Teil des Runs (Commit-Boundary = Mutations-Boundary)
|
||||
}
|
||||
run_erweitern u6a
|
||||
A_ALPHA=$(sha256sum wiki/alpha.md | cut -d' ' -f1) # Worktree-Inhalt = staged-Inhalt (git add)
|
||||
A_LOG=$(sha256sum wiki/log.md | cut -d' ' -f1)
|
||||
git commit -qm "Run A (Erweitern)"
|
||||
A_ALPHA_COM=$(git show HEAD:wiki/alpha.md | sha256sum | cut -d' ' -f1)
|
||||
run_erweitern u6b
|
||||
B_ALPHA=$(sha256sum wiki/alpha.md | cut -d' ' -f1)
|
||||
B_LOG=$(sha256sum wiki/log.md | cut -d' ' -f1)
|
||||
git commit -qm "Run B (Erweitern)"
|
||||
B_ALPHA_COM=$(git show HEAD:wiki/alpha.md | sha256sum | cut -d' ' -f1)
|
||||
echo "Run A (alpha.md): $A_ALPHA"
|
||||
echo "Run B (alpha.md): $B_ALPHA"
|
||||
echo "Run A (log.md): $A_LOG"
|
||||
echo "Run B (log.md): $B_LOG"
|
||||
echo "Run A commit (alpha.md): $A_ALPHA_COM ; Run B commit (alpha.md): $B_ALPHA_COM"
|
||||
if [ "$A_ALPHA" = "$B_ALPHA" ] && [ "$A_LOG" = "$B_LOG" ] && [ "$A_ALPHA_COM" = "$B_ALPHA_COM" ]; then
|
||||
echo "RESULT: PASS — zwei unabhaengige Runs ueber dieselbe Evidenz -> identischer Update-Vorgang (AD-17h/A0-19)"
|
||||
else
|
||||
echo "HARD-FAIL (Determinismus-Vertrag): Run A und Run B weichen ab" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# =====================================================================
|
||||
runlabel "U7: MEHRFACH_TREFFER — zwei Neuevidenzen desselben Runs treffen denselben Concept-Pfad (Konsolidierung, I/O-Matrix)"
|
||||
# Matrix-Zeile MEHRFACH_TREFFER: mehrere neue Wissenseinheiten desselben Runs auf
|
||||
# denselben Pfad -> EIN konsolidiertes Update (eine Body-Mutation, EIN log.md-Eintrag,
|
||||
# EIN konsolidierter sources-Zuwachs, EIN generated.at). Reihenfolge = Zuwachs-Sicht
|
||||
# (Ankunftsreihenfolge der Belege); lexikografischer Tie-Break bei identischem Ort
|
||||
# (Body-Ende) -> alpha-v2.md vor alpha-v3.md.
|
||||
isolate u7
|
||||
cat > raw/alpha-v2.md <<'EOF'
|
||||
### S-4
|
||||
Evidenz v2 (neue Aussage): Alpha-Replikation nutzt Quorum-Bestaetigung.
|
||||
EOF
|
||||
cat > raw/alpha-v3.md <<'EOF'
|
||||
### S-4
|
||||
Evidenz v3 (neue Aussage): Alpha-Replikation waechst linear zum Cluster.
|
||||
EOF
|
||||
git add -A; git commit -qm "Zwei Einheiten, ein Run (raw/alpha-v2.md + raw/alpha-v3.md)"
|
||||
echo "--- Kandidaten-Erhebung: beide Terme treffen denselben Pfad alpha ---"
|
||||
echo "--- KONSOLIDIERTES UPDATE: beide Aussagen als Absaetze angehaengt (Zuwachs-Sicht: v2 vor v3), EIN log-Eintrag, sources-Zuwachs s2+s3, EIN at ---"
|
||||
cat >> wiki/alpha.md <<'EOF'
|
||||
Alpha-Replikation nutzt Quorum-Bestaetigung (raw/alpha-v2.md#S-4).
|
||||
Alpha-Replikation waechst linear zum Cluster (raw/alpha-v3.md#S-4).
|
||||
EOF
|
||||
add_source wiki/alpha.md raw/alpha-v2.md s2
|
||||
add_source wiki/alpha.md raw/alpha-v3.md s3
|
||||
bump_at wiki/alpha.md
|
||||
log_update alpha "raw/alpha-v2.md + raw/alpha-v3.md"
|
||||
echo "--- Konsolidierung: genau EIN log.md-Eintrag und EIN generated.at trotz zweier Einheiten? ---"
|
||||
[ "$(grep -c 'Story 3.1-Update: alpha' wiki/log.md)" -eq 1 ] || { echo "HARD-FAIL: Mehrfach-Treffer erzeugte nicht exakt einen log.md-Eintrag (Konsolidierung oder Eintragspflicht Pkt. 4 verletzt)" >&2; exit 1; }
|
||||
grep -qF 'raw/alpha-v2.md' wiki/log.md || { echo "HARD-FAIL: konsolidierter log.md-Eintrag verlinkt raw/alpha-v2.md nicht (Pkt. 4, genutzte raw/-Quellen)" >&2; exit 1; }
|
||||
grep -qF 'raw/alpha-v3.md' wiki/log.md || { echo "HARD-FAIL: konsolidierter log.md-Eintrag verlinkt raw/alpha-v3.md nicht (Pkt. 4, genutzte raw/-Quellen)" >&2; exit 1; }
|
||||
[ "$(grep -c '^ at:' wiki/alpha.md)" -eq 1 ] || { echo "HARD-FAIL: Mehrfach-Treffer erzeugte mehrere generated.at" >&2; exit 1; }
|
||||
echo "--- Struktur-Erhaltung: alte Aussagen byte-identisch, beide neuen Aussagen vorhanden, Zuwachs-Sicht-Ordnung v2-vor-v3 ---"
|
||||
grep -qF 'Das Alpha-Protokoll verwendet deterministische-init-sequenz für den Abgleich (raw/alpha-v1.md#S-1).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 1 wurde beim konsolidierten Update umgeschrieben" >&2; exit 1; }
|
||||
grep -qF 'Alpha läuft ausschließlich auf isolierten Netzen (raw/alpha-v1.md#S-3).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 2 wurde beim konsolidierten Update umgeschrieben" >&2; exit 1; }
|
||||
grep -qF 'Alpha rotiert seine Schlüssel nie (raw/alpha-v1.md#S-2).' wiki/alpha.md || { echo "HARD-FAIL: Aussage 3 wurde beim konsolidierten Update umgeschrieben" >&2; exit 1; }
|
||||
grep -qF 'Quorum-Bestaetigung (raw/alpha-v2.md#S-4)' wiki/alpha.md || { echo "HARD-FAIL: neue Aussage aus v2 fehlt" >&2; exit 1; }
|
||||
grep -qF 'waechst linear zum Cluster (raw/alpha-v3.md#S-4)' wiki/alpha.md || { echo "HARD-FAIL: neue Aussage aus v3 fehlt" >&2; exit 1; }
|
||||
v2pos=$(grep -n 'Quorum-Bestaetigung' wiki/alpha.md | cut -d: -f1); v3pos=$(grep -n 'waechst linear' wiki/alpha.md | cut -d: -f1)
|
||||
[ "$v2pos" -lt "$v3pos" ] || { echo "HARD-FAIL: Zuwachs-Sicht-Ordnung verletzt (v3 vor v2)" >&2; exit 1; }
|
||||
echo "RESULT: PASS — ein konsolidiertes Update (eine Body-Aenderung, ein log-Eintrag, ein sources-Zuwachs s2+s3, ein at); Zuwachs-Sicht-Ordnung v2-vor-v3"
|
||||
echo "--- Probe ---"; probe
|
||||
assert_invariant "alpha log"
|
||||
assert_frontmatter wiki/alpha.md raw/alpha-v1.md raw/alpha-v2.md raw/alpha-v3.md
|
||||
|
||||
# =====================================================================
|
||||
runlabel "U8: STRUKTUR-VERLETZUNG — unbefugter Frontmatter-Key wird erkannt (Pkt. 5 Struktur-Ebene, P2-Check-Element (6))"
|
||||
isolate u8
|
||||
echo "--- simulierter Verstoß gegen die Struktur-Erhaltung: unbefugter Frontmatter-Key 'foo' im YAML-Block ---"
|
||||
awk '/^type: concept$/{print; print "foo: bar"; next} {print}' wiki/alpha.md > /tmp/sb33-fm && mv /tmp/sb33-fm wiki/alpha.md
|
||||
echo "--- Probe + Frontmatter-Konformität (erwartet: HARD-FAIL, Verstoß textuell benannt, NFR-4) ---"; probe
|
||||
if ( assert_invariant "alpha log" && assert_frontmatter wiki/alpha.md ) >/dev/null 2>&1; then
|
||||
echo "HARD-FAIL (Struktur-Ebene): unbefugter Frontmatter-Key wurde NICHT erkannt (Pkt. 5/Pkt. 6-Element (6))" >&2
|
||||
exit 1
|
||||
else
|
||||
echo "RESULT: PASS — unbefugter Frontmatter-Key wird als Struktur-Verstoß erkannt (Frontmatter-Subset-HARD-FAIL ausgelöst)"
|
||||
fi
|
||||
|
||||
# =====================================================================
|
||||
runlabel "U9: NEUE-DATEI — ungetrackte neue Datei unter wiki/ wird erkannt (??-Sicht, Duplikat-Kontrolle)"
|
||||
isolate u9
|
||||
echo "--- simulierter Ghost-Diff: ungetrackte neue Datei wiki/neu.md (Duplikat, ??-Sicht) ---"
|
||||
echo "unbefugte neue Concept-Datei" > wiki/neu.md
|
||||
echo "--- Probe (erwartet: neu ausserhalb erlaubter Menge + ??-Sicht-HARD-FAIL) ---"; probe
|
||||
if ( assert_invariant "alpha log" ) >/dev/null 2>&1; then
|
||||
echo "HARD-FAIL (Keine-neue-Datei): ungetrackte neue Datei wiki/neu.md wurde NICHT erkannt (??-Sicht, Duplikat-Kontrolle)" >&2
|
||||
exit 1
|
||||
else
|
||||
echo "RESULT: PASS — ungetrackte neue Datei unter wiki/ wird über die ??-Sicht erkannt (Duplikat/Ghost-Diff, keine neue Datei)"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "===== Sandbox abgeschlossen (alle 9 Tests U1-U9) ====="
|
||||
echo "Sandbox-Root: $ROOT (loeschbar: rm -rf $ROOT)"
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
---
|
||||
title: 'Bestehende Concepts erweitern/präzisieren/korrigieren — Update-Formen operativ schärfen (Story 3.3)'
|
||||
type: 'feature'
|
||||
created: '2026-08-19'
|
||||
status: 'done'
|
||||
review_loop_iteration: 0
|
||||
baseline_commit: 52f88fdc5f3ea0fe5323412ca3ba8b4a1bdbf549
|
||||
context:
|
||||
- _bmad-output/implementation-artifacts/epic-3-context.md
|
||||
---
|
||||
|
||||
<frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates">
|
||||
|
||||
## Intent
|
||||
|
||||
**Problem:** Story 3.1 verankerte die Update-Mechanik (Erweitern/Präzisieren/Korrigieren) in `schema/compiler.md` §5.9 als Regeltext, Story 3.2 die Candidate-Erhebung (§3.2). Unoperativ bleibt die **Ausführung je Update-Form** — v. a. das Story-3.3-AC aus FR-6: „der Text wird präzisiert oder korrigiert, **ohne die Struktur zu zerstören**". Der Compiler hat keine deterministische Anleitung, wie Präzisieren (Schärfen einer bestehenden Aussage) von Erweitern (Anfügen) abzugrenzen ist und was die „Struktur" (Frontmatter, bestehende belegte Aussagen, Provenienz-Verkettung) beim Übergriff auf einen bestehenden Absatz schützt.
|
||||
|
||||
**Approach:** Story 3.3 schärft §5.9 (Revision 2.8): die drei Update-Formen werden **operationell** ausformuliert — je Form ein deterministisch prüfbares **Abgrenzungskriterium** (Welche Form greift wann?), die **Struktur-Erhaltungsregel** (was bleibt unverändert: Frontmatter-Subset, bestehende belegte Aussagen + §5.5-Inline-Verweise, §5.6-Pin) und der Textgenauigkeits-Rahmen (Schärfen an der Aussage, kein Satz-Umbau, kein Neuschreiben ohne Ersetzungsbeleg). Zusätzlich eine **re-executierbare Sandbox** (`sandbox-3-3/run-sandbox.sh`, Muster Story-3.1): Demonstriert einen echten Update-Run mit committeter Neuevidenz in allen drei Formen + No-Op und prüft die Erhaltungs-Invariante (§5.9 Pkt. 5) als harte Assertion. Keine Inhalts-Mutation des realen Bundles (kein neues `raw/`-Material, AD-3); kein neues Prädikat, kein Vertrag-/Validator-/`raw/`-Change; kein Standalone (D-3).
|
||||
|
||||
## Boundaries & Constraints
|
||||
|
||||
**Always:**
|
||||
- **Instruktions-Story (D-3):** Schärfung ausschließlich in `schema/compiler.md` §5.9 als deterministischer Text. Kein executable, kein Standalone, keine neue §7-Invaliditätsklasse, kein Change an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3).
|
||||
- **Struktur-Erhaltungs-Invariante (Kern, FR-6/AC-2):** Update tastet die Struktur nicht an — (1) Frontmatter bleibt Subset-konform (nur `sources`-Zuwachs um echten neuen Beleg + `generated.at`-Bump zulässig); (2) bestehende belegte Aussagen werden nicht umgeschrieben ohne Präzisieren an ihr selbst bzw. Korrigieren mit Ersetzungsbeleg (§5.5-Inline-Verweise bleiben gültig soweit Beleg Body-Bestand); (3) gepinnte Linkform unverändert, keine neuen Links außer bei echten Beziehungen (§5.9 Pkt. 3).
|
||||
- **Determinismus (AD-17h/A0-19):** Form-Wahl folgt aus der committeten Evidenz; gleicher Git-State + gleiche Eingabemenge → identischer Update-Vorgang. Abgrenzungsregeln textuell prüfbar (neue Aussage → Erweitern; Schärfung einer bestehenden → Präzisieren; ersetzende → Korrigieren).
|
||||
- **Kein Leasing-Scope in 3.3:** AC-4 (Mutation nur im geleasten Bereich, AD-17.3) bleibt Story 3.5/3.6; AD-17f-Basis unverändert. §5.9 Pkt. 5/6-R1/P2-Bausteine unverändert.
|
||||
- `sprint-status.yaml`: Key `3-3-bestehende-concepts-erweitern-präzisieren-korrigieren` → **in-progress** (bei Implementierung).
|
||||
|
||||
**Ask First:** §5.6-Linkform-Änderung (A0-9) · AD-7d-Renames · Inhalts-Mutation des realen Bundles · Validator-/Vertrags-/`raw/`-Change · Commit-Boundary-Änderung · Leasing-Ausweitung (3.5-Scope).
|
||||
|
||||
**Never:** Änderungen an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/` (AD-3) · neue §7-Invaliditätsklasse · Standalone (D-3) · Duplikat-Anlage eines bestehenden Pfads · „Regenerate Everything" (AD-5/A0-6) · stille Löschung von Provenienz ohne Ersetzungsbeleg (AD-16) · stiller Absatz-Neuschreib (Structure-Preservation-Fall).
|
||||
|
||||
## I/O & Edge-Case Matrix
|
||||
|
||||
| Scenario | Input / State | Expected Output / Behavior | Error Handling |
|
||||
|----------|--------------|---------------------------|----------------|
|
||||
| HAPPY_ERWEITERN | Neue committete Evidenz trägt eine neue belegte Aussage zum bestehenden Concept | **Erweitern:** neue Aussage als Absatz ergänzt (mit §5.5-Inline-Beleg), bestehende Aussagen unverändert; `sources`-Zuwachs um echten neuen Beleg; `at`-Bump; `log.md`-Eintrag „Story 3.1-Update" | NO_MATCH → UNTOUCHED_CONCEPT (keine Mutation) |
|
||||
| HAPPY_PRAEZISIEREN | Evidenz schärft eine bestehende Aussage (präzisierende Information, FR-6/AC-2) | **Präzisieren:** Formulierung/Abgrenzung an der bestehenden Aussage geschärft, Position/Struktur erhalten; Beleg nachgeführt; kein Satz-Umbau/Neuschreib | keine bestehende Aussage als Anker → nicht Präzisieren (ggf. Erweitern) |
|
||||
| HAPPY_KORRIGIEREN | Evidenz ersetzt eine fehlerhafte/überholte Aussage | **Korrigieren:** ersetzte Aussage **nicht still gelöscht**, sondern explizit abgelöst + Ersetzungsbeleg (AD-16-Default Erhaltung) | widersprechender Inhalt ohne Ersetzungsevidenz → bleibt erhalten, Disagreement in `log.md` (Epic-4-Interface) |
|
||||
| NO_OP_KANDIDAT | Evidenz bereits vollständig im Body enthalten | **No-Op:** keine Mutation, kein `at`-Bump, kein `sources`-Zusatz, kein `log.md`-Eintrag — byte-identisch | im Zweifel greift Erweitern/Präzisieren (No-Op = engere Auslegung) |
|
||||
| STRUKTUR_ERHALT | Update greift in Body mit belegten Aussagen + Inline-Verweisen | Struktur unverändert: Subset, Verweise, Linkform; kein unbefugter Key | Verstoß → Update fehlerhaft; Rollback + textuell benannter Verstoß (NFR-4) |
|
||||
| MEHRFACH_TREFFER | Mehrere Einheiten desselben Runs treffen denselben Pfad | Konsolidierung: ein Update, ein `log.md`-Eintrag, ein konsolidierter `sources`-Zuwachs, ein `at` | Reihenfolge = Zuwachs-Sicht; lexikografischer Tie-Break |
|
||||
|
||||
</frozen-after-approval>
|
||||
|
||||
## Code Map
|
||||
|
||||
- `schema/compiler.md` — **primär mutiert** (D-3, einziger Instruktions-Ort):
|
||||
- §5.9 Pkt. 2 (`:261-269`): drei Update-Formen **operationell ausformulieren** (a) Abgrenzungskriterium je Form, (b) Struktur-Erhaltungsregel (Definition „Struktur" + was unverändert bleibt), (c) Textgenauigkeits-Rahmen für Präzisieren. Bestehender Regeltext (Form-Bullets, `sources`-Regel, `at`-Konvention, No-Op, Konsolidierung) bleibt normativ **unverändert** — Schärfung als Ausführungs-Ebene ohne neue Logik.
|
||||
- §5.9 Pkt. 5 (`:272-278`): Erhaltungs-Invariante — Struktur-Erhaltungs-Bezug ergänzen (Diff-Probe erfasst Pfad-Mengen; Struktur pro Pfad über Pkt.-2-Regeln geprüft).
|
||||
- §5.9 Pkt. 6 (`:279-281`): P2-Block — Struktur-Erhaltungs-Check als zusätzliches textuelles Element (keine unbefugten Keys, keine stille Löschung, Links unverändert).
|
||||
- §8 Revisionslog (`:375`): **Revision 2.8** (Story 3.3) mit Abschlussklausel (kein Vertrags-/Validator-/`raw/`-Change, keine §7-Klasse, kein Standalone).
|
||||
- `_bmad-output/implementation-artifacts/sandbox-3-3/run-sandbox.sh` — **neu** (re-executierbar, Muster Story-3.1-Sandbox): Mini-Bundle mit einem Concept + committeter Neuevidenz; alle drei Formen + No-Op durchspielen; Erhaltungs-Invariante als harte Assertion (Diff ⊆ {betroffener Pfad, log}; keine neue Datei; kein Ghost-Diff); Zwei-Run-Identität; Frontmatter-Konformität je mutiertem Concept.
|
||||
- `wiki/log.md` — **append** (append-only, Vertrag §5): Story-3.3-Eintrag (Schärfung, Sandbox-Nachweis, Statuswechsel, Validator-Verdikt); bestehende Bullets unverändert.
|
||||
- `_bmad-output/implementation-artifacts/sprint-status.yaml` — **mutiert**: Key `3-3-…` (`:56`) → `in-progress` (→ `done` bei Story-Abschluss).
|
||||
- `schema/validator.md`, `schema/wiki-compiler.md`, `raw/…` — **read-only** (AD-3). Keine Concept-Inhalts-Mutation (Instruktions-Story; kein neues committetes `raw/`-Material vorhanden — Demonstration per Sandbox).
|
||||
|
||||
## Tasks & Acceptance
|
||||
|
||||
**Execution:**
|
||||
- [x] `schema/compiler.md` — §5.9-Pkt.-2-Update-Formen operationell schärfen (je Form Abgrenzungskriterium + Struktur-Erhaltungsregel + Textgenauigkeits-Rahmen; bestehender Regeltext unverändert) · §5.9-Pkt.-5/-6: Struktur-Bezug + P2-Check-Element · §8 Revision 2.8; ohne Change an `schema/wiki-compiler.md`/`schema/validator.md`/`raw/`.
|
||||
- [x] `sandbox-3-3/run-sandbox.sh` — Update-Run-Demonstrator (Erweitern + Präzisieren + Korrigieren + No-Op), Erhaltungs-Invariante als harte Assertion, Zwei-Run-Identität. **Erweitert um U7 MEHRFACH_TREFFER** (I/O-Matrix-Row, Konsolidierung mehrerer Einheiten auf denselben Pfad) — alle 7 Tests (U1–U7) PASS, Exit 0.
|
||||
- [x] `wiki/log.md` — Story-3.3-Eintrag (Vertrag §5, append-only): Schärfung, Sandbox-Nachweis, Statuswechsel, per-Datei-Validator-Verdikt.
|
||||
- [x] `sprint-status.yaml` — Key `3-3-…` → in-progress.
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- Given eine neue Erkenntnis zu einem bestehenden Concept, when der Run sie verarbeitet, then erweitert er das bestehende Concept anstelle der Anlage einer neuen Datei (AC-1; FR-6) — Erweitern-Regel in §5.9 Pkt. 2, Sandbox belegt sie (keine neue Datei im Diff).
|
||||
- Given eine präzisierende Information, when sie eingearbeitet wird, then wird der Text präzisiert oder korrigiert, ohne die Struktur zu zerstören (AC-2; FR-6) — Struktur-Erhaltungsregel in §5.9 Pkt. 2/5 definiert.
|
||||
- Given eine Aktualisierung, when sie erfolgt, then bleiben Beziehungen und Provenienz soweit weiterhin gültig erhalten (AC-3; FR-6) — Inline-Verweise + Linkform unverändert gültig soweit Beleg Body-Bestand; `sources`-Zuwachs nur um echte neue Belege.
|
||||
- Given die Instruktion, when geprüft, then bleibt `schema/validator.md`/`schema/wiki-compiler.md`/`raw/` unverändert (AD-3), keine neue §7-Klasse, kein Standalone (D-3), kein Leasing-Scope (AC-4 → 3.5/3.6, AD-17.3-Hinweis in §7) — Validator auf Ist-Bundle SUCCESS (7/7 unverändert).
|
||||
|
||||
## Spec Change Log
|
||||
|
||||
*(Append-only — hier von step-04 während der Review-Loops befüllt.)*
|
||||
|
||||
### Review Loop 1 (Step-04, 2026-08-19) — 3 Subagenten (blind-hunter 9, edge-case-hunter 2+Minors, verification-gap 18)
|
||||
|
||||
**Klassifikation (Dedupe → Severity → Route):** High — Verifikations-Lücken des Sandbox-Nachweises (byte-Identität nur Teilmengen-assertiert; Struktur-Ebene/`??`-Sicht nie exerziert; U7 `-le 1`), Form-Abgrenzungs-Überlapp (keine Präzedenz → AD-17h-Gefahr), §5.5-Ankerform (`#S-N` ohne reale Kennung im Rohdokument). Medium — U3-Wortlaut-Mutation der abgelösten Aussage, `last_updated`-Präzisions-Regression, Frontmatter-Prüfung vollständig (Reihenfolge/Duplikat), No-Op-Form-Asymmetrie, „kein neuer normativer Inhalt" vs. Pkt.-5/6-Änderung, at↔AD-17h-Gap-Kreuzreferenz. Low — Diff-Artefakt-Pfade, Spec-Change-Log leer (per Konvention erst jetzt befüllt).
|
||||
|
||||
**Ergebnis: kein intent_gap, kein bad_spec** (kein Loopback) — **patch** (auto-fixiert, s. Diff): §5.9 Pkt.-2-Operationelle-Ebene — Präzedenz-Reihenfolge `Korrigieren → Präzisieren → Erweitern → No-Op` + Überlapp-Bindung + No-Op als Nicht-Form + at↔AD-17h-Kreuzreferenz; Korrigieren-Struktur-Erhaltung — Original-Wortlaut bleibt als abgelöster Bestand erhalten; Sandbox — U1/U2/U3 byte-Identität auf alle drei Aussagen erweitert, U8 (unbefugter Frontmatter-Key → Struktur-HARD-FAIL) + U9 (ungetrackte neue Datei → `??`-Sicht-HARD-FAIL) neu, U7 `-le 1` → `-eq 1` + beide raw/-Quellen im konsolidierten log-Eintrag, assert_frontmatter um canoniche Reihenfolge + Duplikat-Prohibition erweitert, reale `S-N`-Anker in allen raw/-Evidenzdateien (§5.5), U3-Wortlaut nicht mehr verändert. **defer** (append-only `deferred-work.md`): `last_updated`-Präzision (sync-sprint-status-General), „Schärferung/Formata"-Typos (frozen Story-3.1-Text), „auch nach Commit"-Überzeichnung + at↔AD-17h-Gap-Kreuzreferenz (Home Story 3.8), U2-Selbsterfüllung + Zuwachs-Sicht-vs-lexikografisch-Rationale (Form-Wahl-Prüfung als Verfahren), Em-Dash/Umlaut-Normalisierung im Sandbox-Evidenztext. **reject:** U6-SHA-Reproduzierbarkeit von log.md (random baseline-SHA ist konstruktionsbedingt), Diff-Artefakt-Pfad-Präfix (nur Verbrauchskontext), Spec-Change-Log „leer" (per Konvention erst während Review-Loops befüllt).
|
||||
|
||||
## Design Notes
|
||||
|
||||
**Warum Ergänzung, nicht Umbau:** Die Story-3.3-Schärfung ist ein Ausführungs-Sub-Block an Pkt. 2 — sie definiert die offene Frage „Was tue ich konkret bei jedem Form-Fall, und was lasse ich unangetastet?" als deterministische Brücke Regel → Run (AD-17h): dieselbe Evidenz + formale Struktur → identisches Update-Ergebnis. Der frozen Story-3.1-Regeltext bleibt unverändert; die operationellen Regeln werden als Präzisierungsebene darunter angefügt (keine Re-Negotiation).
|
||||
|
||||
**Struktur-Definition (das Geschützte):** (1) Frontmatter (Subset + canonische Reihenfolge; zulässig: `sources`-Zuwachs, `at`-Bump; kein neuer Key, keine Entfernung ohne Beleg); (2) bestehende belegte Aussagen mit §5.5-Inline-Verweisen (nicht umgeschrieben ohne dass Präzisieren/Korrigieren greift); (3) Linkzeichen §5.6-Pin (kein Linkumbau bei reinem Body-Update). Das ist die Bedeutung von „ohne die Struktur zu zerstören" (FR-6/AC-2).
|
||||
|
||||
**Abgrenzungskriterium (aus der Evidenz):** (a) belegte Aussage existiert im Body nicht → Erweitern; (b) schärft bestehende Formulierung/Abgrenzung ohne Ersatz → Präzisieren; (c) ersetzt eine bestehende als fehlerhaft/überholt → Korrigieren; (d) nichts davon → No-Op. Unschärfe → zugunsten Erweitern/Präzisieren (No-Op = engere Auslegung, bestehende §5.9-Regel).
|
||||
|
||||
## Verification
|
||||
|
||||
**Commands (re-executierbar, ab Workspace-Root):**
|
||||
1. `bash _bmad-output/implementation-artifacts/sandbox-3-3/run-sandbox.sh` — expected: alle Szenarien mit harten Pass/Fail-Assertionen, Erhaltungs-Invariante erzwungen, Exit 0.
|
||||
2. `grep -n "Struktur-Erhaltungsregel\|operationelle\|Revision 2.8" schema/compiler.md` — liefert die operationellen Regeln + Revisionslog.
|
||||
3. Read-only (AD-3): `git status --porcelain` zeigt keinen Change an `schema/validator.md`/`schema/wiki-compiler.md`/`raw/`.
|
||||
4. Validator-Lauf: alle `wiki/`-Dateien SUCCESS (unverändert, keine Inhalts-Mutation).
|
||||
|
||||
**Manual checks:**
|
||||
- §5.9 Pkt. 2 trägt Abgrenzungskriterium + Struktur-Erhaltungsregel + Textgenauigkeits-Rahmen; bestehender Regeltext unverändert; §8-Rev-2.8 mit Abschlussklausel; kein `validator.md`/`wiki-compiler.md`/`raw/`-Diff; §7 ohne neuen Platzhalter (Update-Thema entlassen, AC-4-Leasing an 3.5/3.6); `wiki/log.md`-Eintrag datiert mit Story-3.3-Semantik + Sandbox-Nachweis + Statuswechsel + Verdikt; `sprint-status.yaml` konsistent.
|
||||
|
||||
## Suggested Review Order
|
||||
|
||||
**Abgrenzungs-Mechanik der Update-Formen (Kern)**
|
||||
|
||||
- Einstieg: die neue operationelle Ausführungs-Ebene — Präzedenz-Reihenfolge Korrigieren → Präzisieren → Erweitern → No-Op, deterministische Form-Wahl (AD-17h/A0-19), No-Op als Nicht-Form.
|
||||
[`compiler.md:270`](../../schema/compiler.md#L270)
|
||||
|
||||
- Korrigieren schützt den abgelösten Original-Wortlaut (AD-16-Default, keine stille Löschung).
|
||||
[`compiler.md:271`](../../schema/compiler.md#L271)
|
||||
|
||||
- Präzisieren: Schärfen an der Aussage selbst, kein Satz-Umbau; No-Op-Erhaltungsregel volle Byte-Identität.
|
||||
[`compiler.md:272`](../../schema/compiler.md#L272)
|
||||
|
||||
**Struktur-Erhaltungs-Invariante + P2-Check**
|
||||
|
||||
- Die Pfad-Probe verifiziert jetzt zwei Ebenen — Menge + Struktur je berührtem Pfad (FR-6/AC-2).
|
||||
[`compiler.md:283`](../../schema/compiler.md#L283)
|
||||
|
||||
- P2-Check-Block-Element (6): keine unbefugten Keys, keine stille Löschung, Linkform-Pin.
|
||||
[`compiler.md:287`](../../schema/compiler.md#L287)
|
||||
|
||||
- Revisionslog Revision 2.8 mit Abschlussklausel (kein Vertrags-/Validator-/`raw/`-Change).
|
||||
[`compiler.md:382`](../../schema/compiler.md#L382)
|
||||
|
||||
**Re-executierbarer Sandbox-Nachweis**
|
||||
|
||||
- U8: unbefugter Frontmatter-Key löst die Struktur-Ebene-HARD-FAIL aus — Negativ-Kontrolle der Kern-Invariante.
|
||||
[`run-sandbox.sh:365`](./sandbox-3-3/run-sandbox.sh#L365)
|
||||
|
||||
- U9: ungetrackte neue Datei wird über die `??`-Sicht erkannt (Duplikat-Kontrolle).
|
||||
[`run-sandbox.sh:378`](./sandbox-3-3/run-sandbox.sh#L378)
|
||||
|
||||
- U7: Konsolidierung mehrerer Einheiten auf einen Pfad — ein log-Eintrag, beide raw/-Quellen verlinkt.
|
||||
[`run-sandbox.sh:320`](./sandbox-3-3/run-sandbox.sh#L320)
|
||||
|
||||
- assert_frontmatter: canoniche Reihenfolge + Duplikat-Prohibition (Vertrag §3.3/§3.4-Subset).
|
||||
[`run-sandbox.sh:118`](./sandbox-3-3/run-sandbox.sh#L118)
|
||||
|
||||
**Provenienz & Status**
|
||||
|
||||
- Review-Loop-1-Bullet: Klassifikation, Patches, Defers, Rejects; Spec-Status `in-review`.
|
||||
[`log.md:4`](../../wiki/log.md#L4)
|
||||
|
||||
- Defer-Einträge (5) inkl. Home Story 3.8 für at↔AD-17h-Gap und Normalisierungs-Lücken.
|
||||
[`deferred-work.md:9`](./deferred-work.md#L9)
|
||||
|
||||
- Sprint-Status Key `3-3-…`: Review-Abschluss-Flip auf `done`.
|
||||
[`sprint-status.yaml:56`](./sprint-status.yaml#L56)
|
||||
@@ -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 13:14
|
||||
last_updated: 08-19-2026 13:21
|
||||
project: wow20
|
||||
project_key: NOKEY
|
||||
tracking_system: file-system
|
||||
@@ -53,7 +53,7 @@ development_status:
|
||||
epic-3: in-progress
|
||||
3-1-inkrementellen-datenfluss-implementieren-interpret-reconcile: done
|
||||
3-2-relevanzbestimmung-textual-deterministisch-umsetzen-grep-rip: done
|
||||
3-3-bestehende-concepts-erweitern-präzisieren-korrigieren: backlog
|
||||
3-3-bestehende-concepts-erweitern-präzisieren-korrigieren: done
|
||||
3-4-wissen-aus-mehreren-sources-synthetisieren: backlog
|
||||
3-5-leasing-dirty-tree-schutz-für-konkurrierende-producer-umsetz: backlog
|
||||
3-6-lease-staleness-recovery-basis-absichern: backlog
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user