Compare commits
8
Commits
story-3-7
...
8c43d3a09c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c43d3a09c | ||
|
|
73f2c9e71d | ||
|
|
2f079ee3c8 | ||
|
|
73d19cbcea | ||
|
|
96661836e9 | ||
|
|
1c116751d6 | ||
|
|
5a78271f89 | ||
|
|
39471d9422 |
@@ -486,3 +486,75 @@ Noch nicht adressierte, aber real erkannte Arbeit — gesammelt aus Reviews. Ein
|
||||
|
||||
- Bezug: §5.9 Pkt. 2/§5.7 Misch-Runs (Neu-Anlage + Update im selben Run) sind in der CONSIST-Sandbox ab Review-Loop-2 im CONSIST-2 abgedeckt (Neu-Anlage `delta` + Update `alpha`, Plan-Freeze-Menge + Voll-Rollback, Neu-Anlage-Absenz nach Rollback); übrige Phasen-/Synthese-Misch-Formen bleiben Home Story 3.8 (Determinismus-Vertrag AD-17h als Agent-Instruktions-Validator, inkl. A0-20-Post-Zustand-Test).
|
||||
- status: delokalisiert (Home: Story 3.8)
|
||||
|
||||
## Deferred from: code review of spec-3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validator (Story 3.8, 2026-08-20)
|
||||
|
||||
### Aufgegriffen: Em-Dash-Varianten-Lücke der Normalisierung (Story-3.2-Defer, Home Story 3.8) — Story 3.8, 2026-08-20
|
||||
|
||||
- Bezug: Defer «Em-Dash-"—"-Varianten-Lücke der Normalisierung» (Defer-Block „Deferred from: Story 3.2", Eintrag 1; `status: offen (Home: Story 3.8)`).
|
||||
- Umsetzung: `schema/compiler.md` §3.2 Pkt. 1b „Geschlossene Determinismus-Lücken (Story 3.8)": die Kollaps-Klasse ist um den Em-Dash `—` ergänzt (`[-–— _]` → `-`) — En-Dash, Em-Dash, Bindestrich, Unterstrich, Leerzeichen kollabieren identisch auf genau einen Bindestrich. Verankerung: §5.14 Pkt. 5 verweist auf §3.2-Pkt.-1b. Kein stiller Ausschluss; append-only-Regel-Ergänzung, bestehender §3.2-Wortlaut unverändert.
|
||||
- Sandbox-Nachweis: `_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh` DET-5 (Em-Dash → identische canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen) — Exit 0.
|
||||
- status: aufgegriffen (Home erledigt in §3.2 Pkt. 1b / §5.14 Pkt. 5)
|
||||
|
||||
### Aufgegriffen: Kollaps-Reichweite bei Läufen/führenden/trailenden Separatoren (Story-3.2-Defer, Home Story 3.8) — Story 3.8, 2026-08-20
|
||||
|
||||
- Bezug: Defer «§3.2-Pkt.-1b-ii: Kollaps-Reichweite bei aufeinanderfolgenden/führenden/trailenden Separatoren unbestimmt» (Defer-Block „Deferred from: code review of spec-3-2…", Eintrag 2).
|
||||
- Umsetzung: `schema/compiler.md` §3.2 Pkt. 1b „Geschlossene Determinismus-Lücken": Kollaps-Reichweite deterministisch — jedes Separator-Vorkommen kollabiert auf genau ein `-`; Läufe (`a--b` → `a-b`); führende (`-x` → `x`) und trailende (`x-` → `x`) Separatoren werden getrimmt. Verankerung §5.14 Pkt. 5; die in der Sandbox etablierte Semantik wird normativ fixiert.
|
||||
- Sandbox-Nachweis: DET-6 (Läufe `a--b`, führende `-x`, trailende `x-`, Kombination `---x---` → `x`) — Exit 0.
|
||||
- status: aufgegriffen (Home erledigt in §3.2 Pkt. 1b / §5.14 Pkt. 5)
|
||||
|
||||
### Aufgegriffen: Match-Scope der Stufe a (Wortgrenzen, Frontmatter-exklusiv) (Story-3.2-Defer, Home Story 3.8) — Story 3.8, 2026-08-20
|
||||
|
||||
- Bezug: Defer «§3.2-Pkt.-2a: Wortgrenzen-/Frontmatter-Scope der Stufe-a-Match-Semantik ist offen» (Defer-Block „Deferred from: code review of spec-3-2…", Eintrag 1).
|
||||
- Umsetzung: `schema/compiler.md` §3.2 Pkt. 1b „Geschlossene Determinismus-Lücken" (c) Match-Scope der Stufe a: Stufe a matcht ganze Wörter (Wortgrenzen) über den Body, exklusive YAML-Frontmatter — Substring- und Frontmatter-Treffer (z. B. in `sources[].resource`/`generated.by`) liefern keine Kandidaten (deterministischer Stufe-a-Scope). Verankerung §5.14 Pkt. 5.
|
||||
- Sandbox-Nachweis: DET-7 (ganzes Wort trifft alpha; Substring `opplung` und Frontmatter-only-Kandidat `mirror` liefern keine Kandidaten) — Exit 0.
|
||||
- status: aufgegriffen (Home erledigt in §3.2 Pkt. 1b / §5.14 Pkt. 5)
|
||||
|
||||
### Aufgegriffen: Orphan-Kontrolle als deterministische Reconcile-Orphan-Regel (Story-3.4-Defer, Home Story 3.8) — Story 3.8, 2026-08-20
|
||||
|
||||
- Bezug: Defer «Orphan-Kontrolle (§5.10 Pkt. 8) textuell verankert, aber nicht in der Sandbox demonstriert» (Defer-Block „Deferred from: code review of spec-3-4…", Eintrag 2; `status: offen (Home: Story 3.8)`).
|
||||
- Umsetzung: `schema/compiler.md` §5.10 Pkt. 8 „Deterministische Reconcile-Orphan-Regel (Story 3.8; §5.14-Präzisierung)": Verwaist-Befund deterministisch aus dem committeten Git-State (Zuwachs gg. `<Baseline-Commit>`, §5.9 Pkt. 6 R-1); datumsgruppierter `log.md`-Eintrag (Header `YYYY-MM-DD`, neueste zuerst; Quell-Pfad + `<Baseline-Commit>`); kein Banner/keine stille Vorbearbeitung/keine eigenständige Anlage (AD-16-Default, Epic-4-Interface). Verankerung §5.14 Pkt. 5.
|
||||
- Sandbox-Nachweis: DET-8 (verwaiste `raw/`-Evidenz ohne Ziel-Pfad-Treffer → unzugeordnet, `log.md`-Verwaist-Eintrag mit `<Baseline-Commit>`, kein Banner, keine eigenständige Anlage, Erhaltungs-Invariante nur `log.md`) — Exit 0.
|
||||
- status: aufgegriffen (Home erledigt in §5.10 Pkt. 8 / §5.14 Pkt. 5)
|
||||
|
||||
### Aufgegriffen: generated.at↔AD-17h-Gap & Zwei-Run-Identitäts-Nachweis (Story-3.3-Defer, Home Story 3.8) — Story 3.8, 2026-08-20
|
||||
|
||||
- Bezug: Defer «U6-Zwei-Run-Identitäts-Nachweis … kreuzreferenziert den generated.at↔AD-17h-Gap nicht» (Defer-Block „Deferred from: code review of spec-3-3…", Eintrag 3; `status: offen (Home: Story 3.8)`).
|
||||
- Umsetzung: `schema/compiler.md` §5.14 Pkt. 1 (Bundle-State-Definition: `generated.at`/`verified[].at` als benannte Ausnahme der Projektion), Pkt. 3 (Ausnahme-Menge: allein der `generated.at`-Wanduhr-Gap; alle übrigen Bestandteile byte-identisch) und Pkt. 2 (Zwei-Run-Mechanik: identische Plan-/Kandidaten-/Reihenfolge-Outputs und byte-identische mutierte Bundle-Bestandteile bis auf die `at`-Ausnahme). Der A0-20-Wanduhr-Gap bleibt verhaltens-seitig unverändert (Ask-First bei Verhaltens-Wechsel).
|
||||
- Sandbox-Nachweis: DET-2 (Zwei-Run-Identität nicht-vakuum, echte Content-Hashes) + DET-4 (at-Gap-Ausnahme: diff ausschließlich auf der at-Zeile, nach at-Maskierung byte-identisch; Negativkontrolle Body-Differenz = AD-16-Defekt) — Exit 0.
|
||||
- status: aufgegriffen (Home erledigt in §5.14 Pkt. 1–3)
|
||||
|
||||
### Aufgegriffen: A0-20-Post-Zustand-Negativkontrolle in der Sandbox (Story-3.7-Defer, Home Story 3.8) — Story 3.8, 2026-08-20
|
||||
|
||||
- Bezug: Defer «A0-20-Post-Zustand-Negativkontrolle in der Sandbox fehlt … Home: Story 3.8 (A0-20-Home)» (Defer-Block „Deferred from: code review of spec-3-7…", Eintrag 2).
|
||||
- Umsetzung: §5.14 Pkt. 3 definiert die Ausnahme-Menge des Bundle-State-Vergleichs (allein der `generated.at`-Wanduhr-Gap; jede andere Differenz außerhalb der Ausnahme = AD-16-Klassifikationsdefekt, Pkt. 4, textuell benannt NFR-4). Der Post-Zustand wird damit über die Zwei-Run-Mechanik (Pkt. 2) einschließlich at-Handhabung instruiert; die Sandbox demonstriert den Gap positiv und negativ.
|
||||
- Sandbox-Nachweis: DET-4 (positiv: zwei Runs mit unterschiedlichen `at` → diff nur at-Zeile, nach Maskierung byte-identisch; negativ: Body-Differenz → AD-16-Klassifikationsdefekt) — Exit 0.
|
||||
- status: aufgegriffen (Home erledigt in §5.14 Pkt. 2–4)
|
||||
|
||||
### Aufgegriffen: Misch-Run-Coverage Determinismus-Vertrag (Story-3.7-Delokalisierung, Home Story 3.8) — Story 3.8, 2026-08-20
|
||||
|
||||
- Bezug: Delokalisierung «Misch-Run-Coverage Neu-Anlage+Update in der Story-3.7-Sandbox … übrige Phasen-/Synthese-Misch-Formen bleiben Home Story 3.8 (Determinismus-Vertrag AD-17h als Agent-Instruktions-Validator, inkl. A0-20-Post-Zustand-Test)» (Block „### Delokalisierung …", `status: delokalisiert (Home: Story 3.8)`).
|
||||
- Umsetzung: Der Determinismus-Vertrag wird als geschlossene Bestätigungs-Mechanik in §5.14 verankert (Bundle-State-Projektion, Zwei-Run-Bestätigung, at-Ausnahme, Abweichungs-Klassifikation); die §5.13-Determinismus-Nachweise bleiben unverändert, die at-A0-20-Konvention ist auf die §5.14-Pkt.-3-Ausnahme-Menge verlagert (§5.13 Pkt. 7 Seam).
|
||||
- Sandbox-Nachweis: DET-1..DET-4 (Bundle-State-Definition, Zwei-Run-Identität, Abweichungs-Klassifikation, at-Gap-Ausnahme) — Exit 0.
|
||||
- status: aufgegriffen (Home erledigt in §5.14)
|
||||
|
||||
### Aufgegriffen (teilweise): Gemischte Normalisierungs-Politik Umlaute vs. Transkription — Em-Dash-Anteil (Story-3.3/Story-3.4-Defers, Home Story 3.8) — Story 3.8, 2026-08-20
|
||||
|
||||
- Bezug: Defer «Gemischte Normalisierungs-Politik im Sandbox-Evidenztext (Umlaute vs. Transkriptionen) ist ein Determinismus-Hazard für den Term-Abgleich» (Defer-Block „Deferred from: code review of spec-3-3…", Eintrag 5, `status: offen (Home: Story 3.8)`) und Defer «Sandbox-Evidenztexte transkribieren Umlaute, die Concept-Bodies nutzen Umlaut-Schreibweisen» (Defer-Block „Deferred from: code review of spec-3-4…", Eintrag 3, `status: offen (Home: Story 3.8)`).
|
||||
- Umsetzung: Der Em-Dash-Anteil beider Einträge ist in `schema/compiler.md` §3.2 Pkt. 1b / §5.14 Pkt. 5 geschlossen (Em-Dash in der Kollaps-Klasse `[-–— _]` → `-`). Der Umlaut-vs-Transkription-Anteil bleibt offen: die §3.2-Normalisierung (lowercasing + Kollaps-Klasse) deckt Umlaut-Divergenzen („Schlüssel" vs. „Schluessel") weiterhin nicht ab — kein neuer Normalisierungs-Schritt in Story 3.8 (kein neuer Regel-Operand, D-3/append-only).
|
||||
- Sandbox-Nachweis: DET-5 (Em-Dash-Anteil) — Exit 0.
|
||||
- status: teilweise aufgegriffen (Em-Dash-Anteil geschlossen in §3.2 Pkt. 1b / §5.14 Pkt. 5; Umlaut-vs-Transkription-Divergenz bleibt offen — Home: Sandbox-Vereinheitlichung oder folgende Compiler-Instruktions-Revision; kein Instruktions-Defekt)
|
||||
|
||||
## Deferred from: code review of spec-3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato (2026-08-20)
|
||||
|
||||
- **Sandbox-Härtungs-Guards (8 Befunde):** `mktemp` (Z. 37), `git init` (Z. 41), Baseline-Commit (Z. 94-96), `isolate()`-Sequenz (Z. 104-107), fehlende Match-Datei (Z. 136-141), verwaiste unregistrierte Worktree-Verzeichnisse (Z. 243-244) und Porcelain-Pfade mit Leerzeichen (`awk '{print $2}'`, Z. 217/682) tragen keine Fehler-Guards; ein Fehlgeschlagener init-Schritt lässt einen späteren „PASS" auf kaputtem Zustand drucken. — Defer-Grund: Testharness-Robustheit, keine normative Instruktion-Semantik; Re-Run-Risiko dokumentiert. Home: nächste Sandbox-Revision. — status: offen
|
||||
- **DET-1/DET-2-Plan-/Form-Literale vs. AC-5 „nicht hart codiert":** `plan=$(printf 'cand=alpha;form=update;baseline=%s')` (run-sandbox.sh:189) und `echo "form=update"` in `bs_a()` (Z. 221) sind wörtliche Skript-Konstanten; B1==B2-Identität damit trivial. — Defer-Grund: Loop-1-/Loop-2-Präzedenz (Loop-1 hat „DET-2-Plan-Literal (dev-demo, echte Content-Hashes decken)" rejected; DET-1 trägt den Demo-Kommentar Z. 211-214); die Nicht-Vakuum-Assertion tragen die echten Content-Hashes. Home: Story-3.13-Abnahme (echte Gate-Runs über die Instruktion). — status: offen
|
||||
- **`norm()`-Locale-Pinning (`LC_ALL`) fehlt:** unter C/POSIX-Locale zerfällt die Byte-Klasse `[–—]` in {E2,80,93,94} (übermatcht z. B. `…`/`„`), `tr 'A-Z' 'a-z'` ist locale-abhängig → die Kanon-Form hängt am Host-Locale statt am committeten Git-State. — Defer-Grund: Testharness-Host-Locale-Abhängigkeit (Host = Ubuntu-Sandbox, dort UTF-8-Default; auf C-Locale-Hosts falsch), keine normative Semantik der Instruktion. Home: Sandbox-Härtung (gemeinsam mit den Hards-Guards). — status: offen
|
||||
- **Mehrfach-Term-Vereinigung unübend:** §3.2 Pkt. 1c/§5.14 Pkt. 5 pinnen die Vereinigung der Treffer über alle Terme (besuchte Menge, Zuwachs-Sicht-Ordnung) als „vollständig pinbar" — die Sandbox übt nur den Einzel-Term-Pfad; eine Regressions in Union-/Dedup-/visited-Set-Logik würde unbemerkt durchgehen. — Defer-Grund: Story-3.8-Scope (Bestätigungs-Mechanik + Lückenschließung) ist erfüllt; ausführbare Union-Coverage gehört zur deterministischen Term-Gewinnung/Routing. Home: Story 3.9. — **status: offen → aufgegriffen (Story 3.9, 2026-08-20):** in `schema/compiler.md` §5.15 Pkt. 1 verankert (Mehrfach-Term-Vereinigung D-8: kollabierter Gesamt-Name als primärer Term + jedes ≥2-Zeichen-Segment als weiterer Term; Einzelzeichen-Segmente -a/-b tragen keinen eigenen Term); Sandbox R-1 übt die Vereinigung real aus (`beta-kommunikation` → `beta beta-kommunikation kommunikation`, Sidecar-exkludiert, Diff↔Manifest-Äquivalenz)
|
||||
- **Orphan-Term hand-gesteuert + feste 2-Datei-Scan:** DET-8 pinnen den Term `fremdes` und scannen nur `wiki/alpha.md wiki/gamma.md` (run-sandbox.sh:669); die Determinismus der Orphan-ermittlung (Term-Ableitung aus dem `raw/`-Zuwachs, voller Kandidaten-Scan über Stufen a/b/c) ist nicht ausgeübt — nur die Log-Seite wird hart assertiert. — Defer-Grund: Mechanik ist textuell korrekt (DET-8-Assertions Z. 688-692 solide); Term-Derivation ist Story-3.9-AC („geschlossener, geordneter Algorithmus oder persistiertes Term-Manifest"). Home: Story 3.9. — **status: offen → aufgegriffen (Story 3.9, 2026-08-20):** Sandbox R-5 leitet die Terme AUS dem committeten `raw/`-Zuwachs ab (`git diff --name-only HEAD~1 -- raw/`, Dateiname→Term) und scannt **Stufe a** über den Root-`wiki/*.md`-Glob statt eines festen 2-Datei-Scans — Orphan-/CREATE-Term-Derivation auf der Stufe-a-Ebene mechanisch ausgeübt (D-9; §5.15 Pkt. 1). **Scope-Präzisierung (Loop-3, 2026-08-21):** die ausgeübte Termination-Derivation + Scan beschränkt sich auf **Stufe a über den Root-`wiki/*.md`-Glob** (keine Area-Rekursion, keine Stufen b/c); die volle Stufen-b/c-Traversal-Coverage des Kandidaten-Baums bleibt verbleibend offen (Home: Story 3.13-Abnahme / Sandbox-Härtung — benannter Defer, keine instruktionsseitige Lücke, §5.15 Pkt. 2/3 verankern die Stufen)
|
||||
- **Umlaut-vs-Transkription im Match-Pfad unübend:** die §3.2-Normalisierung deckt Umlaut-Divergenzen („Schlüssel" vs. „Schluessel") nicht ab, und kein DET-Szenario treibt einen Umlaut-Term durch den Match-Pfad. — Defer-Grund: bereits „Aufgegriffen (teilweise)" dokumentiert (Block oben, Home: Sandbox-Vereinheitlichung oder folgende Compiler-Instruktions-Revision; „kein Instruktions-Defekt") — keine neue offene Frage, nur fehlende Sandbox-Abdeckung. Home: wie dort. — status: offen
|
||||
|
||||
## Deferred from: code review of spec-3-9-deterministische-relevanz-und-reconcile-routing-schliessen (2026-08-21)
|
||||
|
||||
- **`norm()`/`tr` ohne `LC_ALL`-Pinning (Sandbox-3.9, 952 Zeilen):** unter C/POSIX-Locale zerfällt die Byte-Klasse `[–—]` in {E2,80,93,94} (übermatcht z. B. `…`/`„`), `tr 'A-Z' 'a-z'` ist locale-abhängig → die Kanon-Form hängt am Host-Locale statt am committeten Git-State. — Defer-Grund: bekannter Story-3.8-Defer (D-7, Block oben „`norm()`-Locale-Pinning fehlt"), hier in den Sandbox-3.9-Scope ausgeweitet (alle R-Szenarien + R-9-Worktree-Läufe laufen auf derselben `norm()`); keine normative Instruktion-Semantik (Instruktion nennt Kollaps-Klasse + lowercasing, keine Locale-Bindung). Home: Sandbox-Härtung (gemeinsam mit den Story-3.8-Hard-Guards). — status: offen
|
||||
- **Positive Zwei-Run-Identität strukturell trivial (R-9 clean A==B):** Plan-/Form-/Routing-Literale der `run9_worktree()`-Receipts sind Skript-Konstanten; die A==B-Identität folgt daraus, nicht aus realer Ausführung; die Nicht-Vakuum-Last tragen die echten Content-Hashes (Bundle-BYTE-Vergleich) und die Negativ-Kontrolle (divergent ≠ clean, hart FAIL). — Defer-Grund: Präzedenz Story-3.8-Defer „DET-1/DET-2-Plan-/Form-Literale vs. AC-5 „nicht hart codiert"" (Block oben, Home: Story-3.13-Abnahme, echte Gate-Runs über die Instruktion); Story-3.9-Sandbox folgt demselben Demo-Muster. Home: Story-3.13-Abnahme. — status: offen
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## Goal
|
||||
|
||||
Der Compiler verarbeitet neues Source Material gegen das bestehende Knowledge Bundle, statt es bei jedem Lauf aus sämtlichen Rohquellen neu aufzubauen (Compounding Knowledge). Bestehende Concepts werden durch neue Erkenntnisse erweitert, präzisiert oder korrigiert; Informationen aus mehreren Sources werden zu einer gemeinsamen Wissensrepräsentation mit gemischter, claim-granularer Provenienz synthetisiert; unverändertes Wissen bleibt erhalten. Die Relevanzbestimmung ("welche bestehenden Concepts sind betroffen") ist textual-deterministisch (grep/ripgrep, Markdown-Traversal, Link-Following) — ohne Embedding- oder Vector-Infrastruktur. Konkurrierende Producer koordinieren sich über ein leasing-/branch-basiertes Workspace-Modell mit Root-Scope-Lease und Dirty-Tree-Schutz; Mutationen sind commit-gebunden, und jeder Run endet in einem konsistenten, über denselben Git-State reproduzierbaren Bundle (AD-5, AD-6, AD-13, AD-17a..h).
|
||||
Der Compiler verarbeitet neues Source Material gegen das bestehende Knowledge Bundle, statt das Wiki bei jedem Lauf aus sämtlichen Rohquellen neu aufzubauen (Compounding Knowledge). Bestehende Concepts werden durch neue Erkenntnisse erweitert, präzisiert oder in eindeutig belegten Fällen korrigiert; mehrere Sources werden zu einer gemeinsamen Wissensrepräsentation mit gemischter, claim-granularer Provenienz synthetisiert; unverändertes Wissen bleibt erhalten. Relevanzbestimmung und Reconcile-Routing sind textual-deterministisch ohne Embedding- oder Vector-Infrastruktur. Konkurrierende Producer koordinieren sich über eine atomare Root-Scope-Lease mit transaktionalem Dirty-Tree-, Rollback- und Release-Lifecycle. Klassifikationspflichtige Kollisionen und Widersprüche werden bis Epic 4 fail-closed als strukturierter Hold erhalten; der Determinismus-Vertrag wird mechanisch qualifiziert. Epic 3 gilt erst nach einem realen, unabhängigen Source→Compilation→Wiki-Abnahmegate als abgeschlossen (AD-5, AD-6, AD-13, AD-17a/b/d–h, A0-6/7/12–16/18/19).
|
||||
|
||||
## Stories
|
||||
|
||||
@@ -16,35 +16,39 @@ Der Compiler verarbeitet neues Source Material gegen das bestehende Knowledge Bu
|
||||
- Story 3.6: Lease-Staleness & Recovery-Basis absichern
|
||||
- Story 3.7: Reason/Mutate-Trennung und Konsistenz-Endzustand sicherstellen
|
||||
- Story 3.8: Determinismus-Vertrag (AD-17h) als Agent-Instruktions-Validator umsetzen
|
||||
- Story 3.9: Deterministische Relevanz- und Reconcile-Routing schließen
|
||||
- Story 3.10: Inkrementelle Update- und Synthese-Erhaltung absichern
|
||||
- Story 3.11: Root-Scope-Leasing atomar und worktree-übergreifend akquirieren
|
||||
- Story 3.12: Lease-Lifecycle und Commit-Abschluss transaktional schließen
|
||||
- Story 3.13: Epic-3-Verifikations- und Abnahmegate
|
||||
|
||||
## Requirements & Constraints
|
||||
|
||||
- Ein Compilation Run nimmt neues Source Material und das bestehende Wiki als Input; das Wiki wird inkrementell weiterentwickelt, nie vollständig regeneriert. Unverändertes Wissen bleibt erhalten; Git-Änderungen konzentrieren sich auf die durch die neue Erkenntnis betroffenen Concepts (FR-4, FR-12).
|
||||
- Neue Informationen führen nicht automatisch zu neuen Dateien: bestehende Concepts werden erweitert, präzisiert oder korrigiert, ohne ihre Struktur zu zerstören; Beziehungen und Provenienz bleiben soweit weiterhin gültig erhalten (FR-6).
|
||||
- Mehrere Sources zum selben Thema münden in eine gemeinsame Wissensrepräsentation statt getrennter Zusammenfassungen. Das Ergebnis reflektiert den erkannten Wissensstand, konsolidiert Redundanzen und übernimmt die relevante Source-Provenienz der beteiligten Sources (FR-7, AD-4).
|
||||
- Unvollständiges, ungeprüftes oder teilweise widersprüchliches Wissen wird dargestellt, ohne künstliche Gewissheit zu erzeugen (NFR-7).
|
||||
- Relevanzbestimmung und Merges sind textual-deterministisch; Embeddings, Vector-Search, Knowledge-Graph-DB und RAG gehören nicht in den Compiler-Kern (AD-13, AD-17h, PRD-No-Goals).
|
||||
- Ein Compilation Run nimmt neues Source Material und das bestehende Wiki als Input; das Wiki wird inkrementell weiterentwickelt, nie vollständig regeneriert. Unverändertes Wissen und nicht betroffene Concepts bleiben erhalten; Git-Änderungen konzentrieren sich auf die durch die neue Erkenntnis betroffenen Concepts (FR-4, FR-12, AD-5).
|
||||
- Neue Informationen führen nicht automatisch zu neuen Dateien: bestehende Concepts werden erweitert, präzisiert oder korrigiert, ohne ihre Struktur zu zerstören; weiterhin gültige Beziehungen und Provenienz bleiben erhalten (FR-6).
|
||||
- Mehrere Sources zum selben Thema münden in eine gemeinsame Wissensrepräsentation statt getrennter Zusammenfassungen. Das Ergebnis reflektiert den erkannten Wissensstand, konsolidiert Redundanzen und übernimmt die relevante Source-Provenienz der beteiligten Sources — claim-granular (FR-7, AD-4, A0-3).
|
||||
- Relevanzbestimmung, Routing, Planung und nicht-konfligierende Mutationen sind textual-deterministisch (grep/ripgrep, Markdown-Traversal, Link-Following). Embeddings, Vector-Search, Knowledge-Graph-Datenbank und RAG gehören nicht in den Compiler-Kern (AD-13, A0-18).
|
||||
- Ein Run verwendet ausschließlich veröffentlichte (committete) Inhalte als Input, nie Zwischenstände während der Mutation (AD-17).
|
||||
- `raw/` bleibt immutable und dient als Recovery-Basis; ein fehlgeschlagener Run verändert es nicht (AD-3).
|
||||
- Unvollständiges, ungeprüftes oder widersprüchliches Wissen wird ohne künstliche Gewissheit dargestellt; klassifikationspflichtige Konflikte werden bis Epic 4 ohne Wissensmutation in einem benannten Hold erhalten (NFR-7).
|
||||
|
||||
## Technical Decisions
|
||||
|
||||
- **Inkrementeller Datenfluss (AD-5, A0-6):** Interpret → Reconcile → Synthesize → Update affected Concepts. Startpunkt ist immer das bestehende Bundle — niemals "Regenerate Everything" aus allen Rohquellen. Validiert durch die Incrementality-Anforderung (SM-1, FT-6).
|
||||
- **Reason/Mutate-Trennung (AD-6, A0-7):** Logische Phasen Analyse → Reconcile → Plan Changes → Mutate → Validate. Keine eigene Workflow Engine; ein Agent kann die Phasen in einer Session durchführen, der beobachtbare Endzustand des Bundles muss bei Abbruch konsistent sein.
|
||||
- **Deterministische Relevanzbestimmung (A0-18):** Führt zu einer nachvollziehbaren Candidate-Liste von Concept-Pfaden über grep/ripgrep auf `wiki/`, Markdown-Traversal von `index.md` und Link-Following — deterministisch statt probabilistisch. Gleichsam Grundlage für die Bereichszuordnung (gleiches textuelles Prinzip wie AD-7c).
|
||||
- **Keine eigenständige LLM-Runtime:** Der ausführende agentische Host (Claude/Codex-Adapter) orchestriert die Sequenz gemäß AD-17 (Lease holen, innerhalb des geleasten Bereichs mutieren, committen, freigeben); keine separaten Prozesse oder ein Server (AD-11).
|
||||
- **Leasing-Modell (AD-17a..f, A0-12..A0-16):** Producer arbeiten auf `lease/<area>/<id>`-Branches; Lease-Akquise gegen einen eindeutigen Commit-Object-Wert (Merge-Base-Disziplin); ein Lockfile realisiert semantisch identisch in jedem Adapter — Realisierung ist nicht pro Adapter frei wählbar. Die Lease umfasst die Root-Scope (`wiki/` inklusive `log.md`, `index.md` und aller Root-Dateien).
|
||||
- **Kein textueller Auto-Merge (AD-17c, A0-14):** Zwei Branches mit Änderungen am selben Concept-Pfad werden nie textuell automatisch gemerged; der Merge ist compiler-vermittelt und durchläuft die AD-16-Klassifikation mit explizitem `log.md`-Eintrag, falls die Inhalte ungleich sind.
|
||||
- **Dirty-Tree-Schutz (AD-17e/f, A0-16):** Vor jeder Mutation wird die Working Copy des zu mutierenden Bereichs geprüft; fremde uncommittete Änderungen werden geschützt (Stash/Scratch-Zone) und in `log.md` dokumentiert. Mutationen operieren nur auf Directory-/Commit-Ebene — Commit-Boundary ist die Mutation-Boundary.
|
||||
- **Lease-Staleness (AD-17d, A0-15):** TTL plus Lease-Registrierung im Clone-Root-State; uncommittete Leases gelten nach Run-Abbruch als stale, verwaiste Leases können übernommen oder als stale markiert und protokolliert werden; `raw/` dient als Zugriffs- und Consistency-Basis.
|
||||
- **Auflösungsautorität (AD-17g, A0-17):** Der die Lease haltende Compilation Run löst AD-16-Kollisionen (Default: Erhaltung) auf; menschliche Eskalation nur bei Unentscheidbarkeit; die Auflösung wird an Commit-Hash und Klassifikation im `log.md` gebunden.
|
||||
- **Determinismus-Vertrag (AD-17h/FT-10, A0-19):** Über denselben Git-State und dasselbe Eingabeset erzeugen zwei unabhängige Runs denselben Bundle-State; Abweichung gilt als Fehler der Klassifikation, nicht als Rauschen. Das Enforcement lebt im MVP als Agent-Instruktions-Validator (D-3/Q-6) und muss mechanisch bestätigt sein, bevor es tragend wird.
|
||||
- **Inkrementelle Evolution und menschliche Kuratierung (A0-21, FT-9):** Unabhängige Concepts werden nicht bei jedem Lauf regeneriert; eine menschliche Korrektur eines maschinell erzeugten Concepts überlebt als normale Kuratierung (Datei-Edit + Git) — kein Nulling-Diff und keine Re-Kompilation des ganzen Bundles.
|
||||
- **Synthese bleibt source-grounded (AD-4):** Bestehende Concepts dürfen Kontext und Synthese liefern, fachliche Aussagen müssen aber auf nachvollziehbare Sources zurückführbar bleiben; Wiki-Links ersetzen nie die Provenienz zur ursprünglichen Evidenz.
|
||||
- **Inkrementeller Datenfluss (AD-5, A0-6):** Interpret → Reconcile → Synthesize → Update affected Concepts. Startpunkt ist immer das bestehende Bundle — niemals "Regenerate Everything" (SM-1, FT-6).
|
||||
- **Reason/Mutate-Trennung (AD-6, A0-7):** Logische Phasen Analyse → Reconcile → Plan Changes → Mutate → Validate. Keine eigene Workflow Engine; ein Agent kann die Phasen in einer Session durchführen, der beobachtbare Endzustand des Bundles muss auch bei Abbruch konsistent sein.
|
||||
- **Deterministische Relevanz & Routing (A0-18):** Geschlossene, geordnete Term-Gewinnung bzw. explizites persistiertes Term-Manifest; Suchterm und Concept-Body werden identisch normalisiert und literal-sicher verglichen. Eine exklusive Routing-Tabelle unterscheidet `UPDATE`, `CREATE`, `ORPHAN/HOLD` und echten `NO_OP`; gleicher Git-State plus gleiches Eingabemanifest erzeugt dieselbe Candidate-Liste und Reihenfolge. *Ist (Story 3.9, 2026-08-20): in `schema/compiler.md` **§5.15** verankert (Termgewinnung geschlossen, eine exklusive Routing-Tabelle, Raw-Immutability-Guard, reservierte Zielpfade, Zwei-Run-Identität; §3.2 bleibt Erhebungs-Anker, §5.15 Pkt. 3 die Routing-Zuordnung).*
|
||||
- **Keine eigene LLM-Runtime:** Der ausführende agentische Host orchestriert den AD-17-Ablauf (Lease holen, innerhalb des geleasten Bereichs mutieren, committen, freigeben); keine separaten Prozesse oder ein Server (AD-11).
|
||||
- **Atomare Root-Scope-Lease (AD-17a/b, A0-12/13):** Producer behalten die Branch-Konvention `lease/<area>/<id>`, akquirieren aber genau einen atomaren, scope-bezogenen Lock im clone-geteilten Zustand. Die Run-ID ist Lock-Inhalt, nicht Exklusivitätsschlüssel; konkurrierende Producer verschiedener IDs und Worktrees teilen denselben Root-Scope (`wiki/` inklusive `log.md`, `index.md` und aller Root-Dateien). *Zielzustand (Review-Loop-3, P-11): geplant für Story 3.11 (Sprint-Change-Proposal 2026-08-20) — die atomare Lock-Präzisierung ist noch nicht in `schema/compiler.md` §5.11 verankert; die bestehende §5.11-Verankerung (Branch-Konvention, Root-Scope-Lease) bleibt unverändert maßgeblich.*
|
||||
- **Fail-closed Kollisionsgrenze (AD-17c, A0-14):** Zwei Branches mit ungleichen Änderungen am selben Concept-Pfad werden nie textuell automatisch gemerged. Epic 3 erhält beide Commit-Hashes und den Scope in einem strukturierten Hold; AD-16-Klassifikation und semantische Auflösung sind Epic 4 / Story 4.x.
|
||||
- **Transaktionaler Lifecycle (AD-17d–f, A0-15/16, AD-6):** Preflight schützt getrackte und ungetrackte Fremdänderungen (eindeutige Abort-/Protect-Zustandsmaschine), Rollback restauriert exakt den bezeichneten Baseline-Commit (Index + Worktree), Release hinterlässt Mutation, zulässigen Nachweis und sauberen Worktree dauerhaft. Eine lebende Lease wird nicht allein durch Generationserhöhung stale; Staleness verlangt bestätigten Abbruch oder abgelaufene Liveness plus atomare Ownership-Prüfung. *Zielzustand (Review-Loop-3, P-11): geplant für Story 3.12 (Sprint-Change-Proposal 2026-08-20) — die transaktionale Lifecycle-Präzisierung (Abort-/Protect-Zustandsmaschine, Liveness-Prüfung) ist noch nicht in `schema/compiler.md` §5.11/§5.12 verankert; die bestehende Verankerung bleibt unverändert maßgeblich.*
|
||||
- **Determinismus-Vertrag (AD-17h/FT-10, A0-19):** Das kanonische Eingabemanifest bindet Baseline, geordnete Sources und jeden output-sichtbaren Run-/Zeit-/Identitätswert; der Run-Receipt (Candidates, Reihenfolge, Plan, Entscheidungen, Output-Hashes) liegt außerhalb des Bundles. Zwei getrennte saubere Worktrees mit frischen Agent-Kontexten erzeugen denselben Bundle-State; hart codierte erwartete Pläne oder Concept-Bodies und pauschal maskierte `verified`-Ereignisse sind kein gültiger Nachweis.
|
||||
- **Synthese bleibt source-grounded (AD-4):** Bestehende Concepts dürfen Kontext liefern, fachliche Aussagen müssen aber auf nachvollziehbare `raw/`-Evidenz zurückführbar bleiben; Wiki-Links ersetzen nie die Provenienz zur ursprünglichen Evidenz.
|
||||
- **Epic-3-Abnahmegate:** Ein portables, fail-fast ausführbares Gate führt alle Epic-3-Szenarien aus, ruft den vollständigen autorisierten Schema-Validator über alle `wiki/`-Dateien auf und lässt einen frischen Agent-Kontext die kanonische Instruktion über einer repräsentativen Fixture ausführen — der Harness schreibt keine erwarteten Wiki-Ausgänge selbst. Zwei frische Agent-Kontexte müssen Run-Receipts und Bundle-State angleichen. Ein Defizit des autorisierten Validator-Vertrags blockiert das Gate und verlangt eine separat genehmigte Epic-1-Remediation.
|
||||
- **Keine UX-/Design-Anteile relevant:** v1 ist datei-/CLI-basiert ohne GUI (PRD A-3, AD-11).
|
||||
|
||||
## Cross-Story Dependencies
|
||||
|
||||
- Baut auf dem Workspace aus Epic 1 auf (`raw/` immutable, Bundle-Root, Schema-Validierung) und konsumiert die in Epic 2 erzeugten, OKF-konformen, verlinkten Concepts mit claim-granularer Provenienz als vorhandenes Wissen.
|
||||
- Der compiler-vermittelte Merge (AD-17c) und die Kollisionsauflösung (AD-17g) setzen die AD-16-Klassifikation samt `log.md`-Dokumentation voraus, die in Epic 4 umgesetzt wird.
|
||||
- Das Leasing-/Dirty-Tree-Modell dieses Epics koordiniert Compiler-Runs mit menschlicher Bearbeitung (Q-2) und liefert die Grundlage für die Git-Nachvollziehbarkeit und Auflösungs-Dokumentation, auf die Epic 5 aufsetzt.
|
||||
- Keine UX/Design-Anteile relevant: v1 ist datei-/CLI-basiert ohne GUI (A-3, AD-11).
|
||||
- Baut auf dem Workspace aus Epic 1 auf (immutable `raw/`, Bundle-Root, Schema-Validierung) und konsumiert die in Epic 2 erzeugten OKF-konformen, verlinkten Concepts mit claim-granularer Provenienz als vorhandenes Wissen.
|
||||
- Story 3.9 liefert die deterministische Routing-Basis für Story 3.10; Story 3.11 liefert die atomare Lease-Basis für Story 3.12 (parallel). Story 3.8 wird nach 3.9–3.12 mit echten unabhängigen Runs abgeschlossen; Story 3.13 ist das finale Abnahmegate.
|
||||
- AD-17c/A0-14 sind geteilt: Epic 3 verantwortet Erkennung und fail-closed Erhaltung, Epic 4 Klassifikation und semantische Auflösung. AD-17g/A0-17 verbleiben vollständig in Epic 4. A0-21 ist ebenfalls geteilt: Story 3.10 verantwortet den Incrementality-Teil (Erhaltung unabhängigen Wissens), Story 4.3 die Human-Curation-Semantik (FT-9).
|
||||
- Das Leasing-/Dirty-Tree-Modell koordiniert Compiler-Runs mit menschlicher Bearbeitung und trägt die Git-Nachvollziehbarkeit, auf die Epic 5 aufsetzt.
|
||||
|
||||
@@ -0,0 +1,725 @@
|
||||
#!/usr/bin/env bash
|
||||
# Story 3.8 — Sandbox-Tests des Determinismus-Vertrags (AD-17h/FT-10/A0-19) als
|
||||
# Agent-Instruktions-Validator (§5.14, Revision 3.3)
|
||||
# Re-executierbar: bash run-sandbox.sh (ab Workspace-Root; Sandbox unter /tmp/sb38)
|
||||
# Zweck: die deterministische Bestätigungs-Mechanik (§5.14) als re-executierbarer
|
||||
# Run-Demonstrator durchspielen —
|
||||
# DET-1 BUNDLE_STATE_DEFINITION: ein Mini-Bundle erzeugen und die Bundle-State-
|
||||
# Projektion deterministisch definieren/extrahieren (wiki/-Dateien + Plan-/
|
||||
# Kandidaten-/Reihenfolge-Outputs; Extraktion zweimal -> identisch)
|
||||
# DET-2 ZWEI_RUN_IDENTISCH (nicht-vakuum, zwei getrennte Worktrees): zwei frische
|
||||
# Agent-Kontexte in getrennt aufgebauten, sauberen Worktrees über demselben
|
||||
# committeten Baum -> identische Bundle-States bis auf at (Q-6/A0-19: eine zweite
|
||||
# Ausführung in derselben Session genügt nicht); kanonisches Eingabemanifest +
|
||||
# Run-Receipt (außerhalb des Bundles); keine hart codierten erwarteten Pläne/
|
||||
# Concept-Bodies, kein pauschales verified-Maskieren; echte Content-Hashes
|
||||
# (Witness weicht byte-weise von der Baseline ab — kein Vakuum)
|
||||
# DET-3 ZWEI_RUN_ABWEICHUNG: künstlich divergenter Lauf -> als AD-16-Klassifikations-
|
||||
# defekt klassifiziert und textuell benannt (kein Rauschen); korrigierter zweiter
|
||||
# Lauf == erster Lauf (erneut bestätigt)
|
||||
# DET-4 AT_GAP_AUSNAHME: generated.at-Wanduhr-Gap ist die einzige benannte Ausnahme
|
||||
# (diff zwischen zwei Runs ausschließlich auf der at-Zeile; nach at-Maskierung
|
||||
# byte-identisch); jede andere Differenz liegt ausserhalb der Ausnahme =
|
||||
# AD-16-Klassifikationsdefekt
|
||||
# DET-5 EM_DASH: Em-Dash — kollabiert auf dieselbe canonische Form wie En-Dash/
|
||||
# Bindestrich/Unterstrich/Leerzeichen (§3.2 Pkt. 1b, [-–— _] -> -)
|
||||
# DET-6 KOLLAPS: Läufe (a--b), führende (-x), trailende (x-) -> Kollaps auf
|
||||
# genau ein - + Trim (Reichweite: jedes Vorkommen -> genau ein -)
|
||||
# DET-7 MATCH_SCOPE: Stufe a matcht ganze Wörter über den Body, exklusive YAML-
|
||||
# Frontmatter (Substring-/Frontmatter-Treffer ausgeschlossen)
|
||||
# DET-8 ORPHAN: neu committete raw/-Evidenz ohne Ziel-Pfad-Treffer -> unzugeordnet,
|
||||
# log.md-verwaist protokolliert (Datumsgruppe, <Baseline-Commit>), kein Banner,
|
||||
# keine stille Vorbearbeitung, keine eigenständige Anlage (AD-16-Default)
|
||||
# Determinismus-Vertrag (AD-17h/A0-19) als HARDE Assertion je Szenario; KEINE_EIGENE_ENGINE-
|
||||
# Negativkontrolle (D-3/AD-11) in DET-1; Frontmatter-/log.md-Konformitaet (Vertrag §3.3/§3.4, §5).
|
||||
# Ubuntu-Sandbox-Semantik auf einem /tmp-Baum — NIE der reale wiki/- oder raw/-Baum.
|
||||
set -u
|
||||
ROOT=$(mktemp -d /tmp/sb38-XXXXXX)
|
||||
SB="$ROOT/sb"
|
||||
mkdir -p "$SB/wiki" "$SB/raw"
|
||||
cd "$SB"
|
||||
git init -q
|
||||
# Determinismus vs. Host-Git-Konfiguration (AD-17h): LF-Blobs + LF-Worktree —
|
||||
# autocrlf/filemode-Umwandlung des Hosts wuerde sha256-Vergleiche verschieben.
|
||||
git config core.autocrlf false
|
||||
git config core.filemode false
|
||||
git config user.email "sandbox@test"
|
||||
git config user.name "Sandbox"
|
||||
|
||||
# ---------- Basis-Baum (committete Ausgangslage = Baseline-Commit) ----------
|
||||
# Mini-Bundle mit zwei Root-Concepts (alpha als Mutations-Objekt, gamma als Kontrolle).
|
||||
cat > wiki/index.md <<'EOF'
|
||||
# Index
|
||||
- [Alpha](alpha.md)
|
||||
- [Gamma](gamma.md)
|
||||
EOF
|
||||
cat > wiki/alpha.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/alpha-v1.md
|
||||
id: s1
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-16T09:00:00Z
|
||||
---
|
||||
Das Alpha-Protokoll definiert eine deterministische Init-Sequenz (raw/alpha-v1.md#S-1).
|
||||
Alpha verwendet ausschließlich lokale Netze (raw/alpha-v1.md#S-2).
|
||||
EOF
|
||||
cat > wiki/gamma.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/gamma-v1.md
|
||||
id: s1
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-16T09:00:00Z
|
||||
---
|
||||
Gamma beschreibt ein anderes, hier nicht betroffenes Thema.
|
||||
EOF
|
||||
cat > wiki/log.md <<'EOF'
|
||||
# Log
|
||||
EOF
|
||||
cat > raw/alpha-v1.md <<'EOF'
|
||||
### S-1
|
||||
Evidenz v1: deterministische Init-Sequenz.
|
||||
### S-2
|
||||
Evidenz v1: ausschließlich lokale Netze.
|
||||
EOF
|
||||
cat > raw/gamma-v1.md <<'EOF'
|
||||
### S-1
|
||||
Evidenz v1: Gamma-Thema.
|
||||
EOF
|
||||
git add -A
|
||||
git commit -qm "Baseline"
|
||||
BASE=$(git rev-parse HEAD)
|
||||
echo "BASELINE-COMMIT (Merge-Base, eindeutiger Commit-Object-Wert): $BASE"
|
||||
echo "Sandbox-Root: $ROOT (loeschbar: rm -rf $ROOT)"
|
||||
echo
|
||||
|
||||
# ---------- Helfer: Run-Label / Isolation (kein Carry-over zwischen Szenarien) ----------
|
||||
runlabel() { echo; echo "########## $1 ##########"; }
|
||||
isolate() {
|
||||
git checkout -qf -B "$1" "$BASE"
|
||||
git reset -q --hard "$BASE"
|
||||
git clean -qfd wiki raw lease registry scratch plan-run
|
||||
}
|
||||
|
||||
# ---------- Deterministische Normalisierung (§3.2 Pkt. 1b, Story 3.8) ----------
|
||||
# lowercasing + Binde-Varianten-Kollaps [-–— _] -> - (En-Dash –, Em-Dash —,
|
||||
# Bindestrich -, Unterstrich _, Leerzeichen), Kollaps-Reichweite: jedes Vorkommen ->
|
||||
# genau ein -; Läufe kollabieren; führende/trailende Separatoren werden getrimmt.
|
||||
norm() { # $1 = Begriff (Kollaps-Form, NICHT registry-aufloesend — Kollaps-Scope isoliert)
|
||||
printf '%s' "$1" | sed \
|
||||
-e 's|[–—]|-|g' \
|
||||
-e 's|_| |g' \
|
||||
-e 's| |-|g' \
|
||||
-e 's|--*|-|g' \
|
||||
-e 's|^-*||' \
|
||||
-e 's|-*$||' \
|
||||
| tr 'A-Z' 'a-z'
|
||||
}
|
||||
# Stufe-a-Match-Scope (§3.2 Pkt. 2a, Story 3.8): matcht ganze Wörter über den Body,
|
||||
# exklusive YAML-Frontmatter. Implementierung: Frontmatter (zwischen ersten beiden ---)
|
||||
# wird entfernt, danach Wortgrenzen-Match (rg mit Wortgrenzen bzw. grep '\b').
|
||||
match_stufe_a() { # $1=Begriff $2=Datei-Liste ; liefert getroffene wiki-Pfade (ohne Präfix/Suffix)
|
||||
local term="$1" file
|
||||
# Symmetrische Normalisierung (Review-Loop-3, P-4; §3.2 Pkt. 2a): der Term wird über
|
||||
# norm() (Lowercasing + Kollaps-Klasse [-–— _] -> -, §3.2 Pkt. 1b) normalisiert und der
|
||||
# Body entsprechend lowercased — der Match läuft auf den beidseitig normalisierten Formen
|
||||
# (kein host-abhängiges -i-Flag; Groß-/Kleinschreibung deterministisch über beide Seiten).
|
||||
local term_lc
|
||||
term_lc=$(norm "$term")
|
||||
# Regex-Metazeichen im Begriff literal-escaped (deterministischer, literal-sicherer Vergleich,
|
||||
# §3.2-Pkt.-2a/§5.14 Pkt. 5): ein Term wie "a+b" oder "x.y" darf nie als Muster umgedeutet werden.
|
||||
local esc
|
||||
esc=$(printf '%s' "$term_lc" | sed 's|[][\\.*^$+?(){}|]|\\&|g')
|
||||
for file in "${@:2}"; do
|
||||
# Body = alles nach dem zweiten "---" (Frontmatter exkludiert, deterministisch);
|
||||
# CRLF-tolerant (Host-Checkout-Form normalisiert), sonst wäre der Wortgrenzen-Match unbestimmt.
|
||||
# Der Body wird wie der Term lowercased (Symmetrie); die Kollaps-Äquivalenz des Em-Dash
|
||||
# ist damit im Match-Pfad real ausgeübt (norm-then-match, Review-Loop-3, P-4).
|
||||
body=$(tr -d '\r' < "$file" | tr 'A-Z' 'a-z' | awk 'BEGIN{n=0} /^---$/{n++; next} n>=2{print}')
|
||||
# Wortgrenzen-Match: ganze Wörter — Substring-/Frontmatter-Treffer liefern nichts.
|
||||
if printf '%s' "$body" | grep -Eq "(^|[^A-Za-z0-9])${esc}([^A-Za-z0-9]|$)"; then
|
||||
basename "$file" .md
|
||||
fi
|
||||
done
|
||||
}
|
||||
# log.md-Eintrag (datumsgruppiert, neueste zuerst; Vertrag §5). Deterministisch fester Tag.
|
||||
# Fehler in mktemp/mv werden NICHT geschluckt: ein fehlgeschlagener Eintrag würde den
|
||||
# log.md-Hash beider Läufe identisch (Baseline) lassen => Vakuum-Gleichheit (sha_log).
|
||||
log_bullet() { # $1 = Bullet-Text (eine Zeile)
|
||||
local day="2026-08-20"
|
||||
local header="## $day" line="$1"
|
||||
local tmp
|
||||
if grep -qxF "$header" wiki/log.md; then
|
||||
tmp=$(mktemp) || { echo "HARD-FAIL (log_bullet): mktemp fehlgeschlagen" >&2; exit 1; }
|
||||
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 || { echo "HARD-FAIL (log_bullet): log.md-Update fehlgeschlagen (Eintrag verloren)" >&2; exit 1; }
|
||||
else
|
||||
tmp=$(mktemp) || { echo "HARD-FAIL (log_bullet): mktemp fehlgeschlagen" >&2; exit 1; }
|
||||
{ printf '%s\n' "$header"; printf '%s\n' "$line"; cat wiki/log.md; } > "$tmp" \
|
||||
&& mv "$tmp" wiki/log.md \
|
||||
|| { echo "HARD-FAIL (log_bullet): log.md-Update fehlgeschlagen (Eintrag verloren)" >&2; exit 1; }
|
||||
fi
|
||||
}
|
||||
|
||||
# =====================================================================================
|
||||
# DET-1 BUNDLE_STATE_DEFINITION (§5.14 Pkt. 1)
|
||||
# =====================================================================================
|
||||
runlabel "DET-1: BUNDLE_STATE_DEFINITION — Mini-Bundle erzeugen; Bundle-State-Projektion (wiki/-Dateien + Plan-/Kandidaten-/Reihenfolge-Outputs) deterministisch definieren/extrahieren; KEINE_EIGENE_ENGINE (D-3/AD-11)"
|
||||
if command -v pgrep >/dev/null 2>&1; then
|
||||
engine_proc=$(pgrep -f "wow-flow-engine|wow-server|wow-mcp" 2>/dev/null || true)
|
||||
else
|
||||
command -v ps >/dev/null 2>&1 || { echo "HARD-FAIL (KEINE_EIGENE_ENGINE): weder pgrep noch ps verfügbar" >&2; exit 1; }
|
||||
engine_proc=$(ps aux 2>/dev/null | grep -E "wow-flow-engine|wow-server|wow-mcp" | grep -v "grep" || true)
|
||||
fi
|
||||
if [ -n "$engine_proc" ]; then
|
||||
echo "HARD-FAIL (KEINE_EIGENE_ENGINE D-3/AD-11, §5.14): ein Workflow-Engine-Prozess wurde gestartet" >&2
|
||||
echo "$engine_proc" | sed 's/^/ /' >&2
|
||||
exit 1
|
||||
else
|
||||
echo " BEFUND: keine Workflow-Engine-Prozesse (wow-flow-engine/wow-server/wow-mcp) — der Agent-Instruktions-Validator ist die Instruktion selbst (kein Prozess/Server/MCP)"
|
||||
fi
|
||||
isolate det1
|
||||
# Der Run erzeugt einen definierten Bundle-State: neue committete Evidenz (Input) ->
|
||||
# Plan-/Kandidaten-Output -> Mutations-Commit (deterministischer Run-Ausgangszustand).
|
||||
cat > raw/alpha-v2.md <<'EOF'
|
||||
### S-3
|
||||
Evidenz v2: Alpha erweitert um eine synchrone Kopplung.
|
||||
EOF
|
||||
git add -A && git commit -qm "Evidenz v2"
|
||||
plan=$(printf 'cand=alpha;form=update;baseline=%s' "$BASE")
|
||||
cat > wiki/alpha.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/alpha-v1.md
|
||||
id: s1
|
||||
- resource: raw/alpha-v2.md
|
||||
id: s3
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-20T00:00:00Z
|
||||
---
|
||||
Das Alpha-Protokoll definiert eine deterministische Init-Sequenz (raw/alpha-v1.md#S-1).
|
||||
Alpha verwendet ausschließlich lokale Netze (raw/alpha-v1.md#S-2).
|
||||
Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3).
|
||||
EOF
|
||||
log_bullet "- Determinismus-Bestätigung (Bundle-State-Definition, §5.14 Pkt. 1): $plan"
|
||||
git add -A && git commit -qm "Run: alpha-Update (DET-1)"
|
||||
# Bundle-State-Extraktion (§5.14 Pkt. 1): (a) committeter Baum gg. Baseline,
|
||||
# (b) Kandidatenliste in Zuwachs-Sicht-Ordnung, (c) Ausführungs-Entscheidung (Form-Wahl).
|
||||
# Deterministische Projektion = (a)+(b)+(c) — zweimal extrahiert, byte-identisch.
|
||||
# Dev-Demo-Notiz: die (b)-/(c)-Kandidaten-/Form-Outputs sind für die Wiederholungs-Probe
|
||||
# eigentliche Run-Feststellungen (hier redaktionell verdichtet; die Tendenz "die Bundle-State
|
||||
# wiederholt extrahieren ist deterministisch" wird von der zweimaligen Wiederholung bewiesen,
|
||||
# die Ausführungs-Verdikte selbst belegen die DET-Szenarien DET-3/DET-4/DET-7).
|
||||
bs_a() {
|
||||
{ git diff --name-only "$BASE" -- wiki/ ; git status --porcelain -- wiki/ | awk '{print $2}'; } \
|
||||
| sed -e 's|^wiki/||' -e 's|\.md$||' | LC_ALL=C sort -u
|
||||
# Kandidatenliste (Stufe a, deterministisch; Zuwachs-Ordnung) — hier textuell festgehalten:
|
||||
match_stufe_a "kopplung" wiki/alpha.md wiki/gamma.md
|
||||
# Form-Wahl (Ausführungs-Entscheidung): alpha ist betroffen, gamma nicht
|
||||
echo "form=update"
|
||||
echo "baseline=$BASE"
|
||||
}
|
||||
B1=$(bs_a)
|
||||
B2=$(bs_a)
|
||||
[ "$B1" = "$B2" ] || { echo "HARD-FAIL (DET-1): Bundle-State-Projektion nicht deterministisch (gleiche Extraktion zweimal ungleich)" >&2; exit 1; }
|
||||
case "$B1" in
|
||||
*alpha*) ;;
|
||||
*) echo "HARD-FAIL (DET-1): Bundle-State-Projektion enthaelt Wiki-Pfad-Projektion nicht (alpha fehlt)" >&2; exit 1;;
|
||||
esac
|
||||
echo " Bundle-State-Projektion (deterministisch, wiederextrahierbar):"
|
||||
echo "$B1" | sed 's/^/ /'
|
||||
echo "RESULT: PASS — DET-1: BUNDLE_STATE_DEFINITION — Bundle-State = deterministische Projektion des committeten Git-States ((a) Baum gg. Baseline, (b) Kandidaten-, (c) Plan-/Reihenfolge-/Entscheidungs-Outputs); Extraktion zweimal byte-identisch (AD-17h/A0-19); keine eigene Engine (D-3/AD-11)"
|
||||
|
||||
# =====================================================================================
|
||||
# DET-2 ZWEI_RUN_IDENTISCH (nicht-vakuum, zwei getrennte Worktrees) — §5.14 Pkt. 2
|
||||
# =====================================================================================
|
||||
runlabel "DET-2: ZWEI_RUN_IDENTISCH (nicht-vakuum) — zwei frische Agent-Kontexte in getrennt aufgebauten, sauberen Worktrees über demselben committeten Baum -> identische Bundle-States bis auf at (Q-6/A0-19); kanonisches Eingabemanifest + Run-Receipt außerhalb des Bundles; keine hart codierten erwarteten Bundle-Outputs, verified nicht pauschal maskiert; echte Content-Hashes (Witness weicht byte-weise von Baseline ab)"
|
||||
# --- Zwei getrennte, saubere Worktrees über demselben Baseline-Commit ($BASE) aufbauen ---
|
||||
# Re-Run-Sicherheit: verwaiste worktree-Registrierungen aus früheren Läufen (anderes $ROOT)
|
||||
# erst prune, sonst blockiert `git worktree add` oder trägt Altpfade nach.
|
||||
git worktree prune
|
||||
git worktree add -q "$ROOT/wt-a" "$BASE" || { echo "HARD-FAIL (DET-2): Worktree wt-a nicht aufgebaut" >&2; exit 1; }
|
||||
git worktree add -q "$ROOT/wt-b" "$BASE" || { echo "HARD-FAIL (DET-2): Worktree wt-b nicht aufgebaut" >&2; exit 1; }
|
||||
# Kanonisches Eingabemanifest (A0-19, §5.14 Pkt. 2): Baseline-Commit + geordnete Source-
|
||||
# Eingaben + output-sichtbare Run-/Zeit-/Identitätswerte — identisch für beide Läufe.
|
||||
# Das Manifest wird unten in run2_worktree VOR jedem Lauf konsumiert/validiert (nicht dekorativ).
|
||||
cat > "$ROOT/manifest.yaml" <<EOF
|
||||
baseline: $BASE
|
||||
generated_by: wow-compiler/0.1.0
|
||||
sources:
|
||||
- raw/alpha-v1.md
|
||||
- raw/alpha-v2.md
|
||||
output_visible_run_identity:
|
||||
- generated.by
|
||||
- generated.at # A0-20: einzige benannte Ausnahme im Bundle-State-Vergleich (Pkt. 3)
|
||||
EOF
|
||||
manifest_path="$ROOT/manifest.yaml"
|
||||
[ -f "$manifest_path" ] || { echo "HARD-FAIL (DET-2): kanonisches Eingabemanifest fehlt ($manifest_path; §5.14 Pkt. 2)" >&2; exit 1; }
|
||||
|
||||
run2_worktree() { # $1 = Worktree-Pfad ; $2 = Run-Name ; führt die Instruktion als EIGENER
|
||||
# Ausführungskontext (frischer Agent-Kontext simulativ: eigener Worktree, eigene Subshell
|
||||
# mit eigenem cwd, keine Session-Wiederholung) über demselben committeten Baum aus.
|
||||
# Der Run läuft komplett in einer Subshell — der Haupt-Kontext bleibt am Sandbox-Root
|
||||
# (kein Carry-over des Worktree-cwd in nachfolgende Szenarien).
|
||||
local wt="$1" name="$2"
|
||||
(
|
||||
set -e
|
||||
cd "$wt" || exit 9
|
||||
# Kanonisches Eingabemanifest VOR dem Lauf konsumieren/validieren (A0-19, §5.14 Pkt. 2):
|
||||
# Baseline-Commit und geordnete Source-Eingaben müssen dem Repository-State entsprechen
|
||||
# — das Manifest ist Eingabe der Instruktion, nicht bloße Doku (kein leerer Lauf möglich).
|
||||
m_base=$(sed -n 's/^baseline: //p' "$ROOT/manifest.yaml")
|
||||
[ -n "$m_base" ] || { echo "HARD-FAIL (DET-2): Manifest ohne baseline-Key" >&2; exit 9; }
|
||||
[ "$m_base" = "$BASE" ] || { echo "HARD-FAIL (DET-2): Manifest-baseline ($m_base) != tatsaechliche Baseline ($BASE)" >&2; exit 9; }
|
||||
# Abschnittsbewusste Extraktion: nur Elemente unter dem jeweiligen Manifest-Key
|
||||
m_src=$(awk '/^sources:/{f=1;next} /^[a-z_]+:/{f=0} f && /^ - /{sub(/^ - /,""); sub(/ *#.*$/,""); print}' "$ROOT/manifest.yaml")
|
||||
m_identity=$(awk '/^output_visible_run_identity:/{f=1;next} /^[a-z_]+:/{f=0} f && /^ - /{sub(/^ - /,""); sub(/ *#.*$/,""); print}' "$ROOT/manifest.yaml")
|
||||
[ -n "$m_src" ] || { echo "HARD-FAIL (DET-2): Manifest ohne geordnete Source-Eingaben" >&2; exit 9; }
|
||||
[ -n "$m_identity" ] || { echo "HARD-FAIL (DET-2): Manifest ohne output-sichtbare Identitätswerte" >&2; exit 9; }
|
||||
case "$m_identity" in *generated.at*) ;; *) { echo "HARD-FAIL (DET-2): Manifest muss generated.at als Identitätswert führen (A0-20-Ausnahme)" >&2; exit 9; };; esac
|
||||
case "$m_identity" in *generated.by*) ;; *) { echo "HARD-FAIL (DET-2): Manifest muss generated.by als Identitätswert führen" >&2; exit 9; };; esac
|
||||
# generated.by wird aus dem Manifest KONSUMIERT (nicht hart codiert; Review-Loop-3, P-6):
|
||||
# der output-sichtbare Identitätswert des Laufs ist Manifest-Inhalt, nicht Skript-Konstante.
|
||||
m_by=$(sed -n 's/^generated_by: //p' "$ROOT/manifest.yaml")
|
||||
[ -n "$m_by" ] || { echo "HARD-FAIL (DET-2): Manifest ohne generated_by-Wert" >&2; exit 9; }
|
||||
# Sicherstellen: Worktree am Baseline-Commit, sauber (Q-6: getrennt aufgebaut, sauber).
|
||||
git checkout -qf "$BASE"
|
||||
git clean -qfd wiki raw
|
||||
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"
|
||||
# Source-Eingaben-Verdikt: JEDE manifestierte geordnete Source-Eingabe (raw/alpha-v1.md
|
||||
# aus der Baseline, raw/alpha-v2.md als neuer Increment-Input) existiert im Worktree
|
||||
# NACH dem Input-Commit (EC-1-Semantik: Quelle zum Verarbeitungszeitpunkt vorhanden).
|
||||
for s in $m_src; do
|
||||
[ -f "$s" ] || { echo "HARD-FAIL (DET-2): Manifest-Source fehlt im Worktree nach Input-Commit: $s" >&2; exit 9; }
|
||||
done
|
||||
# Mutations-Commit als commitierter Run-Ausgangszustand: generated.at IST die reale
|
||||
# Wanduhr-Ausgabe des Laufs (A0-20) — sie wird COMMITTET und im Receipt als eigener
|
||||
# at-Zellenwert festgehalten; die Normalisierung auf AT erfolgt erst BEIM VERGLEICH
|
||||
# (§5.14 Pkt. 2: "diff ... ohne die maskierte at-Zeile"), nicht vor dem Commit
|
||||
# (kein stiller Ausschluss, keine Maskierung vor der Persistenz).
|
||||
at_now=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
cat > wiki/alpha.md <<EOF
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/alpha-v1.md
|
||||
id: s1
|
||||
- resource: raw/alpha-v2.md
|
||||
id: s3
|
||||
generated:
|
||||
by: $m_by
|
||||
at: $at_now
|
||||
---
|
||||
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
|
||||
# Plan-/Kandidaten-/Reihenfolge-Ableitung (§5.14 Pkt. 2) — abgeleitet aus dem
|
||||
# deterministischen Run-State, NICHT hart codiert: Kandidat = Stufe-a-Treffer des
|
||||
# Terms "kopplung" über den (deterministischen) Body (dieselbe Ableitung wie DET-1).
|
||||
# cand kann mehrere Dateien zeilengetrennt liefern — auf eine leere/kommafreie Form
|
||||
# normalisiert, damit der Receipt-Zeilenblock nicht durch eingebettete Newlines bricht.
|
||||
local cand
|
||||
cand=$(match_stufe_a "kopplung" wiki/alpha.md wiki/gamma.md | tr '\n' ',' | sed 's/,$//')
|
||||
local plan
|
||||
plan="cand=$cand;form=update;baseline=$BASE"
|
||||
log_bullet "- Determinismus-Bestätigung (Zwei-Run, §5.14 Pkt. 2): $plan; Baseline $BASE"
|
||||
# Confirm: der at-Zellenwert ist als reale Wanduhr-Ausgabe committet (kein Maskieren vor Commit).
|
||||
git add -A && git commit -qm "Run: alpha-Update ($name)"
|
||||
committed_at=$(git show 'HEAD:wiki/alpha.md' | sed -n 's/^ at: //p')
|
||||
[ "$committed_at" = "$at_now" ] || { echo "HARD-FAIL (DET-2): commitierte at != Lauf-at ($committed_at != $at_now; Maskierung vor Commit?)" >&2; exit 9; }
|
||||
# --- Bundle-State projizieren (deterministisch) + RUN-RECEIPT (außerhalb des Bundles) ---
|
||||
# Run-Receipt (A0-19, §5.14 Pkt. 2): Candidate-Liste, Reihenfolge, Plan, Entscheidungen,
|
||||
# Output-Hashes, Bundle-TREE und die at-Ausnahme (je Run-Cell) — liegt AUSSERHALB des
|
||||
# Knowledge Bundle (nicht in wiki//raw/), hier unter $ROOT/receipts/.
|
||||
# Die Run-Identität steht im Dateinamen (run2a.receipt/run2b.receipt); der INHALT ist die
|
||||
# deterministische Projektion plus die at-Ausnahme-Cell, damit der Zwei-Run-Abgleich BOTH
|
||||
# (a) byte-identische deterministische Teile UND (b) die ausgewiesene at-Ausnahme prüft.
|
||||
mkdir -p "$ROOT/receipts"
|
||||
{
|
||||
echo "baseline: $BASE"
|
||||
echo "plan: $plan"
|
||||
echo "candidates: $cand"
|
||||
echo "order: update-$cand"
|
||||
echo "decisions: form=update;candidate_match=stufe_a(kopplung)"
|
||||
# sha_alpha wird über die at-NORMALISIERTE Content-Projektion gebildet (§5.14 Pkt. 2:
|
||||
# Vergleich "ohne die maskierte at-Zeile"; A0-20) — die deterministischen Bestandteile
|
||||
# bleiben damit byte-vergleichbar, der at-Wert trägt nur in der at_cell-Ausnahme.
|
||||
echo "sha_alpha=$(git show 'HEAD:wiki/alpha.md' | sed 's/^ at: .*/ at: AT/' | sha256sum | cut -d' ' -f1)"
|
||||
echo "sha_log=$(git show 'HEAD:wiki/log.md' | sha256sum | cut -d' ' -f1)"
|
||||
echo "sha_index=$(git show 'HEAD:wiki/index.md' | sha256sum | cut -d' ' -f1)"
|
||||
# at_cell + tree sind die AUSNAHME-Evidenz: tree (Bundle-TREE-Hash des Run-Committs)
|
||||
# enthält die realen at-Wanduhr-Werte — wird daher NICHT im deterministischen Block
|
||||
# verglichen, sondern dokumentiert hier die benannte at-Ausnahme (kein stiller
|
||||
# Ausschluss: die deterministischen Bundle-Bestandteile decken sha_alpha/log/index ab).
|
||||
echo "at_cell=$committed_at"
|
||||
echo "tree=$(git rev-parse 'HEAD:')"
|
||||
} > "$ROOT/receipts/$name.receipt"
|
||||
)
|
||||
local rc=$?
|
||||
[ $rc -eq 0 ] || { echo "HARD-FAIL (DET-2): Lauf $name im Worktree fehlgeschlagen (rc=$rc)" >&2; exit 1; }
|
||||
}
|
||||
echo "--- Lauf A (frischer Agent-Kontext, Worktree wt-a) ---"
|
||||
run2_worktree "$ROOT/wt-a" run2a
|
||||
cat "$ROOT/receipts/run2a.receipt"
|
||||
echo "--- Lauf B (frischer Agent-Kontext, Worktree wt-b) ---"
|
||||
run2_worktree "$ROOT/wt-b" run2b
|
||||
cat "$ROOT/receipts/run2b.receipt"
|
||||
# at-Ausnahme-Demo (Review-Loop-3, P-7): die aktive Ausnahme (real unterschiedliche
|
||||
# Wanduhr-at-Werte) wird ERZWUNGEN, nicht nur gedruckt — bei einer Wanduhr-Sekunden-
|
||||
# kollision wird Lauf B deterministisch wiederholt (frischer Kontext, derselbe Baum),
|
||||
# bis die at-Zellen differieren (begrenzte Wiederholungen; jede Kollision ist ein
|
||||
# Host-Timing-Artefakt, keine Eigenschaft des committeten Zustands). Damit ist der
|
||||
# Change-Log-Beleg „zwei Läufe mit real unterschiedlichen at_cell-Werten" eine
|
||||
# Eigenschaft jeder Re-Execution.
|
||||
at_a=$(grep '^at_cell=' "$ROOT/receipts/run2a.receipt" | cut -d= -f2)
|
||||
for try in 1 2 3 4 5; do
|
||||
at_b=$(grep '^at_cell=' "$ROOT/receipts/run2b.receipt" | cut -d= -f2)
|
||||
[ "$at_a" != "$at_b" ] && break
|
||||
if [ "$try" -eq 5 ]; then
|
||||
echo "HARD-FAIL (DET-2): at-Ausnahme nicht demonstrierbar (5x Sekundenkollision — Host-Timing-Anomalie)" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo " at-Kollision (Wanduhr-Sekunde) — Lauf B wird im frischen Kontext wiederholt (Versuch $try)"
|
||||
run2_worktree "$ROOT/wt-b" run2b
|
||||
done
|
||||
# Receipt-Gerüst-Nicht-Vakuum: beide Receipts müssen den deterministischen Zeilenblock tragen
|
||||
# (diff könnte sonst zweifach-leere Dateien als "identisch" PASSen lassen).
|
||||
for r in "$ROOT/receipts/run2a.receipt" "$ROOT/receipts/run2b.receipt"; do
|
||||
[ -s "$r" ] || { echo "HARD-FAIL (DET-2): Receipt $r leer oder fehlt (Vakuum)" >&2; exit 1; }
|
||||
done
|
||||
echo "--- Abgleich der zwei Run-Receipts (nicht nur jeder Lauf gg. Baseline; keine hart codierten Erwartungswerte) ---"
|
||||
# Deterministischer Vergleich: ALLE Zeilen bis auf die beiden Ausnahme-Cells (at_cell=, tree=)
|
||||
# müssen zwischen den zwei Runs byte-identisch sein — at_cell/tree tragen die realen, je Lauf
|
||||
# unterschiedlichen Wanduhr-at-Werte und dokumentieren damit die benannte Ausnahme (A0-20,
|
||||
# §5.14 Pkt. 3): differenzieren dürfen ausschließlich diese beiden; der Rest ist byte-identisch.
|
||||
filtered_a=$(grep -vE '^(at_cell|tree)=' "$ROOT/receipts/run2a.receipt")
|
||||
filtered_b=$(grep -vE '^(at_cell|tree)=' "$ROOT/receipts/run2b.receipt")
|
||||
at_a=$(grep '^at_cell=' "$ROOT/receipts/run2a.receipt" | cut -d= -f2)
|
||||
at_b=$(grep '^at_cell=' "$ROOT/receipts/run2b.receipt" | cut -d= -f2)
|
||||
tree_a=$(grep '^tree=' "$ROOT/receipts/run2a.receipt" | cut -d= -f2)
|
||||
tree_b=$(grep '^tree=' "$ROOT/receipts/run2b.receipt" | cut -d= -f2)
|
||||
# (a) die deterministischen Bestandteile: byte-identisch
|
||||
if [ "$filtered_a" != "$filtered_b" ]; then
|
||||
echo "HARD-FAIL (DET-2): deterministische Receipt-Bestandteile weichen ab (AD-16-Klassifikationsdefekt, ausserhalb der at-Ausnahme; §5.14 Pkt. 2/4):" >&2
|
||||
diff -u <(printf '%s\n' "$filtered_a") <(printf '%s\n' "$filtered_b") >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
# (b) at-Ausnahme benannt vorhanden (dokumentierte Ausnahme, kein stiller Ausschluss)
|
||||
[ -n "$at_a" ] || { echo "HARD-FAIL (DET-2): at-Ausnahme-Cell fehlt in receipt A" >&2; exit 1; }
|
||||
[ -n "$at_b" ] || { echo "HARD-FAIL (DET-2): at-Ausnahme-Cell fehlt in receipt B" >&2; exit 1; }
|
||||
[ -n "$tree_a" ] && [ -n "$tree_b" ] || { echo "HARD-FAIL (DET-2): tree-Cell fehlt in einem Receipt" >&2; exit 1; }
|
||||
# P-7-Assertion: die aktive Ausnahme ist jetzt hart belegt (Wiederholungs-Schleife oben
|
||||
# hat at_a != at_b erzwungen) — kein stilles „BEFUND: at-Grenzfall" mehr.
|
||||
[ "$at_a" != "$at_b" ] || { echo "HARD-FAIL (DET-2): at-Ausnahme nicht demonstriert — beide Läufe tragen identischen at-Wert (P-7: aktive Ausnahme-Assertion)" >&2; exit 1; }
|
||||
echo " BEFUND: at-Ausnahme aktiv (assertiert) — Lauf A at=$at_a, Lauf B at=$at_b (benannte Ausnahme, §5.14 Pkt. 3: übrige Bestandteile byte-identisch)"
|
||||
# (d) Der deterministische Content weicht als Ganzes von der Baseline ab (Witness, echte Hashes).
|
||||
ABS_A=$(git -C "$ROOT/wt-a" show "$BASE:wiki/alpha.md" | sha256sum | cut -d' ' -f1)
|
||||
SHA_A=$(git -C "$ROOT/wt-a" show 'HEAD:wiki/alpha.md' | sha256sum | cut -d' ' -f1)
|
||||
[ -n "$ABS_A" ] && [ -n "$SHA_A" ] || { echo "HARD-FAIL (DET-2): Witness-Hashes leer (Vakuum — Assertion wertlos)" >&2; exit 1; }
|
||||
[ "$ABS_A" != "$SHA_A" ] || { echo "HARD-FAIL (DET-2): Witness == Baseline (vakuum — der Vergleich bewiese nichts; AD-17h/A0-19: echte Content-Identität gefordert)" >&2; exit 1; }
|
||||
# verified wird NICHT pauschal maskiert: das demonstrierte Bundle trägt ausschließlich die
|
||||
# Identitätswerte generated.by + generated.at (kein verified[]-Feld — die Ausnahme-Menge ist
|
||||
# in diesem Mini-Bundle exakt {generated.at}); die einzige erlaubte Differenz der
|
||||
# Bundle-State-Vergleiche ist die benannte at-Ausnahme (Pkt. 3), die hier als at_cell real
|
||||
# committet und beim Vergleich dokumentiert normalisiert ist (kein Maskieren vor Commit,
|
||||
# kein stiller Ausschluss — eine weitere Differenz würde den deterministischen Abgleich brechen).
|
||||
echo " WITNESS: Baseline-alpha-SHA ($ABS_A) != Run-alpha-SHA ($SHA_A) — der Zwei-Run-Vergleich ist nicht-vakuum (Content weicht von Baseline ab, echte Hashes)"
|
||||
echo " MANIFEST: $ROOT/manifest.yaml (identisch für beide Läufe, VOR jedem Lauf validiert); RECEIPTS: $ROOT/receipts/ (außerhalb des Bundles)"
|
||||
echo "RESULT: PASS — DET-2: ZWEI_RUN_IDENTISCH — zwei frische Agent-Kontexte in getrennt aufgebauten, sauberen Worktrees (wt-a/wt-b, demselben committeten Baum) produzieren identische Bundle-States (Run-Receipts byte-identisch bis auf die als at_cell ausgewiesene generated.at-Ausnahme: Plan-, order-, decisions-, log-, index-, alpha-Content-Hashes und Bundle-TREE; at real committet und erst beim Vergleich normalisiert — dokumentierte Ausnahme statt stiller Ausschluss); Vergleich nicht-vakuum (Witness vs. Baseline, echte Content-Hashes, §5.14 Pkt. 2, FT-10/AD-17h AC-1, Q-6/A0-19)"
|
||||
|
||||
# =====================================================================================
|
||||
# DET-3 ZWEI_RUN_ABWEICHUNG (§5.14 Pkt. 4)
|
||||
# =====================================================================================
|
||||
runlabel "DET-3: ZWEI_RUN_ABWEICHUNG — künstlich divergenter Lauf -> als AD-16-Klassifikationsdefekt klassifiziert und textuell benannt (kein Rauschen); korrigierter zweiter Lauf == erster Lauf (erneut bestätigt)"
|
||||
# Referenz-Run (deterministische Bundle-State-Projektion)
|
||||
run3_ref() {
|
||||
isolate run3ref
|
||||
cat > raw/alpha-v2.md <<'EOF'
|
||||
### S-3
|
||||
Evidenz v2: Alpha erweitert um eine synchrone Kopplung.
|
||||
EOF
|
||||
git add -A && git commit -qm "Evidenz v2"
|
||||
cat > wiki/alpha.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/alpha-v1.md
|
||||
id: s1
|
||||
- resource: raw/alpha-v2.md
|
||||
id: s3
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: AT
|
||||
---
|
||||
Das Alpha-Protokoll definiert eine deterministische Init-Sequenz (raw/alpha-v1.md#S-1).
|
||||
Alpha verwendet ausschließlich lokale Netze (raw/alpha-v1.md#S-2).
|
||||
Alpha wird um eine synchrone Kopplung erweitert (raw/alpha-v2.md#S-3).
|
||||
EOF
|
||||
git add -A && git commit -qm "Run: alpha-Update (Referenz)"
|
||||
echo "SHA=$(git show 'HEAD:wiki/alpha.md' | sha256sum | cut -d' ' -f1)"
|
||||
}
|
||||
# Divergenter Run: veränderter Body-Content (RAUSCHEN-fremde Abweichung — ein deterministischer
|
||||
# Bestandteil weicht ab, hier eine andere Formulierung der Aussage) trotz gleichem Git-State+Input.
|
||||
run3_div() {
|
||||
isolate run3div
|
||||
cat > raw/alpha-v2.md <<'EOF'
|
||||
### S-3
|
||||
Evidenz v2: Alpha erweitert um eine synchrone Kopplung.
|
||||
EOF
|
||||
git add -A && git commit -qm "Evidenz v2"
|
||||
cat > wiki/alpha.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/alpha-v1.md
|
||||
id: s1
|
||||
- resource: raw/alpha-v2.md
|
||||
id: s3
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: AT
|
||||
---
|
||||
Das Alpha-Protokoll definiert eine deterministische Init-Sequenz (raw/alpha-v1.md#S-1).
|
||||
Alpha verwendet ausschließlich lokale Netze (raw/alpha-v1.md#S-2).
|
||||
Alpha wird um eine SYNCHRONE KOPPLUNG erweitert (raw/alpha-v2.md#S-3).
|
||||
EOF
|
||||
git add -A && git commit -qm "Run: alpha-Update (divergent)"
|
||||
echo "SHA=$(git show 'HEAD:wiki/alpha.md' | sha256sum | cut -d' ' -f1)"
|
||||
}
|
||||
R3=$(run3_ref)
|
||||
D3=$(run3_div)
|
||||
echo "Referenz-Run: $R3"
|
||||
echo "Divergenter Lauf: $D3"
|
||||
SHA_REF=$(echo "$R3" | cut -d= -f2)
|
||||
SHA_DIV=$(echo "$D3" | cut -d= -f2)
|
||||
[ -n "$SHA_REF" ] && [ -n "$SHA_DIV" ] || { echo "HARD-FAIL (DET-3): Hashes leer (Vakuum)" >&2; exit 1; }
|
||||
if [ "$SHA_REF" = "$SHA_DIV" ]; then
|
||||
echo "HARD-FAIL (DET-3): der divergente Lauf blieb inspiziert ununterscheidbar (Abweichung nicht erkannt; §5.14 Pkt. 4 verlangt Klassifikation)" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "NFR-4-Benennung (textuell): ZWEI_RUN_ABWEICHUNG — Lauf 'divergent' weicht ausserhalb der benannten at-Ausnahme vom Referenz-Lauf ab (unterschiedlicher Content-Hash $SHA_DIV != $SHA_REF bei gleichem Git-State + gleichem Eingabeset) => AD-16-Klassifikationsdefekt (FT-10/AD-17h-AC), kein Rauschen; der Run wird als Fehler im Klassifikations-Mechanismus behandelt, textuell benannt und korrigiert/zurückgerollt (§5.14 Pkt. 4, Zustands-Restaurations-Invariante §5.13 Pkt. 3)"
|
||||
echo "--- Korrigierter zweiter Lauf: rollt zurueck und wiederholt deterministisch (== Referenz) ---"
|
||||
rollback3() {
|
||||
git checkout -q "$BASE" -- wiki/ 2>/dev/null || true
|
||||
git reset -q --hard "$BASE"
|
||||
git clean -qfd wiki
|
||||
}
|
||||
rollback3
|
||||
R3B=$(run3_ref)
|
||||
SHA_REFB=$(echo "$R3B" | grep '^SHA=' | cut -d= -f2)
|
||||
[ "$SHA_REF" = "$SHA_REFB" ] || { echo "HARD-FAIL (DET-3): korrigierte Wiederholung weicht von der Referenz ab (AD-17h verletzt)" >&2; exit 1; }
|
||||
echo " BEFUND: korrigierter Lauf == Referenz-Lauf (SHA $SHA_REF) — der Vertrag ist nach Korrektur erneut bestätigt (Pkt. 4: 'Befund wird (ggf. als korrigierter zweiter Lauf) erneut bestätigt')"
|
||||
echo "RESULT: PASS — DET-3: ZWEI_RUN_ABWEICHUNG — künstlich divergenter Lauf wurde als AD-16-Klassifikationsdefekt erkannt (Content-Hash-Differenz bei gleichem State+Input — kein Rauschen, keine Umgebungs-Streuung) und textuell benannt (NFR-4); korrigierter zweiter Lauf reproduziert den Referenz-Bundle-State (Zustands-Restaurations-Invariante, §5.13 Pkt. 3; §5.14 Pkt. 4)"
|
||||
|
||||
# =====================================================================================
|
||||
# DET-4 AT_GAP_AUSNAHME (§5.14 Pkt. 3)
|
||||
# =====================================================================================
|
||||
runlabel "DET-4: AT_GAP_AUSNAHME — generated.at-Wanduhr-Gap ist die einzige benannte Ausnahme; zwei Runs mit unterschiedlichem at -> diff ausschließlich auf der at-Zeile; nach at-Maskierung byte-identisch; jede andere Differenz = AD-16-Klassifikationsdefekt"
|
||||
isolate det4
|
||||
cat > raw/alpha-v2.md <<'EOF'
|
||||
### S-3
|
||||
Evidenz v2: Alpha erweitert um eine synchrone Kopplung.
|
||||
EOF
|
||||
git add -A && git commit -qm "Evidenz v2"
|
||||
mkrun4() { # $1 = at-Wert — schreibt alpha mit EXAKT unterschiedlichen at-Werten
|
||||
cat > wiki/alpha.md <<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: $1
|
||||
---
|
||||
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
|
||||
}
|
||||
mkrun4 "2026-08-16T09:00:00Z"
|
||||
git add -A && git commit -qm "Run at=A"
|
||||
mkrun4 "2026-08-19T23:59:59Z"
|
||||
git add -A && git commit -qm "Run at=B"
|
||||
# diff zwischen beiden Run-Zuständen: ausschließlich die at-Zeile
|
||||
DABC=$(git diff HEAD~1 HEAD -- wiki/alpha.md)
|
||||
[ -n "$DABC" ] || { echo "HARD-FAIL (DET-4): die zwei Runs sind identisch — at-Gap nicht demonstriert (Vakuum)" >&2; exit 1; }
|
||||
non_at=$(echo "$DABC" | grep '^[-+][^-+]' | grep -v '^[-+] at: ' | grep -v '^[+-][+-]')
|
||||
if [ -n "$non_at" ]; then
|
||||
echo "HARD-FAIL (DET-4): der diff zwischen den zwei Runs betrifft BESTANDTEILE ausserhalb der at-Ausnahme:" >&2
|
||||
echo "$non_at" | sed 's/^/ /' >&2
|
||||
exit 1
|
||||
else
|
||||
echo " BEFUND: diff ausschließlich auf der at-Zeile (einzige benannte Ausnahme, §5.14 Pkt. 3)"
|
||||
fi
|
||||
echo "--- Nach at-Maskierung byte-identisch (restliche Bundle-Bestandteile) ---"
|
||||
H1=$(git show HEAD~1:wiki/alpha.md | sed 's/^ at: .*/ at: AT/' | sha256sum | cut -d' ' -f1)
|
||||
H2=$(git show HEAD:wiki/alpha.md | sed 's/^ at: .*/ at: AT/' | sha256sum | cut -d' ' -f1)
|
||||
[ "$H1" = "$H2" ] || { echo "HARD-FAIL (DET-4): nach at-Maskierung weichen die Runs ab (bestandteil über at hinaus; §5.14 Pkt. 3 verlangt byte-Identität der übrigen Teile)" >&2; exit 1; }
|
||||
echo " BEFUND: nach at-Maskierung byte-identisch (SHA $H1) — dokumentierte Ausnahme, kein stiller Ausschluss"
|
||||
echo "--- Negative Kontrolle: eine Differenz AUSSERHALB der Ausnahme ist ein AD-16-Klassifikationsdefekt ---"
|
||||
mkrun4 "2026-08-16T09:00:00Z"
|
||||
printf '\nAndere Aussagenformulierung.\n' >> wiki/alpha.md
|
||||
git add -A && git commit -qm "Run at=B' (Differenz im Body)"
|
||||
non_at2=$(git diff HEAD~1 HEAD -- wiki/alpha.md | grep '^[-+][^-+]' | grep -v '^[-+] at: ' | grep -v '^[+-][+-]')
|
||||
[ -n "$non_at2" ] || { echo "HARD-FAIL (DET-4): Body-Differenz wurde nicht erkannt (Negativkontrolle leer)" >&2; exit 1; }
|
||||
echo "NFR-4-Benennung (textuell): Body-Differenz ausserhalb der at-Ausnahme-Menge => AD-16-Klassifikationsdefekt (kein Rauschen), textuell benannt (§5.14 Pkt. 3/4)"
|
||||
echo "RESULT: PASS — DET-4: AT_GAP_AUSNAHME — generated.at-Wanduhr-Gap ist die einzige benannte Differenz im Bundle-State-Vergleich (A0-20-Konvention, §5.9 Pkt. 2/§5.10 Pkt. 8): zwei Runs diffieren ausschließlich in der at-Zeile, nach at-Maskierung byte-identisch; jede andere Differenz liegt ausserhalb der Ausnahme = AD-16-Klassifikationsdefekt (Negativkontrolle, §5.14 Pkt. 3)"
|
||||
|
||||
# =====================================================================================
|
||||
# DET-5 EM_DASH (§3.2 Pkt. 1b, §5.14 Pkt. 5)
|
||||
# =====================================================================================
|
||||
runlabel "DET-5: EM_DASH — Em-Dash — normalisiert auf dieselbe canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen (§3.2 Pkt. 1b: Kollaps-Klasse [-–— _] -> -)"
|
||||
# Term-Basis mit Em-Dash / En-Dash / Bindestrich / Unterstrich / Leerzeichen-Separator
|
||||
EM=$(norm "wissen — relevanz")
|
||||
EN=$(norm "wissen – relevanz")
|
||||
HY=$(norm "wissen - relevanz")
|
||||
US=$(norm "wissen_relevanz")
|
||||
SP=$(norm "wissen relevanz")
|
||||
[ "$EM" = "$EN" ] || { echo "HARD-FAIL (DET-5): Em-Dash-Form != En-Dash-Form" >&2; exit 1; }
|
||||
[ "$EM" = "$HY" ] || { echo "HARD-FAIL (DET-5): Em-Dash-Form != Bindestrich-Form" >&2; exit 1; }
|
||||
[ "$EM" = "$US" ] || { echo "HARD-FAIL (DET-5): Em-Dash-Form != Unterstrich-Form" >&2; exit 1; }
|
||||
[ "$EM" = "$SP" ] || { echo "HARD-FAIL (DET-5): Em-Dash-Form != Leerzeichen-Form" >&2; exit 1; }
|
||||
case "$EM" in
|
||||
*"—"*) echo "HARD-FAIL (DET-5): Em-Dash blieb in der canonischen Form erhalten (Kollaps-Klasse greift nicht)" >&2; exit 1;;
|
||||
esac
|
||||
echo " canonische Form (alle fünf Separatoren): '$EM'"
|
||||
echo " Em-Dash-Term kollabiert auf dieselbe canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen (kein stiller Ausschluss, §3.2 Pkt. 1b)"
|
||||
echo "RESULT: PASS — DET-5: EM_DASH — Em-Dash — ist in der Kollaps-Klasse [-–— _] -> - (§3.2-Pkt.-1b-Ergänzung, §5.14 Pkt. 5): Term mit Em-Dash erhält dieselbe canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen-Varianten — deterministisch, keine unterschiedliche canonische Form je Separator"
|
||||
|
||||
# =====================================================================================
|
||||
# DET-6 KOLLAPS (§3.2 Pkt. 1b, §5.14 Pkt. 5)
|
||||
# =====================================================================================
|
||||
runlabel "DET-6: KOLLAPS — Kollaps-Reichweite: Läufe (a--b), führende (-x), trailende (x-) -> Kollaps auf genau ein - + Trim (§3.2 Pkt. 1b)"
|
||||
[ "$(norm "a--b")" = "a-b" ] || { echo "HARD-FAIL (DET-6): Lauf a--b kollabiert nicht auf a-b (norm='$(norm "a--b")')" >&2; exit 1; }
|
||||
[ "$(norm "-x")" = "x" ] || { echo "HARD-FAIL (DET-6): führender Separator -x wird nicht getrimmt (norm='$(norm "-x")')" >&2; exit 1; }
|
||||
[ "$(norm "x-")" = "x" ] || { echo "HARD-FAIL (DET-6): trailender Separator x- wird nicht getrimmt (norm='$(norm "x-")')" >&2; exit 1; }
|
||||
[ "$(norm "a--b")" = "a-b" ] && [ "$(norm "a---b")" = "a-b" ] && [ "$(norm "---x---")" = "x" ] || { echo "HARD-FAIL (DET-6): Läufe/Trim-Kombination inkonsistent" >&2; exit 1; }
|
||||
echo " Läufe a--b -> '$(norm "a--b")'; führend -x -> '$(norm "-x")'; trailend x- -> '$(norm "x-")'"
|
||||
echo "RESULT: PASS — DET-6: KOLLAPS — Kollaps-Reichweite deterministisch (§3.2 Pkt. 1b, §5.14 Pkt. 5): Läufe kollabieren auf genau ein -, führende/trailende Separatoren werden getrimmt — glaubhaft re-executierbar, keine offene Reichweiten-Frage"
|
||||
|
||||
# =====================================================================================
|
||||
# DET-7 MATCH_SCOPE (§3.2 Pkt. 2a, §5.14 Pkt. 5)
|
||||
# =====================================================================================
|
||||
runlabel "DET-7: MATCH_SCOPE — Stufe a matcht ganze Wörter über den Body, exklusive YAML-Frontmatter (Substring-/Frontmatter-Treffer ausgeschlossen, §3.2 Pkt. 2a)"
|
||||
isolate det7
|
||||
# Concept: Body enthält "kopplung" als GANZES Wort; Frontmatter enthält "kopplung" als
|
||||
# Substring im Quell-Pfad raw/kopplung-v1.md (Frontmatter-Treffer-Wächter).
|
||||
cat > wiki/alpha.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/kopplung-v1.md
|
||||
id: s1
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-16T09:00:00Z
|
||||
---
|
||||
Alpha als Wissenseinheit: hier steht einzig das ganz Wort kopplung ohne weitere Bindung.
|
||||
EOF
|
||||
cat > wiki/gamma.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/gamma-v1.md
|
||||
id: s1
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-16T09:00:00Z
|
||||
---
|
||||
Gamma: das Wort entkopplung belegt nur einenerweiternden Teil — kein eigener ganzer Treffer.
|
||||
EOF
|
||||
git add -A && git commit -qm "Stufe-a-Flex"
|
||||
# 1) Substring-Kontrolle: 'kopplung' (ganz) trifft alpha; 'opplung' (Substring) trifft nichts
|
||||
HIT1=$(match_stufe_a "kopplung" wiki/alpha.md wiki/gamma.md)
|
||||
[ "$HIT1" = "alpha" ] || { echo "HARD-FAIL (DET-7): ganzes-Wort-Match 'kopplung' liefert '$HIT1' (Soll: alpha; Substring-/Gamma-Treffer unerlaubt)" >&2; exit 1; }
|
||||
HIT2=$(match_stufe_a "opplung" wiki/alpha.md)
|
||||
[ -z "$HIT2" ] || { echo "HARD-FAIL (DET-7): Substring-Match 'opplung' liefert einen Kandidaten (Stufe a matcht ganze Wörter, §3.2 Pkt. 2a)" >&2; exit 1; }
|
||||
# 2) Frontmatter-Exklusion: Suchbegriff exakt gleich einem Frontmatter-RESOURCE-Substring
|
||||
# (raw/kopplung-v1.md enthält 'kopplung') — zugleich im Body von alpha steht 'kopplung'
|
||||
# nur als ganzes Wort => Treffer genau EINMAL (alpha). Der Frontmatter ist exkludiert,
|
||||
# ein zusätzlicher Body-Treffer erzeugt keinen zweiten Kandidaten — wir prüfen, dass
|
||||
# das Frontmatter-Vorkommen keinen falschen Kandidaten (z. B. durch RegExp über die ganze
|
||||
# Datei inkl. Frontmatter) erzeugt. Konkret: wir legen einen zweiten Concept-Body VOR, der
|
||||
# 'kopplung' NUR im Frontmatter traegt (Quell-Pfad raw/kopplung-mirror.md) — Stufe a muss
|
||||
# ihn verwerfen, weil der Frontmatter exkludiert ist.
|
||||
cat > wiki/mirror.md <<'EOF'
|
||||
---
|
||||
type: concept
|
||||
sources:
|
||||
- resource: raw/kopplung-mirror.md
|
||||
id: s1
|
||||
generated:
|
||||
by: wow-compiler/0.1.0
|
||||
at: 2026-08-16T09:00:00Z
|
||||
---
|
||||
Gamma-Mirror ohne Kopplungs-Begriff im Bodytext.
|
||||
EOF
|
||||
git add -A && git commit -qm "Frontmatter-only-Kandidat"
|
||||
HIT3=$(match_stufe_a "kopplung" wiki/alpha.md wiki/gamma.md wiki/mirror.md)
|
||||
[ "$HIT3" = "alpha" ] || { echo "HARD-FAIL (DET-7): Frontmatter-Treffer erzeugt Kandidat (mirror) — Stufe a matcht nur Body, exklusive YAML-Frontmatter (§3.2 Pkt. 2a)" >&2; exit 1; }
|
||||
# 3) Direkte Formel-Probe der operativen Stufe-a-Formel (§3.2-Pkt.-2a-Zweistufen-Mechanik):
|
||||
# Sweep mit der Formel -> dann deterministischer Scope-Filter (ganze Wörter, Body, after second ---).
|
||||
SWEEP=$(grep -rl 'kopplung' --exclude=log.md wiki/ | LC_ALL=C sort)
|
||||
# Sweep-muss alpha, gamma (Substring entkopplung) und mirror (Frontmatter-only) finden —
|
||||
# der Scope-Filter verwirft gamma+mirror; als Kandidaten bleiben die Body-ganz-Wort-Treffer.
|
||||
FILTERED=$(for f in $SWEEP; do
|
||||
if match_stufe_a "kopplung" "$f" | grep -q .; then basename "$f" .md; fi
|
||||
done | LC_ALL=C sort | tr '\n' ' ')
|
||||
FILTERED="${FILTERED% }"
|
||||
[ "$FILTERED" = "alpha" ] || { echo "HARD-FAIL (DET-7): operative Stufe-a-Zweistufen-Mechanik liefert '$FILTERED' (Soll: alpha) — Scope-Filter unvollständig (§3.2 Pkt. 2a, §5.14 Pkt. 5)" >&2; exit 1; }
|
||||
echo " Direkte Formel-Probe: Sweep (grep -rl) -> Scope-Filter verwirft Substring-/Frontmatter-Treffer -> Kandidat: alpha"
|
||||
echo "RESULT: PASS — DET-7: MATCH_SCOPE — Stufe a matcht ganze Wörter (Wortgrenzen) über den Body, exklusive YAML-Frontmatter: Substring-Treffer ('opplung') und Frontmatter-only-Kandidaten (mirror) liefern keine Kandidaten (§3.2 Pkt. 2a, §5.14 Pkt. 5) — deterministischer Stufe-a-Scope, keine falschen Kandidaten; operative Zweistufen-Mechanik (Sweep+Filter) abgesichert"
|
||||
|
||||
# =====================================================================================
|
||||
# DET-8 ORPHAN (§5.10 Pkt. 8, §5.14 Pkt. 5)
|
||||
# =====================================================================================
|
||||
runlabel "DET-8: ORPHAN — neu committete raw/-Evidenz ohne Ziel-Pfad-Treffer -> unzugeordnet, log.md-verwaist protokolliert (Datumsgruppe, <Baseline-Commit>), kein Banner, keine stille Vorbearbeitung, keine eigenständige Anlage (AD-16-Default)"
|
||||
isolate det8
|
||||
cat > raw/orphan-v1.md <<'EOF'
|
||||
### S-1
|
||||
Evidenz: gänzlich fremdes Thema, das in keinem bestehenden Concept-Body Wort-Treffer hat.
|
||||
EOF
|
||||
git add -A && git commit -qm "Verwaiste Evidenz"
|
||||
# Ziel-Pfad-Treffer-Prüfung: Term über die neuen Quellen enthält 'fremdes-thema' — kein
|
||||
# bestehender Concept-Body trifft (Stufe a, deterministisch); kein Update-Kandidat.
|
||||
CAND=$(match_stufe_a "fremdes" wiki/alpha.md wiki/gamma.md)
|
||||
[ -z "$CAND" ] || { echo "HARD-FAIL (DET-8): verwaiste Evidenz erzielt einen Ziel-Pfad-Treffer (Kein-Orphan erwartet)" >&2; exit 1; }
|
||||
# Reconcile-Orphan-Regel (§5.10 Pkt. 8 / §5.14 Pkt. 5): deterministisch aus dem committeten
|
||||
# Git-State (Zuwachs gg. <Baseline-Commit>) als verwaist befunden -> datumsgruppierter
|
||||
# log.md-Eintrag (Header YYYY-MM-DD, Quell-Pfad + <Baseline-Commit>); keine eigenständige Anlage.
|
||||
log_bullet "- Reconcile-Orphan (Story 3.8; §5.10 Pkt. 8 / §5.14 Pkt. 5): raw/orphan-v1.md (Zuwachs gg. <Baseline $BASE>) ohne Ziel-Pfad-Treffer — unzugeordnet, verwaist protokolliert; kein Banner, keine stille Vorbearbeitung, keine eigenständige Anlage (AD-16-Default, Epic-4-Interface)"
|
||||
echo "--- Kein Banner / keine stille Vorbearbeitung / keine eigenständige Anlage ---"
|
||||
if [ -f wiki/orphan.md ]; then
|
||||
echo "HARD-FAIL (DET-8): verwaiste Evidenz wurde eigenständig als Concept angelegt (verboten, AD-16-Default)" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Nur log.md ist mutiert (Orphan-Eintrag) — Erhaltungs-Invariante §5.9 Pkt. 5 (log.md ist
|
||||
# erlaubtes Mitglied des Diff-Selbsttest-Satzes); keine weiteren Mutations-Pfade.
|
||||
MUT=$( { git diff --name-only "$BASE" -- wiki/ ; git status --porcelain -- wiki/ | awk '{print $2}'; } | sed -e 's|^wiki/||' -e 's|\.md$||' | LC_ALL=C sort -u)
|
||||
[ "$MUT" = "log" ] || { echo "HARD-FAIL (DET-8): Verwaist-Run mutiert ausserhalb {log} — Pfade: [$MUT]" >&2; exit 1; }
|
||||
grep -qF "Reconcile-Orphan" wiki/log.md || { echo "HARD-FAIL (DET-8): Verwaist-Protokoll fehlt in log.md (§5.10 Pkt. 8)" >&2; exit 1; }
|
||||
grep -qF "## 2026-08-20" wiki/log.md || { echo "HARD-FAIL (DET-8): log.md-Eintrag nicht in Datumsgruppe (Vertrag §5)" >&2; exit 1; }
|
||||
grep -qF "$BASE" wiki/log.md || { echo "HARD-FAIL (DET-8): <Baseline-Commit> fehlt im Verwaist-Eintrag (§5.10 Pkt. 8, deterministisch auflösbar D-2)" >&2; exit 1; }
|
||||
echo " BEFUND: raw/orphan-v1.md bleibt in raw/ unangetastet (AD-3); log.md trägt datumsgruppierten Verwaist-Eintrag mit <Baseline-Commit>"
|
||||
echo "RESULT: PASS — DET-8: ORPHAN — neu committete raw/-Evidenz ohne Ziel-Pfad-Treffer bleibt unzugeordnet und wird als datumsgruppierter log.md-Eintrag (Quell-Pfad + <Baseline-Commit>) verwaist protokolliert (§5.10 Pkt. 8 / §5.14 Pkt. 5): kein Banner, keine stille Vorbearbeitung, keine eigenständige Anlage (AD-16-Default) — Erhaltungs-Invariante gewahrt (nur log.md mutiert)"
|
||||
|
||||
echo
|
||||
echo "===== Sandbox abgeschlossen (DET-1..DET-8) ====="
|
||||
echo "Sandbox-Root: $ROOT (loeschbar: rm -rf $ROOT)"
|
||||
File diff suppressed because it is too large
Load Diff
+267
@@ -0,0 +1,267 @@
|
||||
---
|
||||
title: 'Story 3.8 — Determinismus-Vertrag (AD-17h) als Agent-Instruktions-Validator umsetzen'
|
||||
type: 'feature'
|
||||
created: '2026-08-20'
|
||||
status: 'done'
|
||||
baseline_commit: 'c4cdf4b93e17b3f84dff03a4bd5608251be56268'
|
||||
review_loop_iteration: 2 # Review-Loop-3 (2026-08-20): abgeschlossene Review-Loops (1, 2); in Loop-1/2 nicht gepflegt (0) — ab Loop-3 gepflegt (P-10)
|
||||
course_correction: '_bmad-output/planning-artifacts/sprint-change-proposal-2026-08-20.md'
|
||||
context:
|
||||
- '_bmad-output/implementation-artifacts/epic-3-context.md'
|
||||
---
|
||||
|
||||
<frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates">
|
||||
|
||||
## Re-Open-Delta (Story-3.8-Neu-Verhandlung, 2026-08-20)
|
||||
|
||||
**Neu verhandelt durch genehmigtes Sprint-Change-Proposal** — `_bmad-output/planning-artifacts/sprint-change-proposal-2026-08-20.md` (Status: approved; approved_by: ProMods; explizite Chat-Freigabe). Der Plan korrigiert die zyklische Behauptung, Story 3.8 sei abgeschlossen, während Epic 3 seine zugesagten Verträge noch nicht als kohärentes System-Inkrement belegt. Story 3.8 wurde daher aus `review` nach `in-progress` **zurückgenommen** und mit erweitertem Scope wieder eröffnet (Epics-Datei ACs Z. 357–370):
|
||||
|
||||
1. **Getrennte Worktrees + frische Agent-Kontexte (Q-6/A0-19):** „zwei frische Agent-Kontexte in getrennt aufgebauten Worktrees; eine zweite Ausführung in derselben Session genügt nicht".
|
||||
2. **Kanonisches Eingabemanifest:** hält Baseline-Commit, geordnete Source-Eingaben und jeden im Bundle sichtbaren Run-/Zeit-/Identitätswert explizit fest.
|
||||
3. **Run-Receipt außerhalb des Knowledge Bundle:** Candidate-Liste, Reihenfolge, Plan, Entscheidungen und Output-Hashes.
|
||||
4. **Keine Hartcodes, kein pauschales Maskieren:** weder erwartete Pläne noch Concept-Bodies werden im Test hart codiert; `verified`-Ereignisse werden niemals pauschal aus dem Vergleich maskiert.
|
||||
|
||||
Dieser Frozen-Intent wurde **nur in dem Umfang** geändert, den dieses Re-Open-Delta verlangt (document-human respektierend [Tippfehler-Korrektur Review-Loop-3, D-3 — autorisierte Neu-Verhandlung, dokumentiert im Spec Change Log]; Appendix: fehlendes `</frozen-after-approval>`-Schließtag nach dem Spec Change Log ergänzt). Die ACs in `_bmad-output/planning-artifacts/epics.md` (Z. 357–370) sind die verbindliche Neu-Verhandlung; abweichende Alt-Formulierungen (namentlich „in einer Session") sind auf den Re-Open-Stand korrigiert.
|
||||
|
||||
## Intent
|
||||
|
||||
**Problem:** AD-17h/FT-10/A0-19 verlangen: Über denselben Git-State + dasselbe Eingabeset erzeugen **zwei unabhängige Runs denselben Bundle-State**; eine Abweichung ist ein Fehler der AD-16-Klassifikation, kein Rauschen. Das **Enforcement** lebt im MVP (D-3, Q-6) als **Agent-Instruktions-Validator** und muss **mechanisch bestätigt** sein, bevor es tragend wird. Der Ist-Zustand der Instruktion verankert den Vertrag zwar an vielen Stellen (AD-17h-Rückverweise in §3.2/§5.9/§5.10/§5.11/§5.12/§5.13), aber es fehlt die **geschlossene, aus dem committeten Git-State ableitbare Bestätigungs-Mechanik**: Es gibt keinen normativen Ort, der definiert, (a) was genau der „Bundle-State" ist, (b) wie die Zwei-Run-Bestätigung mechanisch abläuft, (c) welche **Ausnahmen** vom byte-identischen Vergleich gelten (namentlich der dokumentierte `generated.at`-Wanduhr-Gap, A0-20) und (d) wie eine festgestellte Abweichung klassifiziert wird (AD-16-Klassifikationsfehler). Mehrere bekannte Lücken sind hierher gewandert (Em-Dash-Normalisierung, Kollaps-Reichweite, Match-Scope, `at`-Gap, Orphan-Politik, Misch-Run-Coverage).
|
||||
|
||||
**Approach:** Neue Sektion **§5.14 „Determinismus-Vertrag & Agent-Instruktions-Validator (Story 3.8)"** (nach §5.13, vor §6): definiert (1) den **Bundle-State** als deterministische Projektion des committeten Git-States (vergleichbare Zustandsmenge, `at`-Feld als benannte Ausnahme), (2) die **Zwei-Run-Bestätigungs-Mechanik** als textuell festgehaltenes, re-executierbares Prüfverfahren — im Re-Open-Stand in **zwei getrennten, sauberen Worktrees** mit **frischen Agent-Kontexten** (Q-6/A0-19; eine zweite Ausführung in derselben Session genügt nicht); Vergleichs-Operandum = committeter Baum; identische Plan-/Kandidaten-/Reihenfolge-Outputs; kein neuer Prozess/Server/MCP, D-3 — unter einem **kanonischen Eingabemanifest** (Baseline-Commit, geordnete Source-Eingaben, output-sichtbare Run-/Zeit-/Identitätswerte) und mit einem **Run-Receipt** (Candidate-Liste, Reihenfolge, Plan, Entscheidungen, Output-Hashes) **außerhalb des Knowledge Bundle**; (3) die **Ausnahme-Menge** des Bundle-State-Vergleichs (der `generated.at`-Wanduhr-Gap als dokumentierte A0-20-Konvention; sonst byte-identisch) und (4) die **Abweichungs-Klassifikation** (jede Abweichung außerhalb der Ausnahme = AD-16-Klassifikationsdefekt, textuell benannt, NFR-4). Die Zwei-Run-Bestätigung wird als **Sandbox-Szenario** mechanisch demonstriert (zwei Worktrees, zwei unabhängige Läufe); weder Pläne noch Concept-Bodies werden im Test hart codiert, `verified`-Ereignisse werden niemals pauschal aus dem Vergleich maskiert (nur die benannte `at`-Ausnahme). Die bekannten Lücken (Em-Dash, Kollaps-Reichweite, Match-Scope, Orphan) werden als **geschlossene, deterministische Regeln** in die Instruktion gehoben — keine offenen Fragen verbleiben, die die Zwei-Run-Identität gefährden.
|
||||
|
||||
## Boundaries & Constraints
|
||||
|
||||
**Always:**
|
||||
- Nur `schema/compiler.md` (neue §5.14 + §7-Auflösung des Determinismus-Vorbehalts + §8 Revisionslog **Revision 3.3** + gegebenenfalls Kollaps-/Match-Scope-/Orphan-Präzisierungen in §3.2/§5.10) mutiert (D-3). `schema/validator.md`, `schema/wiki-compiler.md`, `adapters/`, `raw/` **read-only** (AD-3). Kein Standalone (D-3), keine eigene Workflow-Engine/kein neuer Prozess/Server/MCP (AD-6, AD-11). Keine neue §7-Invaliditätsklasse, kein Vertrags-Change, kein neuer Prädikat-/Format-/Frontmatter-Key.
|
||||
- Deterministisch aus dem committeten Git-State ableitbar (AD-17h/A0-19): Bundle-State-Vergleich, Zwei-Run-Bestätigungs-Mechanik, Ausnahme-Menge, Abweichungs-Klassifikation. **Keine Wanduhr/`now`-Steuerung** der Bestätigungs-Mechanik.
|
||||
- Der `generated.at`-Wanduhr-Gap **bleibt als dokumentierte Ausnahme** bestehen (A0-20-Konvention, §5.9 Pkt. 2, §5.10 Pkt. 8, unverändert bindend bis Ask-First-Wechsel). §5.14 **definiert** die Behandlung von `at` im Bundle-State-Vergleich (Ausnahmemenge), ändert aber **nicht** das `generated.at`-Verhalten selbst.
|
||||
- Bei einer Abweichung zweier Runs: die Abweichung **ist** ein AD-16-Klassifikationsfehler (kein akzeptables Rauschen, FT-10/AD-17h-AC); die textuelle Benennung (NFR-4) ist verpflichtend.
|
||||
- Die **normalisierenden Lücken-Schließungen** (Em-Dash in der Kollaps-Klasse, Kollaps-Reichweite bei Läufen/führenden/trailenden Separatoren, Wortgrenzen-/Frontmatter-Scope der Stufe-a-Erhebung) werden als **deterministische Regel-Ergänzungen** in §3.2 umgesetzt — **append-only/kein Umbruch** des bestehenden §3.2-Wortlauts; die Orphan-Politik (§5.10 Pkt. 8) wird zu einer deterministischen Reconcile-Orphan-Regel präzisiert.
|
||||
- Die Bestätigung ist **agent-instruction-basiert (D-3, Q-6)**: **zwei frische Agent-Kontexte in getrennt aufgebauten (sauberen) Worktrees** führen die Instruktion jeweils einmal aus und belegen die Zwei-Run-Identität (Q-6, A0-19) — eine zweite Ausführung in derselben Session genügt nicht; kein dedizierter Validator-Prozess, keine extra Runtime.
|
||||
|
||||
**Ask First:**
|
||||
- **Änderung des `generated.at`-Verhaltens** selbst (z. B. Ableitung `at` aus dem Git-State statt Wanduhr) — §5.14 definiert nur seine Behandlung im Vergleich, der Konventionswechsel wäre Ask-First.
|
||||
- Einführung einer **eigenständigen, ausführbaren Validator-Datei** (separates Skript/Programm außerhalb der Instruktion als Enforcer) statt der textuellen Agent-Instruktions-Disziplin — wäre ein Realisierungswechsel weg vom D-3/Q-6-Modell.
|
||||
- Kollaps-Reichweite bei Läufen/führenden/trailenden Separatoren **anders** zu definieren als „Kollaps auf genau ein `-` + Trim" (z. B. Doppel-Bindestrich-Erhaltung) — jede andere Wahl bricht bestehende Sandbox-Erwartungen.
|
||||
- Umbenennung/Neudefinition der vorhandenen §3.2-Erhebungsstufen (a/b/c) oder deren Reihenfolge.
|
||||
|
||||
**Never:**
|
||||
- `raw/`-Inhalte verändern (AD-3); uncommittete fremde `wiki/`-Änderungen löschen (AD-17e); textueller Auto-Merge bei Branch-Konvergenz (AD-17c); Wanduhr/`now`-Zeitstempel als Bestätigungs-Steuergröße; eigener `# Log`-Stand in der Registry; Standalone-Compiler/eigene LLM-Runtime (D-3, AD-11); Änderung an `schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`; neuer Frontmatter-Key; neue §7-Invaliditätsklasse; neuer Prädikat-/Format-Key; eigene Workflow-Engine; neuer dedizierter Prozess/Server/MCP als Enforcer.
|
||||
|
||||
## I/O & Edge-Case Matrix
|
||||
|
||||
| Scenario | Input / State | Expected Output / Behavior | Error Handling |
|
||||
|----------|--------------|---------------------------|----------------|
|
||||
| BUNDLE_STATE_DEFINITION | gleicher committeter Git-State + gleiche Eingabemenge | Bundle-State definiert als deterministische Projektion: Datei-Gesamtheit unter `wiki/`/`raw/` gg. Baseline, Plan-/Kandidaten-/Reihenfolge-Outputs; `generated.at` als benannte Ausnahme | textuell begründet (NFR-4), keine Lücke |
|
||||
| ZWEI_RUN_IDENTISCH | zwei unabhängige Runs, gleicher Git-State + Eingabeset | identische Bundle-States bis auf benannte `at`-Ausnahme; Sandbox-Assertion nicht-vakuum (echte Content-Identität) | PASS; bei Abweichung außerhalb Ausnahme: AD-16-Klassifikationsdefekt |
|
||||
| ZWEI_RUN_ABWEICHUNG | zwei Runs, gleicher State, verschiedene Ausgabe | Abweichung = Fehler der AD-16-Klassifikation (kein Rauschen); textuell benannt, Run korrigiert/rollt zurück | NFR-4-Benennung; AD-17h-AC |
|
||||
| AT_GAP_AUSNAHME | zwei unabhängige Runs, gleicher Input | `generated.at` darf abweichen (A0-20-Konvention, §5.9 Pkt. 2) — einzige benannte Ausnahme im Bundle-State-Vergleich; übrige Teile byte-identisch | dokumentiert (kein stiller Ausschluss) |
|
||||
| NORMALISIERUNG_EM_DASH | Term mit Em-Dash `—` | Em-Dash in die Kollaps-Klasse aufgenommen (`[-–— _]`→`-`); identische canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen | deterministisch, kein stiller Ausschluss |
|
||||
| NORMALISIERUNG_KOLLAPS | Term mit Läufen/führenden/trailenden Separatoren | Kollaps-Reichweite definiert: Kollaps auf genau ein `-` + Trim (führende/trailende entfernt), Läufe auf ein `-` | deterministisch, glaubhaft re-executierbar |
|
||||
| MATCH_SCOPE_STUFE_A | Stufe-a-grep-Treffer mit/ohne Wortgrenze, Frontmatter-Treffer | Match-Semantik fixiert: ganzes Wort (Wortgrenzen), Frontmatter exkludiert (nur Body) | deterministisch, keine falschen Kandidaten |
|
||||
| ORPHAN_POLITIK | neu committete `raw/`-Evidenz ohne Ziel-Pfad-Treffer | Orphan bleibt unzugeordnet, wird in `log.md` als verwaist protokolliert, kein Banner, keine stille Vorbearbeitung | deterministische Reconcile-Orphan-Regel (AD-16-Default) |
|
||||
|
||||
## Code Map
|
||||
|
||||
- `schema/compiler.md` — **primär mutiert** (D-3): neue Sektion **§5.14 „Determinismus-Vertrag & Agent-Instruktions-Validator (Story 3.8)"** (nach §5.13, vor §6; Fixierung: §5.13-Ende Z. 362, §6-Start Z. 364 — neue Sektion zwischen beide, §5.14 Z. 365–377); §0-Phasen-Listentext **unverändert**; §5.13 Pkt. 7 „Home Story 3.8" — wird auf §5.14-**Anker** umgehängt (die `generated.at`-Gap-Ausnahme ist jetzt in §5.14 definiert statt nur deklariert; Home-Verweis bleibt, wird aber auf die §5.14-Definition verlagert); §3.2 Normalisierungs-Lücken (Em-Dash in Kollaps-Klasse Z. 51; Kollaps-Reichweite; Match-Scope Z. 55) — als Regel-Ergänzungen aufgelöst; §5.10 Pkt. 8 Orphan-Politik Z. 301 — zur deterministischen Reconcile-Orphan-Regel präzisiert; §7 (`Z. 424ff.`) Determinismus-Vorbehalt „Em-Dash-Lücke an Story 3.8 übergeben" — **aufgelöst**, Verankerung in §5.14 benannt; §8-Normreferenz `AD-17h` (`Z. 445`) auf **§5.14-Anker** angehoben (mit der `at`-Ausnahme-Nennung); Revisionslog-Eintrag **Revision 3.3** nach Z. 477. Anker (IST-Zeilen nach Review-Loop-3, 2026-08-20; P-1): §5.14-Sektion Z. 365 (Pkt. 1–5 = 369/370/375/376/377); §7-Determinismus-Bullet Z. 434; §8-AD-17h Z. 445; Revisionslog **Revision 3.3** Z. 477.
|
||||
- `wiki/log.md` — **append** (append-only, Vertrag §5): Story-3.8-Eintrag (Verankerung, Sandbox-Nachweis, Statuswechsel, Validator-Verdikt); bestehende Bullets unverändert.
|
||||
- `_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh` — **neu** (re-executierbar, Muster sandbox-3-7, Exit 0): Szenarien DET-1..DET-8 (s. Design Notes), harte Pass/Fail-Assertionen, Zwei-Run-Identität nicht-vakuum, keine Berührung des realen Ist-Baums.
|
||||
- `_bmad-output/implementation-artifacts/sprint-status.yaml` — **mutiert**: `3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato` `backlog` → `in-progress` (Implementierungs-Flip) → `review` (Review-Start-Flip, Step-04; finaler `done`-Flip im Step-05); `last_updated` (Format `MM-DD-YYYY HH:MM`, HEAD-Präzision).
|
||||
- `_bmad-output/implementation-artifacts/deferred-work.md` — **append** (append-only): ggf. Story-3.8-Defers; die bestehenden „Home: Story 3.8"-Einträge werden **aufgegriffen/geschlossen** — nicht als Nur-Read-markiert, sondern als aufgehobene Homes gekennzeichnet (Status-Eintragung). Stand: mehrere determinismus-bezogene Defer-Homes (Em-Dash, Kollaps, Match-Scope, Orphan, `at`-Gap, Misch-Run-Coverage) werden in §5.14/§3.2/§5.10 geschlossen; verbleibende Homes (falls nicht schließbar) bleiben offen mit verbleibendem Ziel.
|
||||
- `_bmad-output/implementation-artifacts/epic-3-context.md`, `spec-3-7-…md` — **read-only** (continue-context; Kette unverändert).
|
||||
|
||||
**Read-only evidence (AD-3):** `schema/validator.md`, `schema/wiki-compiler.md`, `adapters/`, `raw/` (inkl. `raw/architecture-spine/…md` AD-17h/Q-6/FT-10/D-3, `raw/epics/epics-2026-08-14.md` A0-19/A0-20 — normativer Rückbezug, keine Mutation). `schema/canonical-terms.md` bleibt append-only-Registry (keine Änderung an Bestandseinträgen; die Em-Dash-/Kollaps-Schließung lebt als Regel in `compiler.md` §3.2, nicht als Registry-Edits — §3.2-Pkt.-1b-Kollaps-Klasse ist die zentrale Normalisierungsregel).
|
||||
|
||||
## Tasks & Acceptance
|
||||
|
||||
**Execution:**
|
||||
- [x] `schema/compiler.md` — §5.14 einfügen (nach §5.13, vor §6): Bundle-State-Definition, Zwei-Run-Bestätigungs-Mechanik (agent-Instruktions-basiert, D-3/Q-6, re-executierbare Formeln), `at`-Ausnahme-Menge, Abweichungs-Klassifikation als AD-16-Klassifikationsdefekt; §0/§5.13/§6 Wortlaut-unverändert referenzieren; kein neuer Prädikat-/Format-/Frontmatter-Key
|
||||
- [x] `schema/compiler.md` — §3.2-Normalisierungs-Lücken schließen (Em-Dash-Klasse, Kollaps-Reichweite, Match-Scope der Stufe a) — als deterministische Regel-Ergänzungen ohne Umbruch des bestehenden §3.2-Wortlauts; Orphan-Politik §5.10 Pkt. 8 zur deterministischen Reconcile-Orphan-Regel präzisieren
|
||||
- [x] `schema/compiler.md` — Revision 3.3 in §8 belegen (AD-17h auf §5.14-Anker, `at`-Ausnahme-Nennung, Abschlussklausel); §7-Determinismus-Vorbehalt auflösen (Verankerung in §5.14)
|
||||
- [x] `_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh` — Szenarien DET-1..DET-8 (Bundle-State-Definition, Zwei-Run-identisch nicht-vakuum, Zwei-Run-Abweichung klassifiziert, `at`-Gap-Ausnahme, Em-Dash-, Kollaps-, Match-Scope-, Orphan-Szenario), Exit 0
|
||||
- [x] `_bmad-output/implementation-artifacts/sprint-status.yaml` — Key `3-8-…` → `in-progress` (Implementierung) → `review` (Review-Start); `_bmad-output/implementation-artifacts/deferred-work.md` — Story-3.8-Defers bzw. aufgegriffene/geschlossene „Home: Story 3.8"-Einträge kennzeichnen
|
||||
- [x] `wiki/log.md` — (Implementierung) Story-3.8-Eintrag, `sprint-status.yaml` → in-progress (Implementierung) bzw. `review` (Review-Start, Step-04); Review-Abschluss `done` im Review-Schritt (Workflow-Konvention)
|
||||
- [x] `schema/compiler.md` §5.14 — **Re-Open-Delta:** Zwei-Run-Bestätigung auf **zwei getrennte saubere Worktrees + frische Agent-Kontexte** umgestellt (Q-6/A0-19; „in einer Session" ersetzt); **kanonisches Eingabemanifest** (Baseline-Commit, geordnete Sources, output-sichtbare Run-/Zeit-/Identitätswerte) und **Run-Receipt** (Candidates, Reihenfolge, Plan, Entscheidungen, Output-Hashes) **außerhalb des Bundles** eingefordert; Verbot von **hart codierten erwarteten Plänen/Concept-Bodies** und **pauschaler `verified`-Maskierung** (nur benannte `at`-Ausnahme)
|
||||
- [x] `_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh` — **Re-Open-Delta:** DET-2 auf **zwei getrennte Worktrees/independ. Läufe** umgestellt (Manifest + Receipt-Szenario, keine hart codierten erwarteten Bundle-Outputs, verified nicht pauschal maskiert) — Exit 0
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- Given einen Fixieren Git-State + feste Eingabemenge, when zwei unabhängige Runs ausgeführt werden, then produziert §5.14-Wortlaut identische Bundle-States bis auf die benannte `at`-Ausnahme (FT-10, AD-17h, AC-1).
|
||||
- Given eine Abweichung bei zwei solchen Runs, when sie festgestellt wird, then wird sie als Fehler im AD-16-Klassifikations-Mechanismus behandelt und textuell benannt (nicht als akzeptables Rauschen) (AD-17h, AC-2).
|
||||
- Given der MVP (D-3), when der Agent-Instruktions-Validator ausgeführt wird, then laufen die beiden Ausführungen in **getrennten sauberen Worktrees und frischen Agent-Kontexten**; eine zweite Ausführung in derselben Session genügt nicht (Q-6, A0-19; AC-3).
|
||||
- Given das kanonische Eingabemanifest, when ein Run geplant wird, then hält es Baseline-Commit, geordnete Source-Eingaben und jeden im Bundle sichtbaren Run-/Zeit-/Identitätswert explizit fest; der **Run-Receipt** enthält Candidate-Liste, Reihenfolge, Plan, Entscheidungen und Output-Hashes **außerhalb des Knowledge Bundle** (AC-4).
|
||||
- Given der Zwei-Run-Nachweis, when Pläne und Bundle-State verglichen werden, then dürfen weder erwartete Pläne noch Concept-Bodies **hart codiert** werden; `verified`-Ereignisse werden **niemals pauschal** aus dem Vergleich maskiert (AC-5).
|
||||
- Given der Validator, when umgesetzt, then hält er keine Embedding-/Vector-Infrastruktur vor (AD-13; FT-3, FT-4; AC-4) und erzeugt keine eigene Runtime/kein neues Werkzeug (D-3, AD-11).
|
||||
|
||||
## Spec Change Log
|
||||
|
||||
<!-- Append-only. Populated by step-04 during review loops. Do not modify or delete existing entries. -->
|
||||
|
||||
### Review-Loop-1 (2026-08-20, Step-04)
|
||||
|
||||
**Ergebnis:** keine intent_gap / kein bad_spec; 0 Loopback. Review-Schicht 3 Subagenten (blind-hunter / edge-case-hunter / verification-gap, synchron); Triage: 14 Patch / 0 defer / Rest Reject (ausführliche Reject-Begründung im Story-Protokoll `wiki/log.md`). Alle Patches rein dokumentarischer Natur (Klarstellung/Verweis/Status); Semantik unverändert, keine neue Vertragsentscheidung.
|
||||
|
||||
**Patch-Stapel (in dieser Runde angewandt):**
|
||||
- §3.2-Pkt.-1b (b): paketierte Kollaps-Klasse in der Operativ-Klausel auf die geschlossene `[-–— _]`-Klasse angehoben; Verweis auf den Append-Block als maßgeblich (KEEP: die append-only-Schließung bleibt unverändert; der Operativ-Satz ist jetzt konsistent).
|
||||
- §3.2-Pkt.-2a: Match-Scope (ganze Wörter über den Body, exklusiv Frontmatter) in die operative Stufe-a-Formel gewirkt — Einzel-Term-Klausel + Mehrfach-Term-Vereinigung (Pkt. 1c) verdeutlicht; Body-Abgrenzung (nach der zweiten `---`-Zeile) bestimmt.
|
||||
- §3-Pkt.-2-Kandidatenliste (und damit §5.9-Worked Example): Stufe-a-Scope-Verweis ergänzt.
|
||||
- §5.14-Pkt.-2: Zwei-Run-Abgleich als Vergleich der beiden Run-Ausgänge gegeneinander (nicht nur je Lauf gg. Baseline) verdeutlicht — Beispiel `git diff <Run-A> <Run-B>` ergänzt.
|
||||
- §5.14-Pkt.-1-Intro: AD-3-Schutzliste um `adapters/` ergänzt.
|
||||
- §5.10-Pkt.-8: die pre-existing-Orphan-Obligationsformulierung als vorbestehend markiert (Verweis auf die neue deterministische Regel unten; keine Staffelung an Story 3.8/Epi-4 mehr).
|
||||
- `deferred-work.md`: Bezugs-Eintrag-Nummern der Story-3.2-review-Defers korrigiert (Kollaps Eintrag 3 → 2; Match-Scope Eintrag 2 → 1).
|
||||
- `wiki/log.md`: „8 `### Aufgegriffen`-Blöcke" → „7 `### Aufgegriffen`-Blöcke + 1 `### Aufgegriffen (teilweise)`".
|
||||
- `sandbox-3-8/run-sandbox.sh`: DET-2-at-Maskierungszweck als Kommentar klargestellt (belegt die Nicht-at-Bestandteile; at-Varianz demonstriert DET-4); DET-1-Demo-Kommentar (Kandidaten-/Form-Outputs als redaktionell verdichtete Run-Feststellungen).
|
||||
- `sprint-status.yaml`: Key `3-8-…` → `review` (Review-Start-Flip; finaler `done`-Flip im Step-05).
|
||||
- `spec`-Frontmatter: `status: 'in-review'` (Review-Start per Step-04), `review_loop_iteration: 0` unverändert; SRO-Review-Loop-1-Hinweis ergänzt.
|
||||
|
||||
**Rejected-Findings (Kurznotation, nicht Teil der Patches):** Stufe-a-Formel-Änderung nicht nötig (die Formel `rg -l`/`grep -rl` + Scope-Klausel bleibt die Instruktionsform; die Wortgrenzen-/Frontmatter-Semantik reist über die Pkt.-2a-Klausel, nicht über ein Flag); DET-2-Plan-Literal (dev-demo, echte Content-Hashes decken; Kandidaten-Ableitung über DET-1/DET-8); DET-8-hardcodierter Verwaist-Befund (Mechanik textuell, Existenz-negativ-Kontrolle hart); §5.14-`raw/`-Input-Verdacht (Pkt.-1a nennt `raw/`-Zuwächse bereits explizit „als Input"); §5.14-„kommt erstellt der Diff" — keine Formel-Verschmelzung; DET-2-maskierte-`at` (Display-Maske, DET-4 behandelt Varianz); Log-Overcount (Patch 9, siehe oben); Umlaut-Aufschlag (behandelt als Patch-7-Fundament); Sprint-Last-Updated-Timing (Konvention); §3.2-„keine offene Frage"(Umlaut bleibt dokumentiert offen, Wortlaut angepasst).
|
||||
|
||||
### Re-Open-Implementierung (2026-08-20, Step-03; genehmigtes Sprint-Change-Proposal 2026-08-20)
|
||||
|
||||
**Neu-Verhandlung:** `_bmad-output/planning-artifacts/sprint-change-proposal-2026-08-20.md` (approved, ProMods, explizite Chat-Freigabe) nimmt Story 3.8 aus `review` nach `in-progress` zurück und erweitert den Scope (Epics-Datei ACs Z. 357–370): getrennte saubere Worktrees + frische Agent-Kontexte (Q-6/A0-19), kanonisches Eingabemanifest, Run-Receipt außerhalb des Bundles, keine hart codierten erwarteten Pläne/Concept-Bodies, keine pauschale `verified`-Maskierung. Dieser Change-Log-Eintrag dokumentiert die Implementierung des Deltas: §5.14-Wortlaut (Zwei-Run-Mechanik auf Worktrees/Manifest/Receipt, Verbot von Hartcodes/pauschaler Maskierung), Sandbox DET-2 auf zwei Worktrees umgestellt. `<frozen-after-approval>`-Intent ausschließlich im Re-Open-Delta-Umfang angepasst; fehlendes Schließtag nach diesem Change Log ergänzt.
|
||||
|
||||
### Review-Loop-2 (2026-08-20, Step-04)
|
||||
|
||||
**Ergebnis:** keine intent_gap / kein bad_spec; 0 Loopback. Review-Schicht erneut 3 Subagenten (blind-hunter, edge-case-hunter-Retry, verification-gap, synchron). Diesmal ist die Sandbox-DET-2-Mechanik der Review-Objekte — die Befunde betreffen **die Re-Open-Implementierung selbst** (nicht nur Doku). Triage: **10 Patch** (Sandbox-Härtung) / **0 defer** / Rest Reject. Kern-Veranlassung: die drei Re-Open-ACs (Worktrees, Manifest-Verwendung, `at`-Ausnahme als *dokumentierte* Ausnahme statt stillem Ausschluss) wurden von den Subagenten als **nicht wirklich ausgeübt** erkannt — das Manifest war dekorativ (nie konsumiert), die `at`-Maskierung erfolgte **vor** dem Commit (stiller Ausschluss statt dokumentierter Ausnahme), ein `verified[]`-Feld existiert nicht, der Receipt hatte kein Reihenfolge-/Entscheidungs-Feld, und die Subshell ohne `set -e` riskierte false-PASS.
|
||||
|
||||
**Patch-Stapel (in dieser Runde angewandt, ausschließlich `sandbox-3-8/run-sandbox.sh`):**
|
||||
- **DET-2 ganzheitlich gehärtet:** `at` wird jetzt als **reale Wanduhr-Ausgabe committet** (`date -u`) und als eigener `at_cell`-Wert im Receipt festgehalten; die Normalisierung auf `AT` erfolgt **erst beim Vergleich** (Hash-Bildung über die at-normalisierte Content-Projektion, §5.14 Pkt. 2 „ohne die maskierte at-Zeile") — kein Maskieren vor Commit, kein stiller Ausschluss. Nach-Commit-Attestierung: `committed_at == at_now` wird verifiziert. Der Zwei-Run-Abgleich vergleicht **alle deterministischen Receipt-Bestandteile byte-identisch** und **nur die zwei Ausnahme-Cells `at_cell`/`tree` dürfen differieren**; die `at`-Varianz wird in den Läufen real demonstriert (zwei getrennte Worktree-Läufe → unterschiedliche Wanduhr-`at`).
|
||||
- **Kanonisches Eingabemanifest wird konsumiert/validiert** (nicht dekorativ): Baseline-Commit und geordnete Source-Eingaben werden abschnittsbewusst aus `manifest.yaml` extrahiert und vor jedem Lauf gegen den Worktree-Zustand geprüft („Manifest ohne baseline / Quellen / Identitätswerte" → HARD-FAIL); die Quell-Eingaben-Existenz wird **nach** dem Increment-Input-Commit geprüft (EC-1-Semantik: Quelle zum Verarbeitungszeitpunkt vorliegend).
|
||||
- **Receipt erweitert** um `order:` (Reihenfolge) und `decisions:` (Ausführungs-Entscheidung) gemäß §5.14 Pkt. 2; Receipt-Gerüst-Nicht-Vakuum (beide Dateien non-empty) vor dem Vergleich.
|
||||
- **Subshell `set -e`** in `run2_worktree` aktiviert (jeder fehlende `git`/`sed`-Schritt bricht als rc≠0 ab → HARD-FAIL statt false-PASS); Witness-/sha-Leer-Prüfung blieb.
|
||||
- **`match_stufe_a` literal-sicher:** Term wird regex-escaped (`sed 's|[][\\.*^$+?(){}|]|\\&|g'`) — ein Term wie `a+b`/`x.y` darf nie als Muster umgedeutet werden (§3.2-Pkt.-2a/§5.14 Pkt. 5); Body-Extraktion CRLF-tolerant (`tr -d '\r'`).
|
||||
- **`cand`-Newline-Normalisierung** (`tr '\n' ','`) — mehrzeilige Candidate-Liste bricht den Receipt-Zeilenblock nicht mehr.
|
||||
- **`log_bullet` fail-hard:** `mktemp`/`mv`-Fehler werden nicht mehr geschluckt (ein verlorener `log.md`-Eintrag hätte beide Runs identisch=Baseline gelassen → Vakuum-Gleichheit; jetzt HARD-FAIL).
|
||||
- **`git worktree prune` vor dem Add** — Re-Run-Sicherheit (keine verwaisten worktree-Registrierungen blockieren/nachtragen).
|
||||
- **`git clean` fail-hard** unter `set -e` (kein `|| true`-Schlucken von Rest-Unternehmungsdateien).
|
||||
- **Manifest-`output_visible_run_identity`-Klarstellung:** das Manifest führt konkrete **Feldnamen-Werte** (`generated.by`, `generated.at` — die benannte A0-20-Ausnahme), nicht einen Feldnamen-Platzhalter; die Manifest-Validierung verlangt `generated.at` explizit.
|
||||
|
||||
**Kein `defer`:** die Befunde waren sämtlich durch die Re-Open-Implementierung verursacht und hier (auto-)fixierbar; keine pre-existing Lücke wurde dabei neu aufgedeckt. **Reject:** einige Findings (z. B. „Teil-Zeitstimmen"/„literal") waren bereits durch die Hash-basierte Abwichen-Erkennung abgedeckt oder überreich.
|
||||
|
||||
**Verifikation dieser Runde:* `bash run-sandbox.sh` → 8/8 `PASS` (DET-1..DET-8), Exit 0, zwei Läufe mit real unterschiedlichen `at_cell`-Wanduhrwerten (Ausnahme aktiv), Witness nicht-vakuum (Baseline-SHA ≠ Run-SHA); die Befunde „Manifest wird nie konsumiert", „at-Maske vor Commit", „kein Reihenfolge-/Entscheidungsfeld" sind damit direkt behoben.
|
||||
|
||||
### Review-Loop-3 (2026-08-20, Step-04)
|
||||
|
||||
**Ergebnis:** keine intent_gap / kein bad_spec; 0 Loopback. Review-Schicht 4 Subagenten (blind-hunter, edge-case-hunter, verification-gap, acceptance-auditor, synchron). Triage: **4 decision-needed / 13 patch / 6 defer / 7 dismissed.** Nutzer-Entscheidungen (alle empfohlene Option 1): **D-1** §5.14-Schließungs-Bullet macht den §7 „Bekannte Determinismus-Lücke"-Alt-Bullet **superseded** (append-only-Superseded-Hinweis am Alt-Bullet, kein Umbruch — §3.2-„kein Umbruch" gewahrt); **D-2** Story-Status-Flip auf **`done`** nach Loop-3-Abschluss — die Change-Proposal-Sequenzierung „3.9 → 3.10 / 3.11 → 3.12 → 3.8 Abschluss → 3.13 Abnahme" (Sprint-Change-Proposal 2026-08-20) betrifft das **Epic-3-Abnahmegate (Story 3.13)**, nicht die Story-3.8-Instruktionsverankerung (die ist mit diesem Loop abgeschlossen; 3.9–3.12-Verankerungen und die 3.13-Abnahme bleiben offen, epic-3 remains `in-progress` — als Key-Kommentar in `sprint-status.yaml` festgehalten); **D-3** autorisierte Neu-Verhandlung des Frozen-Intents in **geringfügigem** Umfang: Typo „documenthuman" → „document-human" (dieses File, Re-Open-Delta-Zeile; nur der Rechtschreibfehler, kein Intent-Wechsel) — diese Change-Log-Zeile ist ihre Doku; **D-4** Hold-Home = **Story 3.10 (Epic 3)** (Hold-Mechanik: Erhaltung unzugeordneter `raw/`-Evidenz im benannten Hold ohne Wissensmutation, NFR-7), Korrektur-/Erweiterungs-**Klassifikation** = Epic-4-Interface/Story 4.1 — §5.10 Pkt. 8 entsprechend präzisiert.
|
||||
|
||||
**Patch-Stapel (in dieser Runde angewandt):**
|
||||
- **P-1** SRO-/Code-Map-Anker auf IST-Zeilen: `schema/compiler.md` SRO 374→375 (Pkt. 3), 375→376 (Pkt. 4), 376→377 (Pkt. 5), 476→477 (Rev 3.3); Code Map „§5.14 Z. 364–381 ca." → 365–377, „§7 (Z. 409ff.)" → 424ff, „§8-AD-17h (Z. 430)" → 445, „Revision 3.3 nach Z. 461" → 477; alle 6 Sandbox-SRO-Anker neu berechnet (vorher exakt, durch die Loop-3-Sandbox-Edits verschoben): 238→245, 257→265, 409→442, 267→275, 414→447, 498→531.
|
||||
- **P-2/P-4** symmetrische Normalisierung: §3.2 Pkt. 2a-Klausel + `match_stufe_a` — Term **und** Body werden **identisch normalisiert** (Lowercasing + Kollaps-Klasse Pkt. 1b) vor dem Vergleich; kein host-abhängiges `-i`-Flag (wurde entfernt); Wortgrenze folgt der Tool-Wortdefinition (rg `-w` / GNU `grep -w`/`\b`); ASCII-Boundary `[^A-Za-z0-9]` im Skript trägt die Tool-Semantik portabel.
|
||||
- **P-3** §5.14 Pkt. 2: der **Receipt-basierte Hash-/Textvergleich ist die re-executierbare Formel** des Zwei-Run-Abgleichs; die `git diff <Run-A> <Run-B>`-Formel ist deren Austauschbar-Form auf demselben committeten Baum (Sandbox belegt über Receipt-Hashvergleich).
|
||||
- **P-5** §5.14 Pkt. 2: Sandbox-Fresh-Kontext-Restlücke textuell benannt — die zwei frischen Agent-Kontexte sind **mechanisch simuliert** (Subshell-Läufe in getrennten Worktrees desselben Skripts); Nachweis echter frischer Kontexte erfolgt im **Story-3.13-Abnahmegate** (echte Agent-Läufe).
|
||||
- **P-6** Manifest-`generated_by` wird **konsumiert**: Manifest erhält `generated_by: wow-compiler/0.1.0`; Verbrauch-Guard (`generated.by`-Identität + non-empty) + Concept-Frontmatter `by: $m_by` (statt hart-codiert) — „nicht dekorativ" ist jetzt materiell erfüllt.
|
||||
- **P-7** at-Ausnahme **hart assertiert**: bei Wanduhr-Sekundenkollision wird Lauf B im frischen Kontext wiederholt (begrenzt, 5x), bis die `at_cell`-Werte real differieren; sonst `HARD-FAIL` — die aktive Ausnahme (Change-Log-Beleg „zwei Läufe mit real unterschiedlichen at_cell-Werten") ist jetzt eine Eigenschaft jeder Re-Execution. Re-executiert: `BEFUND: at-Ausnahme aktiv (assertiert) — Lauf A at=2026-08-20T15:05:09Z, Lauf B at=2026-08-20T15:05:12Z`.
|
||||
- **P-8** „vollständig pinbar"/„keine offene Determinismus-Frage" **ge scopet** (§5.14 Pkt. 5 + §7-Determinismus-Bullet): gelten nur für die mit §5.14 geschlossenen Lücken (Em-Dash-Klasse, Kollaps-Reichweite, Match-Scope, Reconcile-Orphan-Regel, `at`-Gap-Ausnahme); bewusst nicht damit geschlossen: Umlaut-vs-Transkription-Divergenz (benannter Defer) und Story-3.9-ACs (geplant, noch nicht verankert — §3.2 maßgeblich bis dahin).
|
||||
- **P-9** `epics.md` Story-3.8-AC-2: „Determinismusfehler" als **Fehler der AD-16-Klassifikation** (AD-16-Klassifikationsdefekt) präzisiert — die AD-16-Kopplung war bei Story-Aufnahme nicht ausgeschrieben; AC-Wortlaut erhalten, Nachführung als Präzisierungsklausel.
|
||||
- **P-10** Frontmatter `review_loop_iteration: 0 → 2` (der Counter war in Loop-1/2 nicht gepflegt; ab Loop-3 gepflegt, Wert = Anzahl bereits abgeschlossener Loops).
|
||||
- **P-11** `epic-3-context.md` Technical Decisions (Z. 39/41/43): als **Zielzustand** markiert (Story 3.9/3.11/3.12 — noch nicht in `schema/compiler.md` verankert; bestehende Verankerungen bleiben maßgeblich) — die Bullets lesen nicht mehr wie Ist-Zustand.
|
||||
- **P-12** **verifiziert, kein Edit nötig:** die acceptance-auditor-Finding „epics.md-AD-17-Enum inkonsistent" wurde per Grep widerlegt: `epics.md` enthält **kein** Literal „AD-17a..h" als Block; alle Enum-Vorkommen (Z. 61–67, 94–95, 101, 262–263, 321–329, 357–408) sind mit dem genehmigten Change-Proposal konsistent (AD-17g verbleibt in Epic 4, Z. 101; AD-17d..17f in Story 3.11/3.12-ACs; AD-17h in Story 3.8-ACs).
|
||||
- **P-13** dieser Change-Log-Eintrag (append-only nach Loop-2-Eintrag, vor `</frozen-after-approval>` — Loop-1/2-Präzedenz: der Change Log liegt frozen-intern, weil er die Frozen-Änderungsdoku des Re-Opens ist; kein frozen-interner Text wurde hier verändert außer dem D-3-Typo).
|
||||
|
||||
**Defers (6, → `deferred-work.md` append-only, Block „Deferred from: code review of spec-3-8… (2026-08-20)"):** D-5 Sandbox-Härtungs-Guards (8 Befunde: `set -u`-Scope, ungeschützte `mktemp`/`git init`/Baseline-Commit, `isolate()`, `log_bullet`-Temporaries) — Testharness-Robustheit, keine normative Semantik; D-6 DET-1/DET-2-Plan-/Form-Literale vs. AC-5 „nicht hart codiert" (dev-demo-Kommentar + echte Content-Hashes tragen die Nicht-Vakuum-Assertion; Home: Story-3.13-Abnahme mit echten Gate-Runs); D-7 `norm()`-Locale-Pinning (`LC_ALL` — C-Locale degradiert `[–—]` zu Byte-Menge; Home: Sandbox-Härtung mit D-5); D-8 Mehrfach-Term-Vereinigung unübend (Home: Story 3.9); D-9 Orphan-Term hand-pinned + feste 2-Datei-Scan (Home: Story 3.9); D-10 Umlaut-vs-Transkription im Match-Pfad unübend (bereits „Aufgegriffen (teilweise)" offen, kein Instruktions-Defekt).
|
||||
|
||||
**Dismissed (7):** (1) Blind-Hunter „alle Sandbox-SRO-Anker stale" — **widerlegt** (alle 6 exakt vor den Loop-3-Edits; die Staleness wurde erst durch die eigenen P-6/P-7-Edits erzeugt und per P-1 aufgelöst); (2) Blind-Hunter „§7-Zeilenanker off-by-one (409/430/461)" — bereits im Loop-3-Review-Stand korrekt verortet, Anker waren Implementierungs-Zielwerte (jetzt per P-1 IST); (3) edge-case „Wiederholungs-Schleife unendlicher Loop" — die Schleife ist auf 5 Versuche begrenzt mit HARD-FAIL-Exit; (4) verification-gap „Manifest-`generated.by`-Guard tautologisch" — Guard prüft Manifest-Inhalt gegen Konzepts-Ausgabe (Konsistenz), nicht gegen sich selbst (P-6); (5) acceptance-auditor „AC-5 verletzt durch `plan`-Literal im Receipt" — das `plan`-Feld ist der **abgeleitte** Plan-State (aus Git-State + Stufe-a-Match), kein vorab hart codierter Erwartungswert (D-6-Präzedenz); (6) acceptance-auditor „epics.md AD-17-Enum inkonsistent" — widerlegt (P-12); (7) verification-gap „`last_updated`-Formatbruch" — Format `MM-DD-YYYY HH:MM` beibehalten (Z. 32), Präzedenz-Prüfung bestanden.
|
||||
|
||||
**Verifikation dieser Runde:** `bash _bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh` → **8/8 PASS (DET-1..DET-8), Exit 0**; at-Ausnahme aktiv (assertiert) mit real unterschiedlichen Wanduhr-`at`-Werten (Lauf A 15:05:09Z vs. Lauf B 15:05:12Z); Witness nicht-vakuum (Baseline-SHA ≠ Run-SHA); Manifest `generated_by` konsumiert (Concept-Frontmatter `by:` trägt Manifest-Wert). AD-3 geprüft (`schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`/`raw/` unverändert). **Status:** Spec-Frontmatter `status: 'done'`, `review_loop_iteration: 2`; `sprint-status.yaml`-Key `3-8-…` → **`done`** (D-2, mit Sequenzierungs-Hinweis), `last_updated` → 08-20-2026 17:04. `wiki/log.md` Loop-3-Abschluss-Bullet ergänzt.
|
||||
|
||||
</frozen-after-approval>
|
||||
|
||||
### Review Findings (Review-Loop-3, 2026-08-20; bmad-code-review, 4 Layer)
|
||||
|
||||
<!-- Append-only Review-Protokoll (Step-04); analog zur Change-Log-Sanction. Bestehender Frozen-Text wird NICHT verändert. Dismissed (7) werden nicht persistiert — Begründungen im Review-Loop-3-Change-Log-Eintrag (P-13). -->
|
||||
|
||||
**Decision-Needed (4):**
|
||||
- [x] [Review][Decision] D-1 §3.2-Alt-Bullet-Selbstwiderspruch — der Pre-Existing-Bullet „Bekannte Determinismus-Lücke … deckt den Em-Dash `—` **nicht** ab … übergeben an Story 3.8" (`schema/compiler.md:53`) steht wortgleich über dem Schließungs-Bullet (`:54`) und ist jetzt faktisch falsch; zwei benachbarte, sich widersprechende normative Aussagen über die Kollaps-Klasse. Kollidiert mit dem Spec-Constraint „ohne Umbruch des bestehenden §3.2-Wortlauts" (append-only). — **Entscheidung (2026-08-20): Option 1** — neuer append-only-Nachtrags-Bullet unter `:54` kennzeichnet den Alt-Bullet ausdrücklich als **superseded** (Alt-Wortlaut bleibt unverändert; Widerspruch aufgelöst).
|
||||
- [x] [Review][Decision] D-2 Status-Trail bruch — Spec-Frontmatter `status: 'done'` + `wiki/log.md:4` „Step-05 done" + Commit-Titel „Step-05 done" vs. `sprint-status.yaml:61` `review` vs. genehmigtes Change-Proposal („Story 3.8 wird nach 3.9–3.12 … abgeschlossen; 3.8 Abschluss → 3.13 Abnahme"). Welcher Wert ist maßgeblich, und wer flippt wann? — **Entscheidung (2026-08-20): Option 1** — `sprint-status.yaml` auf `done` flippen (Loop-3-Abschluss); Change-Proposal-Sequencing betrifft das Epic-3-Abnahmeverfahren (Gate 3.13), nicht den Story-Zustand; Sequencing-Vorbehalt wird im `wiki/log.md`-Abschluss-Bullet textuell vermerkt.
|
||||
- [x] [Review][Decision] D-3 „documenthuman respektierend" im Frozen-Block — mangelhafter Phrase (vermutl. „document-human respektierend") in `spec` Z. 24, dem menschlich-eigenen Frozen-Block; nur per menschlicher Renegotiation änderbar. — **Entscheidung (2026-08-20): Option 1** — menschliche Renegotiation hiermit erteilt: Korrektur auf „document-human respektierend"; die Renegotiation wird im Review-Loop-3-Change-Log-Eintrag dokumentiert (D-3).
|
||||
- [x] [Review][Decision] D-4 Orphan-/Hold-Home-Konflikt — §5.10 Pkt. 8 (`schema/compiler.md:302`) + Log-Einträge benennen „Epic-4-Interface, Story 4.1" als Home der Korrektur-/Erweiterungs-Klassifikation, während die Story-3.10-ACs (epics.md Z. 402) einen Hold „bis Epic 4" in Epic 3 selbst verlangen. Welches Story-AC besitzt die Orphan-/Hold-Klassifikation? — **Entscheidung (2026-08-20): Option 1** — Story 3.10 ist Home des Holds (Mechanik in Epic 3); die Korrektur-/Erweiterungs-*Klassifikation* bleibt Epic-4-Interface (Story 4.1); Pkt.-8-Verweis wird entsprechend präzisert (Patch aus D-4).
|
||||
|
||||
**Patches (13):**
|
||||
- [x] [Review][Patch] P-1 SRO-Anker-Drift `schema/compiler.md` — SRO-Zeilen `:374`→`375`, `:375`→`376`, `:376`→`377` (Pkt. 3/4/5), `:476`→`477` (Revision 3.3); Code-Map „Revision 3.3 nach Z. 461"→477, „§7 nach Z. 420"→434, „§8-AD-17h Z. 430"→Ist, „§5.14 Z. 364–381"→365–377 (spec Z. 66/182/183/184/194).
|
||||
- [x] [Review][Patch] P-2 §3.2-Stufe-a-Boundary-Semantik klären — normative Klausel benennt `rg -w`/`grep -w`/`\b` (ASCII-only Wortklassen), Sandbox nutzt `[^A-Za-z0-9]`-Boundary + `-i`; für deutsche Inhalte (Umlaut/ß) divergieren „Wort"-Definitionen; `-i` nirgends instruiert (spec:79, `schema/compiler.md:56`, run-sandbox.sh:144).
|
||||
- [x] [Review][Patch] P-3 §5.14 Pkt. 2 Run-A↔Run-B-Formel konkretisieren — die benannte `git diff <Run-A> <Run-B> -- wiki/`-Formel wird von der Sandbox nie ausgeführt (nur Receipt-/Hash-Vergleich; `tree`-Cells als Ausnahme); entweder Sandbox ergänzt die Formel, oder Pkt. 2 benennt den Hash-Textvergleich ausdrücklich als äquivalente re-executierbare Formel (spec:88, §5.14 Pkt. 2 `schema/compiler.md:371`).
|
||||
- [x] [Review][Patch] P-4 §5.14 Pkt. 2/5 Body-Normalisierung klären — „identisch normalisiert" (§3.2/§5.14) gilt textuell nur für den Term; `match_stufe_a` normalisiert den Body nicht (nur CRLF-Strip), der Em-Dash-Kollaps fehlt im Match-Pfad vollständig (DET-5 testet `norm`, nie den Matcher) (run-sandbox.sh:126-142, 555-571).
|
||||
- [x] [Review][Patch] P-5 AC-3-Fresh-Kontext-Restlücke dokumentieren — „zwei frische Agent-Kontexte" (Q-6/A0-19) sind in der Sandbox strukturell nur als Subshells simulierbar; die Restlücke soll in spec/Log textuell als „mechanisch simuliert" benannt sein (spec:90, run-sandbox.sh:238-260).
|
||||
- [x] [Review][Patch] P-6 Manifest-Verbrauchs-Tautologie — Manifest wird aus `$BASE` + harter Source-Liste erzeugt und gegen dieselben Variablen validiert; `generated.by` wird nie konsumiert (hart-codiert `wow-compiler/0.1.0`); „nicht dekorativ" nur formal erfüllt (spec:91, run-sandbox.sh:248-266, 300).
|
||||
- [x] [Review][Patch] P-7 at-Ausnahme-Demo asserten — bei identischen `at_cell`-Werten (Wanduhr-Sekundenkollision) druckt das Skript nur „BEFUND: at-Grenzfall" und PASST; die aktive Ausnahme wird nicht assertiert; Change-Log-Claim „zwei Läufe mit real unterschiedlichen at_cell-Werten" nicht vom Skript erzwungen (spec Change-Log Z. 127, run-sandbox.sh:394-401).
|
||||
- [x] [Review][Patch] P-8 §7-Absoluthheits-Claim eingrenzen — „Keine offene Determinismus-Frage verbleibt" (§7 `schema/compiler.md:434`) + §5.14 Pkt. 5 „vollständig pinbar … keine offene Frage" (:377) vs. `deferred-work.md` (Umlaut-vs-Transkription offen) + Story-3.9-ACs (closed term-gewinnung/manifest/Routing-Tabelle existiert noch nicht).
|
||||
- [x] [Review][Patch] P-9 Terminologie-Drift AC-2 — epics.md Z. 366 „Determinismusfehler … Run gilt als fehlgeschlagen" vs. §5.14 Pkt. 4 „AD-16-Klassifikationsdefekt … korrigiert bzw. rollt zurück" (:376); AD-16-Kopplung in der Neuformulierung ohne Verweis verloren.
|
||||
- [x] [Review][Patch] P-10 `review_loop_iteration` + Change-Log-Finalität — Counter blieb `0` über zwei Loops (dekorativ); kein Change-Log-Eintrag für den Step-05-Statuswechsel (spec Z. 7, 95-142).
|
||||
- [x] [Review][Patch] P-11 `epic-3-context.md` geplanter Zustand markieren — Technical Decisions beschreiben Story-3.9/3.11/3.12-Entscheidungen als aktuellen Ist-Zustand, die in `compiler.md` nicht existieren; Ziel-/geplanter-Zustand kennzeichnen.
|
||||
- [x] [Review][Patch] P-12 epics.md-Epic-Narrativ-AD-17a..h nachziehen — Summary-Tabelle/Epic-Body zitieren weiterhin „(AD-17a..h)"; AD-17g-Entzug (jetzt „vollständig in Epic 4") nur in der AD/A0-Enum sichtbar, nicht im Narrativ.
|
||||
- [x] [Review][Patch] P-13 Review-Loop-3-Change-Log-Eintrag anhängen — Triage-Ergebnis, Patch-Stapel, Defer-Verweise und die 7 Dismissals mit Begründung (darunter Blind-Hunter „alle Sandbox-SRO-Anker stale" — widerlegt, alle 6 exakt).
|
||||
|
||||
**Defer (6):**
|
||||
- [x] [Review][Defer] D-5 Sandbox-Härtungs-Guards (8 Befunde) [run-sandbox.sh:37,41,94-96,104-107,136-141,243-244] — deferred, Testharness-Robustheit (keine normative Semantik); Re-Run-Risiko dokumentiert, Home: nächste Sandbox-Revision.
|
||||
- [x] [Review][Defer] D-6 DET-1/DET-2-Plan-/Form-Literale vs. AC-5-„nicht hart codiert" [run-sandbox.sh:189,211-221] — deferred, Loop-1-/Loop-2-Präzedenz (dev-demo-Kommentar Z. 211-214; echte Content-Hashes tragen die Nicht-Vakuum-Assertion); Home: Story-3.13-Abnahme (echte Gate-Runs).
|
||||
- [x] [Review][Defer] D-7 `norm()`-Locale-Pinning (`LC_ALL`) [run-sandbox.sh:115-122] — deferred, Testharness-Host-Locale-Abhängigkeit; C-Locale degradiert `[–—]` zu Byte-Menge; Home: Sandbox-Härtung (mit D-5).
|
||||
- [x] [Review][Defer] D-8 Mehrfach-Term-Vereinigung unübend [run-sandbox.sh:555-660] — deferred, §5.14-Pkt.-5-„pinbar"-Verhalten ohne ausführbare Coverage; Home: Story 3.9 (Routing/Term-Gewinnung).
|
||||
- [x] [Review][Defer] D-9 Orphan-Term hand-gesteuert + feste 2-Datei-Scan [run-sandbox.sh:660-693] — deferred, Mechanik textuell korrekt, Determinismus der Orphan-ermittlung (Term-Ableitung aus `raw/`-Zuwachs, voller Kandidaten-Scan) nicht ausgeübt; Home: Story 3.9.
|
||||
- [x] [Review][Defer] D-10 Umlaut-vs-Transkription im Match-Pfad unübend [run-sandbox.sh:555-571] — deferred, bereits als „Aufgegriffen (teilweise)" offen (deferred-work.md Z. 541-546, kein Instruktions-Defekt); Home: Sandbox-Vereinheitlichung/folgende Instruktions-Revision.
|
||||
|
||||
## Design Notes
|
||||
|
||||
**Warum §5.14 als eigene Sektion, nicht §6.5-Erweiterung?** §6.5 ist die „Determinismus- & Selbsttest-Norm" mit **drei** Nachprüf-Kriterien (Vollständige §3-Subset-Konformität, `at`-Normalform, `sources`-Existenz) — die projektions-seitige Content-Prüfung je erzeugtem Concept. Der Determinismus-*Vertrag* (AD-17h/FT-10) ist die **Cross-Run-Eigenschaft** (zwei unabhängige Runs → gleicher Bundle-State), kein Einzel-Concept-Kriterium. §5.14 ist die geschlossene Verankerung dieser Cross-Run-Eigenschaft: (a) **Bundle-State-Definition** (welche Zustandsmenge ist „der Bundle-State" — die committete Baum-Projektion unter `wiki/`/`raw/` zzgl. Plan-/Kandidaten-/Reihenfolge-Outputs; `generated.at` als benannte Ausnahme), (b) **Zwei-Run-Bestätigungs-Mechanik** (agent-Instruktions-basiert; **Re-Open-Stand:** die beiden Ausführungen laufen in **getrennten sauberen Worktrees** mit **frischen Agent-Kontexten** über demselben committeten Git-State und vergleichen die Bundle-States; eine zweite Ausführung in derselben Session genügt nicht — Q-6/A0-19; unter **kanonischem Eingabemanifest** und mit **Run-Receipt außerhalb des Bundles**), (c) **Ausnahme-Menge** (allein `generated.at`-Wanduhr-Gap, dokumentiertes A0-20; Nichts sonst), (d) **Abweichungs-Klassifikation** (jede Differenz außerhalb der Ausnahme = AD-16-Klassifikationsfehler; textuell benannt NFR-4; kein stiller Vorbeilass). Damit ist die bisher „offen verankerte" AD-17h-Eigenschaft (viele Rückverweise, kein normativer Ort der Bestätigung) zu einem **instruierten, mechanisch bestätigbaren Verfahren** verdichtet.
|
||||
|
||||
**Die Normalisierungs- und Match-Lücken werden deterministisch geschlossen, nicht nur notiert.** Die Kollaps-Klasse in §3.2 Pkt. 1b ist `[-–_ ]` (En-Dash –, Bindestrich -, Unterstrich _, Leerzeichen) — der Em-Dash `—` fehlt (bekannte Story-3.2-Lücke mit Home Story 3.8). Die Schließung ist eine **Ergänzung der Kollaps-Klasse** um den Em-Dash (`[-–— _]` → `-`) sowie die Festlegung der **Kollaps-Reichweite** (jedes Vorkommen → genau ein `-`; führende/trailende Separatoren werden getrimmt — die bereits in der Sandbox etablierte Semantik) und des **Match-Scope** der Stufe a (Stufe-a-grep-matcht **ganze Wörter** über den Body, exklusive YAML-Frontmatter — `rg -l '<term>' -g '!log.md' wiki/` erhält einen deterministischen Scope; Substring- und Frontmatter-Treffer werden ausgeschlossen). §5.10 Pkt. 8 (Orphan) erhält eine **deterministische Reconcile-Orphan-Regel**: neu committete `raw/`-Evidenz ohne Ziel-Pfad-Treffer bleibt unzugeordnet, wird in `log.md` als verwaist protokolliert (Datumsgruppe, `<Baseline-Commit>`), kein Banner/keine stille Vorbearbeitung. Diese Schließungen machen die relevanz-/synthese-seitigen Erhebungen über den committeten Zustand vollständig pinbar.
|
||||
|
||||
**Die Sandbox (DET-1..DET-8, `bash run-sandbox.sh`, `/tmp`-Baum, Exit 0) demonstriert die Bestätigung mechanisch.**
|
||||
- DET-1 BUNDLE_STATE_DEFINITION: erzeugt ein Mini-Bundle, definiert/extrahiert die Bundle-State-Projektion (wiki/-Dateien + Plan-/Kandidaten-/Reihenfolge-Outputs) deterministisch
|
||||
- DET-2 ZWEI_RUN_IDENTISCH (nicht-vakuum): **zwei getrennte Worktrees** mit **frischen Agent-Kontexten** (je ein eigener Lauf über demselben committeten Baum) → identische Bundle-States bis auf `at`; unter **kanonischem Eingabemanifest** und mit **Run-Receipt** (Candidates, Reihenfolge, Plan, Entscheidungen, Output-Hashes) **außerhalb des Bundles**; die Assertion vergleicht echte Content-Hashes (nicht nur Vorhandensein); keine hart codierten erwarteten Bundle-Outputs, `verified` nicht pauschal maskiert (nur die benannte `at`-Ausnahme)
|
||||
- DET-3 ZWEI_RUN_ABWEICHUNG: künstlich divergenter Lauf → wird als AD-16-Klassifikationsdefekt klassifiziert und textuell benannt (kein Rauschen)
|
||||
- DET-4 AT_GAP_AUSNAHME: zeigt, dass `generated.at`-Wanduhr-Gap die einzige benannte Ausnahme ist (übrige Teile byte-identisch)
|
||||
- DET-5 EM_DASH: Term mit Em-Dash `—` normalisiert auf dieselbe canonische Form wie En-Dash/Bindestrich/Unterstrich/Leerzeichen
|
||||
- DET-6 KOLLAPS: Läufe (`a--b`), führende (`-x`), trailende (`x-`) → Kollaps auf genau ein `-` + Trim
|
||||
- DET-7 MATCH_SCOPE: Stufe-a-matcht ganze Wörter über Body, exklusive Frontmatter (Substring-/Frontmatter-Treffer ausgeschlossen)
|
||||
- DET-8 ORPHAN: neu committete Evidenz ohne Ziel-Pfad-Treffer → unzugeordnet, `log.md`-verwaist protokolliert, kein Banner/keine Mutation
|
||||
|
||||
(Code-/Zahlgenauigkeiten: Szenario-Labels sind Fixierung der I/O-Matrix; die Implementierung trägt die harten Assertionen in der Sandbox.)
|
||||
|
||||
## Verification
|
||||
|
||||
**Commands (re-executierbar, ab Workspace-Root):**
|
||||
1. `bash _bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh` — expected: DET-1..DET-8 harte PASS/Fail (Re-Open-Stand, gehärtet in Review-Loop-2: DET-2 in zwei getrennten Worktrees mit frischen Kontexten, **kanonisches Eingabemanifest konsumiert/validiert** vor jedem Lauf, **Run-Receipt außerhalb des Bundles** mit `order:`/`decisions:`/`at_cell`, **keine hart codierten Bundle-Outputs**, `verified` nicht pauschal maskiert — **`generated.at` als reale Wanduhr-Ausgabe committet und erst beim Vergleich normalisiert** (dokumentierte Ausnahme, kein stiller Ausschluss), Ausnahme-Cells `at_cell`/`tree` dürfen differieren, übrige Bestandteile byte-identisch), Zwei-Run-Identität nicht-vakuum, Exit 0.
|
||||
2. `grep -n "§5.14\|Revision 3.3" schema/compiler.md` — liefert §5.14-Sektion + Revisionslog-Eintrag; `grep -n "Determinismus-Vertrag & Agent-Instruktions-Validator" schema/compiler.md` — die §5.14-Überschrift wortgleich (inkl. §5.13-Seam-Satz in §5.14-Intro).
|
||||
3. Read-only (AD-3): `git status --porcelain` zeigt keinen Change an `schema/validator.md`/`schema/wiki-compiler.md`/`adapters/`/`raw/`. `schema/canonical-terms.md` unverändert (append-only-Registry unangetastet).
|
||||
4. Validator-Lauf: alle `wiki/`-Dateien SUCCESS (unverändert, keine Inhalts-Mutation).
|
||||
5. Auf den **`wiki/`-Scope begrenzt** (`git status --porcelain -- wiki/`): ausschließlich `wiki/log.md` (dieser Eintrag) — Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt; `sprint-status.yaml`/`deferred-work.md`/`sandbox-3-8/` liegen außerhalb `wiki/` und sind nicht Teil der Diff-Probe.
|
||||
|
||||
**Zu beachten (beim step-04-Review):** (a) §0-Phasen-Listentext, §5.13-Phasen-Disziplin und §6/§6.5 müssen textuell **unverändert** bleiben — §5.14 verweist auf sie (Fugen-Identität); (b) der `generated.at`-Wanduhr-Gap **bleibt verhaltens-seitig unverändert** (A0-20-Konvention); §5.14 definiert nur seine Behandlung im Bundle-State-Vergleich (Ausnahmemenge) — ein Wechsel des `generated.at`-Verhaltens wäre Ask-First; (c) die vorhandene §8-Revisionslog-Nummer ist **3.2** (Story 3.7); **Revision 3.3 ist für Story 3.8 frei** (grep-verifiziert: keine 3.3 im Revisionslog); (d) kein neuer §7-Bullet ersetzt einen bestehenden — der Determinismus-Bullet wird **ergänzt** (Verankerungs-Verweis), die bestehenden Story-Bullets bleiben unverändert; (e) **Re-Open-Delta (§5.14):** die Zwei-Run-Mechanik nutzt **getrennte saubere Worktrees + frische Agent-Kontexte** (Q-6/A0-19), ein **kanonisches Eingabemanifest** und einen **Run-Receipt außerhalb des Bundles** — keine hart codierten erwarteten Bundle-Outputs, keine pauschale `verified`-Maskierung (nur `at`-Ausnahme); die alte Formulierung „in einer Session" ist entfernt.
|
||||
|
||||
## Suggested Review Order
|
||||
|
||||
<!-- Klickbare Review-Route (Step-05): jede Zeile = [Beschreibung:Zeilennummer](../../relativer-pfad#LZeile) -- Ctrl+Klick (Cmd+Klick auf macOS) öffnet den Anker. Zuerst die §5.14-Bestätigungs-Mechanik lesen, dann die Lückenschließung, dann Nachweis-Orte, Sandbox-Beweis und Protokoll als Peripherie. -->
|
||||
|
||||
**§5.14-Determinismus-Vertrag (Kern, Einstieg)**
|
||||
|
||||
- [compiler.md:365](../../schema/compiler.md#L365) — §5.14-Überschrift, Intro mit §5.13-Seam und AD-3-Schutzliste inkl. `adapters/`.
|
||||
- [compiler.md:369](../../schema/compiler.md#L369) — Pkt. 1 Bundle-State-Definition: committete Baum-Projektion, `generated.at` als benannte Ausnahme (A0-20), FT-10/AD-17h/AC-1.
|
||||
- [compiler.md:370](../../schema/compiler.md#L370) — Pkt. 2 Zwei-Run-Bestätigungs-Mechanik: zweimal über denselben committeten Git-State, Run-A↔Run-B-Abgleich (Beispiel `git diff`), keine Wanduhr-Steuerung.
|
||||
- [compiler.md:375](../../schema/compiler.md#L375) — Pkt. 3 Ausnahme-Menge: allein der `generated.at`-Wanduhr-Gap; alle übrigen Bestandteile byte-identisch (kein stiller Ausschluss).
|
||||
- [compiler.md:376](../../schema/compiler.md#L376) — Pkt. 4 Abweichungs-Klassifikation: jede Differenz außerhalb der Ausnahme = AD-16-Klassifikationsdefekt, kein Rauschen (NFR-4, Zustands-Restaurations-Invariante).
|
||||
- [compiler.md:377](../../schema/compiler.md#L377) — Pkt. 5 Normalisierungs-/Match-/Orphan-Schließung: Verankerung auf §3.2-Pkt.-1b / §5.10-Pkt.-8, Erhebungen vollständig pinbar.
|
||||
|
||||
**§3.2/§5.10-Lückenschließung (deterministische Regel-Ergänzungen)**
|
||||
|
||||
- [compiler.md:54](../../schema/compiler.md#L54) — §3.2-Pkt.-1b „Geschlossene Determinismus-Lücken": Em-Dash-Kollaps-Klasse `[-–— _]`, Kollaps-Reichweite (ein `-` + Trim), Match-Scope Stufe a (ganze Wörter, Body-exklusiv).
|
||||
- [compiler.md:56](../../schema/compiler.md#L56) — §3.2-Pkt.-2a operative Stufe-a-Mechanik: `rg -l`/`grep -rl`-Sweep + deterministischer Scope-Filter (zweistufig, tool-portabel), Mehrfach-Term-Vereinigung.
|
||||
- [compiler.md:302](../../schema/compiler.md#L302) — §5.10-Pkt.-8 Erhaltungs-Invariante & Determinismus-Vertrag: Reconcile-Orphan-Regel (Zuwachs gg. Baseline, datumsgruppierter `log.md`-Eintrag, kein Banner, AD-16-Default).
|
||||
|
||||
**§7/§8-Nachweis**
|
||||
|
||||
- [compiler.md:477](../../schema/compiler.md#L477) — Revisionslog Revision 3.3: §5.14-Verankerung, §7-Determinismus-Vorbehalt aufgelöst, §8-AD-17h-Normreferenz auf §5.14-Anker, Abschlussklausel (AD-3/D-3/keine neue §7-Klasse).
|
||||
|
||||
**Sandbox-Beweis (mechanische Bestätigung)**
|
||||
|
||||
- [run-sandbox.sh:245](../../_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh#L245) — DET-2 Szenario-Start: zwei getrennte Worktrees + frische Kontexte über demselben committeten Baum; Einstieg in die gehärtete Determinismus-Mechanik (Review-Loop-2).
|
||||
- [run-sandbox.sh:265](../../_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh#L265) — Kanonisches Eingabemanifest (`manifest_path`), das jetzt VOR jedem Lauf konsumiert/validiert wird (nicht dekorativ; Review-Loop-2-Patch; Review-Loop-3 P-6: `generated_by` wird konsumiert).
|
||||
- [run-sandbox.sh:442](../../_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh#L442) — DET-2 RESULT: Receipts byte-identisch bis auf `at_cell`/`tree` (Ausnahme-Cells); att real committet, erst beim Vergleich normalisiert — dokumentierte Ausnahme statt stiller Ausschluss (Review-Loop-3 P-7: at-Ausnahme hart assertiert, Wiederholungs-Schleife bei Sekundenkollision).
|
||||
- [run-sandbox.sh:275](../../_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh#L275) — `set -e`-Subshell: jeder fehlende Schritt bricht als rc≠0 ab (kein false-PASS; Review-Loop-2-Patch).
|
||||
- [run-sandbox.sh:447](../../_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh#L447) — DET-3: künstlich divergenter Lauf → AD-16-Klassifikationsdefekt, textuell benannt (NFR-4), korrigierte Wiederholung == Referenz.
|
||||
- [run-sandbox.sh:531](../../_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh#L531) — DET-4: `generated.at`-Gap als einzige benannte Ausnahme; at-Maskierung beim Vergleich (byte-identische Restteile) + Negativkontrolle.
|
||||
|
||||
**Story-Protokoll/Defers (Peripherie, zuletzt)**
|
||||
|
||||
- [log.md:4](../../wiki/log.md#L4) — Story-3.8-Eintrag: Verankerung, Sandbox-Nachweis, Erhaltungs-Invariante, Validator-Verdikt; Revision 3.3.
|
||||
- [deferred-work.md:492](../../_bmad-output/implementation-artifacts/deferred-work.md#L492) — aufgegriffene/geschlossene „Home: Story 3.8"-Defers (7 `### Aufgegriffen` + 1 `### Aufgegriffen (teilweise)`, append-only ab Zeile 492).
|
||||
- [spec:122](../../_bmad-output/implementation-artifacts/spec-3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato.md#L122) — Spec Change Log Review-Loop-2: 10 Patches der Sandbox-Härtung (at-Ausnahme real ausgeübt, Manifest-Validierung, Receipt order/decisions, `set -e`, literal-sichere Stufe-a).
|
||||
- [sprint-status.yaml:61](../../_bmad-output/implementation-artifacts/sprint-status.yaml#L61) — Key `3-8-determinismus-…` auf `review` (Review-Start-Flip Step-04); `done`-Transition im Step-05.
|
||||
+229
File diff suppressed because one or more lines are too long
@@ -29,7 +29,7 @@
|
||||
# - Dev moves story to 'review', then runs code-review (fresh context, different LLM recommended)
|
||||
# - Retrospective appends its action items to action_items; the status view surfaces open ones
|
||||
generated: 08-14-2026 00:00
|
||||
last_updated: 08-20-2026 08:56
|
||||
last_updated: 08-21-2026 10:16
|
||||
project: wow20
|
||||
project_key: NOKEY
|
||||
tracking_system: file-system
|
||||
@@ -58,7 +58,12 @@ development_status:
|
||||
3-5-leasing-dirty-tree-schutz-für-konkurrierende-producer-umsetz: done
|
||||
3-6-lease-staleness-recovery-basis-absichern: done
|
||||
3-7-reason-mutate-trennung-und-konsistenz-endzustand-sicherstell: done
|
||||
3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato: backlog
|
||||
3-8-determinismus-vertrag-ad-17h-als-agent-instruktions-validato: done # Review-Loop-3-Abschluss 2026-08-20 (bmad-code-review; D-2-Entscheidung). Hinweis: die Abschluss-Reihenfolge „3.9 → 3.10 / 3.11 → 3.12 → 3.8 Abschluss → 3.13 Abnahme" des genehmigten Sprint-Change-Proposal 2026-08-20 betrifft das Epic-3-Abnahmegate (3.13) — die Story-3.8-Instruktionsverankerung ist abgeschlossen (done); die 3.9–3.12-Verankerungen und die 3.13-Abnahme bleiben offen (epic-3 remains in-progress).
|
||||
3-9-deterministische-relevanz-und-reconcile-routing-schliessen: done # Review-Loop-3-Abschluss 2026-08-21 (bmad-code-review, 4 Layer; D-3.9-1/2/3 = 1/1/2 — empfohlene Optionen; kein Loopback). Hinweis: der finale `done`-Flip ist der Step-05-Status-Sync nach konvergiertem Review-Loop (Präzedenz Story 3.7/3.8); die Epic-3-Abnahme (3.13) bleibt offen (epic-3 remains in-progress).
|
||||
3-10-inkrementelle-update-und-synthese-erhaltung-absichern: backlog
|
||||
3-11-root-scope-leasing-atomar-akquirieren: backlog
|
||||
3-12-lease-lifecycle-und-commit-abschluss-transaktional-schliessen: backlog
|
||||
3-13-epic-3-verifikations-und-abnahmegate: backlog
|
||||
epic-3-retrospective: optional
|
||||
|
||||
epic-4: backlog
|
||||
|
||||
@@ -88,16 +88,17 @@ Aus den Sources entstehen eigenständige, OKF-0.2-konforme Concepts mit claim-gr
|
||||
**AD/A0:** AD-1, AD-4, AD-4a, AD-4b, AD-4c, AD-7, AD-7a..7d, AD-8, AD-9, A0-3, A0-4, A0-5, A0-8, A0-9, A0-10, A0-20
|
||||
|
||||
### Epic 3: Inkrementelle Kompilation & Synthese
|
||||
Der Nutzer verarbeitet neue Sources gegen das bestehende Wiki: bestehende Concepts werden erweitert, präzisiert oder korrigiert; mehrere Sources werden zu einer gemeinsamen Wissensrepräsentation synthetisiert; unverändertes Wissen bleibt erhalten. Die Relevanzbestimmung erfolgt textual-deterministisch (grep/ripgrep/Traversal, AD-13); Producer arbeiten auf `lease/<area>/<id>`-Branches mit Dirty-Tree-Schutz, Root-Scope-Lease und commit-gebundener Mutation (AD-17a..h).
|
||||
Der Nutzer verarbeitet neue Sources gegen das bestehende Wiki: bestehende Concepts werden erweitert, präzisiert oder korrigiert; mehrere Sources werden zu einer gemeinsamen Wissensrepräsentation synthetisiert; unverändertes Wissen bleibt erhalten. Die Relevanzbestimmung erfolgt textual-deterministisch (grep/ripgrep/Traversal, AD-13); Producer arbeiten mit atomarer Root-Scope-Lease, Dirty-Tree-Schutz und commit-gebundener Mutation. Klassifikationspflichtige Kollisionen enden bis Epic 4 fail-closed in einem strukturierten Hold; der Determinismus-Vertrag wird unabhängig und mechanisch qualifiziert.
|
||||
**FRs covered:** FR-4, FR-6, FR-7, FR-12
|
||||
**NFRs covered:** NFR-7
|
||||
**AD/A0:** AD-5, AD-6, AD-13, AD-17, AD-17a..17h, A0-6, A0-7, A0-12..A0-18, A0-19, A0-21
|
||||
**AD/A0:** AD-5, AD-6, AD-13, AD-17a, AD-17b, AD-17c (Fail-closed-Sicherheitsgrenze), AD-17d..17f, AD-17h, A0-6, A0-7, A0-12, A0-13, A0-14 (No-Auto-Merge-Sicherheitsgrenze), A0-15, A0-16, A0-18, A0-19, A0-21 (Incrementality-Teil)
|
||||
**Shared boundary:** Epic 3 verantwortet bei AD-17c/A0-14 ausschließlich Erkennung und fail-closed Erhaltung; Epic 4 verantwortet Klassifikation und semantische Auflösung. Bei A0-21 verantwortet Epic 3 die Erhaltung unabhängigen Wissens, Story 4.3 die spezifische Human-Curation-Semantik.
|
||||
|
||||
### Epic 4: Wissenstreue — Widersprüche & menschliche Kuratierung
|
||||
Widersprüche werden nie stillschweigend zur scheinbar eindeutigen Aussage zusammengeführt; relevante Disagreements bleiben als explizite Einträge in `log.md` erhalten; menschlich kuratierte Inhalte werden als bestehendes Wissen respektiert und bleiben über OKF-Trust-Metadaten (`verified: human:...`) von ungeprüftem maschinellem Output unterscheidbar; unvollständiges/ungeprüftes Wissen wird ohne künstliche Gewissheit dargestellt.
|
||||
**FRs covered:** FR-8, FR-13
|
||||
**NFRs covered:** NFR-7
|
||||
**AD/A0:** AD-16, AD-16a, AD-16b, AD-15, A0-11, A0-17, A0-20
|
||||
**AD/A0:** AD-16, AD-16a, AD-16b, AD-15, AD-17c, AD-17g, A0-11, A0-14, A0-17, A0-20, A0-21
|
||||
|
||||
### Epic 5: Consumer-Zugriff & Nachvollziehbarkeit
|
||||
Menschen und beliebige LLM-Agenten (BMAD, Claude Code, Codex, ...) lesen das Knowledge Bundle ohne Wiki-of-Wikis-spezifische Runtime; Änderungen sind über Git-Diffs nachvollziehbar; die kanonischen Compiler-Regeln sind agent-unabhängig mit dünnen Adaptern; es gibt keinen obligatorischen Server, keine Datenbank und keine proprietäre Abhängigkeit.
|
||||
@@ -257,8 +258,9 @@ So that ein Consumer relevantes Wissen schrittweise findet, ohne das gesamte Wik
|
||||
|
||||
## Epic 3: Inkrementelle Kompilation & Synthese
|
||||
|
||||
Der Nutzer verarbeitet neue Sources gegen das bestehende Wiki: bestehende Concepts werden erweitert, präzisiert oder korrigiert; mehrere Sources werden zu einer gemeinsamen Wissensrepräsentation synthetisiert; unverändertes Wissen bleibt erhalten. Relevanzbestimmung erfolgt textual-deterministisch (grep/ripgrep/Traversal, AD-13); Producer arbeiten auf `lease/<area>/<id>`-Branches mit Dirty-Tree-Schutz, Root-Scope-Lease und commit-gebundener Mutation (AD-17a..h).
|
||||
**FRs covered:** FR-4, FR-6, FR-7, FR-12 · **NFRs:** NFR-7 · **AD/A0:** AD-5, AD-6, AD-13, AD-17, AD-17a..17h, A0-6, A0-7, A0-12..A0-18, A0-19, A0-21
|
||||
Der Nutzer verarbeitet neue Sources gegen das bestehende Wiki: bestehende Concepts werden erweitert, präzisiert oder korrigiert; mehrere Sources werden zu einer gemeinsamen Wissensrepräsentation synthetisiert; unverändertes Wissen bleibt erhalten. Relevanzbestimmung erfolgt textual-deterministisch (grep/ripgrep/Traversal, AD-13); Producer arbeiten mit atomarer Root-Scope-Lease, Dirty-Tree-Schutz und commit-gebundener Mutation. Klassifikationspflichtige Kollisionen enden bis Epic 4 fail-closed in einem strukturierten Hold; der Determinismus-Vertrag wird unabhängig und mechanisch qualifiziert.
|
||||
**FRs covered:** FR-4, FR-6, FR-7, FR-12 · **NFRs:** NFR-7 · **AD/A0:** AD-5, AD-6, AD-13, AD-17a, AD-17b, AD-17c (Fail-closed-Sicherheitsgrenze), AD-17d..17f, AD-17h, A0-6, A0-7, A0-12, A0-13, A0-14 (No-Auto-Merge-Sicherheitsgrenze), A0-15, A0-16, A0-18, A0-19, A0-21 (Incrementality-Teil)
|
||||
**Shared boundary:** Epic 3 verantwortet bei AD-17c/A0-14 ausschließlich Erkennung und fail-closed Erhaltung; Epic 4 verantwortet Klassifikation und semantische Auflösung. Bei A0-21 verantwortet Epic 3 die Erhaltung unabhängigen Wissens, Story 4.3 die spezifische Human-Curation-Semantik.
|
||||
|
||||
### Story 3.1: Inkrementellen Datenfluss implementieren (Interpret → Reconcile → Synthesize → Update)
|
||||
|
||||
@@ -316,14 +318,14 @@ So dass kein separates Summary pro Quelle entsteht und die gemischte Provenienz
|
||||
|
||||
As a Producer/Compiler,
|
||||
I want auf `lease/<area>/<id>`-Branches mit Root-Scope-Lease und Dirty-Tree-Schutz zu arbeiten,
|
||||
So dass zwei Producer denselben Concept-Pfad nicht stillschweigend überschreiben und Fremdänderungen nie als Nebenwirkung gelöscht werden (AD-17, AD-17a..f, A0-12..A0-16).
|
||||
So dass zwei Producer denselben Concept-Pfad nicht stillschweigend überschreiben und Fremdänderungen nie als Nebenwirkung gelöscht werden (AD-17a, AD-17b, AD-17e/f, A0-12, A0-13, A0-16; semantische Kollisionsauflösung in Epic 4).
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
**Given** ein Producer, **When** er einen Bereich bearbeitet, **Then** arbeitet er auf einem `lease/<area>/<id>`-Branch und akquiriert die Lease gegen einen eindeutigen Commit-Object-Wert (Merge-Base-Disziplin) (AD-17a, A0-12).
|
||||
**Given** eine Lease, **When** sie vergeben ist, **Then** umfasst sie die Root-Scope inklusive `log.md`, `index.md` und aller Root-Dateien (AD-17b, A0-13).
|
||||
**Given** eine vorliegende uncommittete Fremdänderung im zu mutierenden Bereich, **When** der Producer mutieren will, **Then** schützt er sie (Stash/Scratch-Zone) und dokumentiert den Vorgang in `log.md` (AD-17e, A0-16).
|
||||
**Given** zwei Branches mit Änderungen am selben Concept-Pfad, **When** gemerged werden soll, **Then** erfolgt kein stiller textueller Auto-Merge (AD-17c, A0-14) — Auflösung compiler-vermittelt über AD-16 mit explizitem `log.md`-Eintrag.
|
||||
**Given** zwei Branches mit ungleichen Änderungen am selben Concept-Pfad, **When** vor Epic 4 ein Merge versucht wird, **Then** erfolgt kein textueller Auto-Merge; der Run endet mit einem strukturierten Kollisions-Hold, der beide Commit-Hashes und den betroffenen Scope erhält. AD-16-Klassifikation und semantische Auflösung folgen in Epic 4 (Sicherheitsgrenze von AD-17c; vollständige Auflösung in Story 4.1/4.2).
|
||||
**And** Mutationen operieren nur auf Directory-/Commit-Ebene — Commit-Boundary ist die Mutation-Boundary (AD-17f, A0-16).
|
||||
|
||||
### Story 3.6: Lease-Staleness & Recovery-Basis absichern
|
||||
@@ -356,21 +358,104 @@ So dass ein teilweise fehlgeschlagener Run nie ein inkonsistentes Bundle hinterl
|
||||
|
||||
As a Compiler,
|
||||
I want dass derselbe Git-State + dieselbe Eingabemenge bei zwei unabhängigen Runs denselben Bundle-State erzeugt,
|
||||
So dass die AD-16-Klassifikation deterministisch genug ist (AD-17h, FT-10, A0-19).
|
||||
So dass Relevanz-, Routing-, Planungs- und Mutationsentscheidungen reproduzierbar sind (AD-17h, FT-10, A0-19).
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
**Given** einen Fixed Git-State und eine feste Eingabemenge, **When** zwei unabhängige Runs ausgeführt werden, **Then** produzieren sie identische Bundle-Zustände (FT-10, AD-17h).
|
||||
**Given** eine Abweichung bei zwei solchen Runs, **When** sie festgestellt wird, **Then** wird sie als Fehler im AD-16-Klassifikations-Mechanismus behandelt (nicht als akzeptables Rauschen) (AD-17h).
|
||||
**Given** der MVP (D-3), **When** die Determinsmus-Enforcement fehlt, **Then** lebt sie als Agent-Instruktions-Validator und ist vor Last tragenden Anspruch als mechanisch bestätigt (Q-6, A0-19).
|
||||
**Given** eine Abweichung bei zwei solchen Runs, **When** sie festgestellt wird, **Then** wird sie als Determinismusfehler behandelt und der Run gilt als fehlgeschlagen — nicht als akzeptables Rauschen (AD-17h). *Präzisierung (Review-Loop-3, 2026-08-20): „Determinismusfehler" = **Fehler der AD-16-Klassifikation** (AD-16-Klassifikationsdefekt) im Sinne von §5.14 Pkt. 4 `schema/compiler.md` — der AC-Wortlaut „Determinismusfehler" bleibt erhalten; die Klassifikations-Verknüpfung (AD-16) war bei Story-Aufnahme nicht ausgeschrieben und wird hier nachgeführt, ohne den AC-Sinn zu ändern.*
|
||||
**Given** der MVP (D-3), **When** der Agent-Instruktions-Validator ausgeführt wird, **Then** laufen die beiden Ausführungen in getrennten sauberen Worktrees und frischen Agent-Kontexten; eine zweite Ausführung in derselben Session genügt nicht (Q-6, A0-19).
|
||||
**Given** das kanonische Eingabemanifest, **When** ein Run geplant wird, **Then** hält es Baseline-Commit, geordnete Source-Eingaben und jeden im Bundle sichtbaren Run-/Zeit-/Identitätswert explizit fest; der Run-Receipt enthält Candidate-Liste, Reihenfolge, Plan, Entscheidungen und Output-Hashes außerhalb des Knowledge Bundle.
|
||||
**Given** der Zwei-Run-Nachweis, **When** Pläne und Bundle-State verglichen werden, **Then** dürfen weder erwartete Pläne noch Concept-Bodies im Test hart codiert werden; `verified`-Ereignisse werden niemals pauschal aus dem Vergleich maskiert.
|
||||
**And** der Validator hält keine Embedding-/Vector-Infrastruktur vor (AD-13; FT-3, FT-4).
|
||||
|
||||
### Story 3.9: Deterministische Relevanz- und Reconcile-Routing schließen
|
||||
|
||||
As a Compiler,
|
||||
I want Evidenz deterministisch bestehenden, neuen oder nicht klassifizierbaren Wissenseinheiten zuordnen,
|
||||
So that keine relevante Information still ignoriert, dupliziert oder falsch verwaist wird (FR-4, FR-5-Interaktion, FR-6, FR-12, AD-5, AD-13, A0-6, A0-18).
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
**Given** einen committeten Git-State und ein kanonisches Eingabemanifest, **When** Candidate-Terme gewonnen werden, **Then** folgt die Gewinnung einem geschlossenen, geordneten Algorithmus oder einem expliziten, persistierten Term-Manifest — keine freie Producer-Auswahl.
|
||||
**Given** semantisch gleiche Schreibweisen mit Groß-/Kleinschreibung, Leerzeichen, Unterstrich, Bindestrich, En-Dash oder Em-Dash, **When** die Stufe-a-Suche läuft, **Then** werden Suchterm und Concept-Body identisch normalisiert und literal-sicher verglichen; `index.md`-Treffer bleiben für die Traversal-Stufe erhalten.
|
||||
**Given** interpretierte Evidenz, **When** Reconcile abgeschlossen wird, **Then** gilt genau eine Routing-Tabelle: bestehender Match → `UPDATE`; eigenständige neue Wissenseinheit → `CREATE`; nicht klassifizierbare Evidenz → expliziter `ORPHAN/HOLD`; bereits vollständig repräsentierte identische Evidenz → `NO_OP`.
|
||||
**Given** eine geänderte oder gelöschte bereits committete Datei unter `raw/`, **When** der Run seine Eingaben prüft, **Then** schlägt er vor jeder Mutation fehl; akzeptiert werden nur neu hinzugefügte oder separat versionierte Sources (AD-3).
|
||||
**Given** ein neues Concept-Ziel, **When** dessen Slug `index` oder `log` beziehungsweise ein anderer reservierter Bundle-Name wäre, **Then** wird das Ziel nicht geschrieben und ein deterministischer Hold verlangt eine disambiguierte Identität.
|
||||
**And** gleicher Git-State plus gleiches Eingabemanifest erzeugt dieselbe Candidate-Liste, Reihenfolge und Routing-Entscheidung (AD-17h, A0-19), belegt durch positive und negative ausführbare Fixtures.
|
||||
|
||||
### Story 3.10: Inkrementelle Update- und Synthese-Erhaltung absichern
|
||||
|
||||
As a Compiler,
|
||||
I want bestehendes Wissen semantisch erweitern und mehrere Sources kohärent synthetisieren,
|
||||
So that neues Wissen integriert wird, ohne gültiges vorhandenes Wissen oder Provenienz zu verlieren (FR-4, FR-6, FR-7, FR-12, AD-4, AD-5).
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
**Given** eine passende neue Erkenntnis zu einem bestehenden Concept, **When** der Run sie verarbeitet, **Then** wird das bestehende Concept in-place erweitert oder präzisiert und kein thematisches Duplikat angelegt.
|
||||
**Given** explizite aktuelle Evidenz, die eine bestehende Aussage eindeutig korrigiert, ohne dass zwischen weiterhin gültigen Sources ein Widerspruch verbleibt, **When** der Run sie verarbeitet, **Then** wird das bestehende Concept in-place korrigiert und die ersetzte Aussage samt Source-Basis bleibt im Run-Receipt nachvollziehbar; mehrdeutige Fälle gehen in den Hold für Epic 4.
|
||||
**Given** ein betroffenes Concept mit weiterhin gültigen Aussagen und Provenienz, **When** es aktualisiert wird, **Then** bleiben diese geschützten Bestandteile erhalten; nicht betroffene Concepts bleiben byte-identisch.
|
||||
**Given** eine neue Source, die eine bestehende Aussage unabhängig bestätigt, **When** synthetisiert wird, **Then** erscheint die Aussage genau einmal und trägt alle beitragenden Evidenzanker; die neue Source ist kein `NO_OP`.
|
||||
**Given** mehrere Sources mit redundanten und ergänzenden Aussagen, **When** der Run synthetisiert, **Then** entsteht eine gemeinsame Wissensrepräsentation mit claim-granularer gemischter Provenienz — keine Source-A/Source-B-Aneinanderreihung.
|
||||
**Given** eine bereits vollständig repräsentierte identische Source samt Evidenzanker, **When** sie erneut verarbeitet wird, **Then** ist der Run für dieses Wissen byte-erhaltend (`NO_OP`).
|
||||
**Given** der Provenienz- und Link-Selbsttest, **When** erwartete Deltas bestimmt werden, **Then** stammen Baseline und Erwartung aus dem aktuellen Run; kein historischer, fest codierter Commit oder globaler Zählwert ist normativ.
|
||||
**And** klassifikationspflichtige oder widersprüchliche Evidenz wird bis Epic 4 ohne Wissensmutation in einem benannten Hold erhalten; beide Evidenzpfade bleiben im Run-Receipt nachvollziehbar (NFR-7).
|
||||
|
||||
### Story 3.11: Root-Scope-Leasing atomar und worktree-übergreifend akquirieren
|
||||
|
||||
As a Producer,
|
||||
I want pro kanonischem Scope genau eine atomare Lease erwerben,
|
||||
So that verschiedene Run-IDs niemals gleichzeitig Schreibzugriff auf dasselbe Knowledge Bundle erhalten (AD-17a, AD-17b, A0-12, A0-13).
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
**Given** den Root-Scope `wiki/`, **When** eine Lease akquiriert wird, **Then** existiert genau ein scope-bezogener Lock im clone-geteilten Zustand; die Run-ID ist Lock-Inhalt und nicht Teil des Exklusivitätsschlüssels.
|
||||
**Given** zwei Producer mit verschiedenen IDs und Worktrees, **When** beide denselben Root-Scope akquirieren, **Then** ist die Akquise atomar und genau ein Producer erhält die Lease; der andere erhält `LEASE_HOLD`.
|
||||
**Given** einen abgewiesenen Producer, **When** sein Lauf endet, **Then** verändert er weder `wiki/` noch den bestehenden Lock, erzeugt keinen Compilation Commit und entfernt keine fremde Lease.
|
||||
**Given** einen realen Zwei-Worktree-/Zwei-Prozess-Test, **When** die Akquise zeitlich überlappt, **Then** beweisen Zwischenzustands-Assertions, dass niemals zwei aktive Root-Leases gleichzeitig existieren.
|
||||
**And** ungleiche Änderungen am selben Concept-Pfad werden nicht automatisch gemerged, sondern als strukturierter Kollisions-Hold mit beiden Commit-Hashes an Epic 4 übergeben.
|
||||
|
||||
### Story 3.12: Lease-Lifecycle und Commit-Abschluss transaktional schließen
|
||||
|
||||
As an Operator,
|
||||
I want Akquise, Dirty-Tree-Schutz, Mutation, Rollback und Freigabe als konsistenten Lifecycle ausführen,
|
||||
So that SUCCESS und FAIL jeweils einen sauberen, wiederanlaufbaren Zustand hinterlassen (AD-6, AD-17d..17f, A0-7, A0-15, A0-16).
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
**Given** einen lebenden Lease-Halter, **When** eine höhere Generation sichtbar wird, **Then** bleibt seine Lease aktiv; Staleness verlangt bestätigten Abbruch oder abgelaufene Liveness sowie atomare Ownership-Prüfung.
|
||||
**Given** eine nachweislich stale Lease, **When** sie übernommen wird, **Then** gelingt die Übernahme genau einmal, nennt die ersetzte Holder-ID und hinterlässt genau eine aktive Root-Lease.
|
||||
**Given** getrackte oder ungetrackte fremde Änderungen im Mutationsbereich, **When** der Preflight läuft, **Then** folgt er einer eindeutigen Abort-/Protect-Zustandsmaschine und stellt geschützte Bytes nach dem Run vollständig wieder her.
|
||||
**Given** einen Fehler nach Mutation oder Staging, **When** Rollback läuft, **Then** restauriert er explizit aus dem bezeichneten Baseline-Commit sowohl Index als auch Worktree; der Post-Rollback-Diff gegen die Baseline ist leer.
|
||||
**Given** einen erfolgreichen Run, **When** er freigegeben wird, **Then** sind Mutation, zulässiger Log-/Koordinationsnachweis und Release dauerhaft, der aktive Lock ist entfernt, der Worktree ist sauber und der unmittelbar folgende Run besteht den Clean-Input-Guard.
|
||||
**Given** `wiki/log.md`, **When** ein Run protokolliert wird, **Then** enthält das kanonische Knowledge Log nur vertragskonforme fachliche Änderungen und notwendige Koordinationsereignisse; Build-, Review-, Story- und Sandbox-Historie liegt außerhalb des Knowledge Bundle.
|
||||
**And** Kill-Point-Tests vor Mutation, nach Mutation, vor Commit und nach Commit beweisen den jeweils konsistenten Endzustand.
|
||||
|
||||
### Story 3.13: Epic-3-Verifikations- und Abnahmegate
|
||||
|
||||
As a Product Owner/Compiler-Verantwortlicher,
|
||||
I want Epic 3 durch einen realen, reproduzierbaren Source→Compilation→Wiki-Lauf qualifizieren,
|
||||
So that seine Fertigstellung durch ausführbare Evidenz statt handgeschriebene Simulationen belegt ist (SM-1, SM-2, FT-6, FT-10).
|
||||
|
||||
**Acceptance Criteria:**
|
||||
|
||||
**Given** einen sauberen Checkout, **When** das repositoryweite Epic-3-Gate ausgeführt wird, **Then** führt ein Kommando alle Epic-3-Szenarien fail-fast aus; fehlgeschlagene Assertions, übersprungene Szenarien, fehlende Abhängigkeiten und Kindprozessfehler ergeben einen Non-Zero-Exit.
|
||||
**Given** macOS/BSD- und Linux/GNU-Userland, **When** das Gate dort läuft, **Then** ist es ohne plattformspezifisches `sed -i` reproduzierbar, arbeitet ausschließlich in temporären Repositories und hinterlässt `git status --porcelain` unverändert.
|
||||
**Given** positive und negative OKF-Fixtures, **When** validiert wird, **Then** wird der vollständige Vertrag aus `schema/validator.md` über alle `wiki/`-Dateien ausgeführt; unter anderem fehlendes `generated.by`, kalenderinvalides `generated.at`, unzulässige Source-Pfade und gebrochene Index-Links verhindern SUCCESS und Commit.
|
||||
**Given** der autorisierte Validator-Vertrag oder seine ausführbare Aufrufbarkeit weist dabei ein Defizit auf, **When** das Gate es erkennt, **Then** bleibt Story 3.13 offen und benennt den Bedarf für eine separat autorisierte Epic-1-Remediation; Story 3.13 darf die Schema-Semantik nicht still ändern, verantwortet aber die Integration und vollständige Ausführung des bestehenden Vertrags.
|
||||
**Given** eine repräsentative committete Fixture, **When** ein frischer Agent-Kontext die kanonische Instruktion `schema/compiler.md` ausführt, **Then** darf der Harness nach dem Setup weder erwartete Wiki-Bodies noch Lease-, Log- oder Git-Ausgänge selbst schreiben.
|
||||
**Given** diese Fixture, **When** der Compilation Run endet, **Then** demonstriert er Update eines bestehenden Concepts, Anlage einer neuen Wissenseinheit, kohärente Multi-Source-Synthese, vollständige Multi-Evidenz-Provenienz, Source-Immutabilität und byte-identische Erhaltung unabhängigen Wissens.
|
||||
**Given** dasselbe kanonische Eingabemanifest, **When** zwei frische Agent-Kontexte in getrennt aufgebauten Worktrees laufen, **Then** stimmen Run-Receipts und Bundle-State gemäß Story 3.8 überein; eine perturbierte Entscheidung oder Ausgabe wird erkannt.
|
||||
**Given** nur das erzeugte Knowledge Bundle ohne Planungsartefakte, **When** ein unabhängiger Consumer im Epic-5-Abhängigkeits-Smoke-Test vordefinierte Wissensfragen beantwortet, **Then** benötigt er weder Product Brief, SPEC, Architecture Spine noch Story-Historie zum semantischen Verständnis; solche Referenzen sind höchstens optionale Provenienz/Traceability. Dieser Smoke-Test nimmt die vollständige FR-15/FR-16-Abnahme aus Epic 5 nicht vorweg.
|
||||
**And** erst nach bestandenem Gate und `done`-Status aller Stories 3.8 bis 3.13 wird Epic 3 auf `done` gesetzt; bis dahin bleibt Epic 3 `in-progress`.
|
||||
|
||||
---
|
||||
|
||||
## Epic 4: Wissenstreue — Widersprüche & menschliche Kuratierung
|
||||
|
||||
Widersprüche werden nie stillschweigend zur scheinbar eindeutigen Aussage zusammengeführt; relevante Disagreements bleiben als explizite Einträge in `log.md` erhalten; menschlich kuratierte Inhalte werden als bestehendes Wissen respektiert und bleiben über OKF-Trust-Metadaten (`verified: human:...`) von ungeprüftem maschinellem Output unterscheidbar; unvollständiges/ungeprüftes Wissen wird ohne künstliche Gewissheit dargestellt.
|
||||
**FRs covered:** FR-8, FR-13 · **NFRs:** NFR-7 · **AD/A0:** AD-16, AD-16a, AD-16b, AD-15, A0-11, A0-17, A0-20
|
||||
Epic 4 beginnt nach bestandenem Story-3.13-Abnahmegate und übernimmt die in Epic 3 fail-closed erhaltenen Kollisions-/Widerspruchs-Holds zur semantischen Klassifikation und Auflösung.
|
||||
**FRs covered:** FR-8, FR-13 · **NFRs:** NFR-7 · **AD/A0:** AD-16, AD-16a, AD-16b, AD-15, AD-17c, AD-17g, A0-11, A0-14, A0-17, A0-20, A0-21
|
||||
|
||||
### Story 4.1: Information vor jeder Änderung klassifizieren (NEW/CONFIRMING/CORRECTING/CONTRADICTING/REDUNDANT)
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: Sprint Change Proposal — Epic 3 Completion Remediation
|
||||
status: approved
|
||||
created: 2026-08-20
|
||||
approved_by: ProMods
|
||||
approval: "Explizite Chat-Freigabe: Ja"
|
||||
classification: moderate
|
||||
affected_epic: 3
|
||||
---
|
||||
|
||||
# Sprint Change Proposal: Epic 3 belastbar abschließen
|
||||
|
||||
## 1. Issue Summary
|
||||
|
||||
Der unabhängige Read-only-Audit nach Story 3.8 zeigte, dass Epic 3 seine bereits zugesagten Anforderungen und Architekturverträge noch nicht als kohärenten System-Inkrement belegt. Betroffen sind insbesondere deterministische Relevanz und Routing, semantische Update-/Synthese-Erhaltung, Root-Scope-Leasing, transaktionaler Run-Abschluss, AD-17h-Reproduzierbarkeit und die ausführbare End-to-End-Abnahme.
|
||||
|
||||
Der Trigger ist kein neuer Produktwunsch, sondern eine fehlgeschlagene Verifikation bestehender Zusagen aus FR-4, FR-6, FR-7, FR-12, AD-5/6/13/17 und A0-6/7/12..19. Konkrete Evidenz liegt in `schema/compiler.md`, den Story-3-Sandboxes, `wiki/log.md`, dem Sprint-Status und `epic-3-context.md` vor.
|
||||
|
||||
## 2. Impact Analysis
|
||||
|
||||
### Epic Impact
|
||||
|
||||
- Epic 3 bleibt `in-progress`; Story 3.8 wird aus `review` nach `in-progress` zurückgenommen.
|
||||
- Stories 3.9–3.13 werden innerhalb von Epic 3 ergänzt.
|
||||
- Ein neues Epic ist nicht gerechtfertigt: Alle Arbeiten schließen bereits zugesagte Epic-3-Verträge.
|
||||
- Epic 4 beginnt erst nach dem Story-3.13-Abnahmegate.
|
||||
|
||||
### Scope Boundary zu Epic 4
|
||||
|
||||
Epic 3 erkennt klassifikationspflichtige Kollisionen und Widersprüche und hält fail-closed an; dies ist seine Sicherheitsgrenze aus AD-17c/A0-14. Vollständige AD-16-Klassifikation, semantische Kollisionsauflösung (AD-17c/g) und Disagreement-Dokumentation verbleiben in Epic 4. A0-21 ist geteilt: Story 3.10 belegt die Erhaltung unabhängigen Wissens, Story 4.3 das Human-Curation-Verhalten/FT-9. Damit entfällt die bisherige zyklische Behauptung, Epic 3 sei abgeschlossen, obwohl sein Merge-/Resolution-Pfad Epic 4 voraussetzt.
|
||||
|
||||
### Artifact Impact
|
||||
|
||||
- PRD: keine Änderung.
|
||||
- Architecture Spine: keine Änderung; die Story-Zuordnung wird mit den bestehenden Entscheidungen konsistent gemacht.
|
||||
- `epics.md`: Scope-Korrektur, Story-3.8-Präzisierung und Stories 3.9–3.13.
|
||||
- `sprint-status.yaml`: Story 3.8 `in-progress`, neue Stories `backlog`.
|
||||
- `epic-3-context.md`: Story-Liste, technische Grenzen und Abhängigkeiten synchronisiert.
|
||||
- Code, Compiler-Instruktion, Tests und Knowledge Bundle werden durch diese Planungskorrektur nicht verändert.
|
||||
|
||||
## 3. Recommended Approach
|
||||
|
||||
**Gewählt: Direct Adjustment innerhalb von Epic 3.**
|
||||
|
||||
Rollback bereits abgeschlossener Stories würde die vorhandene Arbeit nicht vereinfachen. Eine PRD-/MVP-Neudefinition ist ebenfalls nicht nötig. Die kleinste kohärente Korrektur ist, die offenen systemischen Verantwortungen in klar geschnittene Remediation-Stories zu überführen, Story 3.8 ehrlich wieder zu öffnen und ein finales ausführbares Abnahmegate einzuführen.
|
||||
|
||||
Aufwand: mittel bis hoch. Risiko: mittel bei Umsetzung vor Epic 4; hoch, falls Epic 4 auf dem derzeit unzuverlässigen Lease-/Log-/Compiler-Unterbau beginnt.
|
||||
|
||||
## 4. Detailed Change Proposals
|
||||
|
||||
### Bestehende Story
|
||||
|
||||
- **Story 3.8 — Determinismus-Vertrag:** wieder öffnen; zwei getrennte Worktrees und frische Agent-Kontexte, kanonisches Eingabemanifest, rekonstruierbarer Run-Receipt, keine hart codierten Outputs und keine pauschale Maskierung von Trust-Ereignissen.
|
||||
|
||||
### Neue Stories
|
||||
|
||||
1. **Story 3.9 — Deterministische Relevanz- und Reconcile-Routing schließen**
|
||||
|
||||
Schließt Termgewinnung, symmetrische Normalisierung, literal-sichere Suche, exklusive Routing-Tabelle, Raw-Immutability-Guard und reservierte Zielpfade.
|
||||
|
||||
2. **Story 3.10 — Inkrementelle Update- und Synthese-Erhaltung absichern**
|
||||
|
||||
Beweist In-place-Update, Erhaltung vorhandenen Wissens, vollständige Multi-Evidenz-Provenienz, echten No-op und kohärente Synthese ohne historische Hardcodings.
|
||||
|
||||
3. **Story 3.11 — Root-Scope-Leasing atomar und worktree-übergreifend akquirieren**
|
||||
|
||||
Realisiert einen scope-bezogenen atomaren Lock und echte konkurrierende Worktree-Tests für unterschiedliche Run-IDs.
|
||||
|
||||
4. **Story 3.12 — Lease-Lifecycle und Commit-Abschluss transaktional schließen**
|
||||
|
||||
Schließt Staleness/Liveness, Dirty-Tree-Schutz, Baseline-Rollback, durable Release, Clean-Next-Run und die Grenze des kanonischen Knowledge Logs.
|
||||
|
||||
5. **Story 3.13 — Epic-3-Verifikations- und Abnahmegate**
|
||||
|
||||
Führt portable fail-fast Verifikation, vollständigen OKF-Validator, einen realen Agent-Instruktionslauf, unabhängige Reproduktion und einen Epic-5-Abhängigkeits-Smoke-Test zusammen.
|
||||
|
||||
### Reihenfolge
|
||||
|
||||
```text
|
||||
3.9 → 3.10 ┐
|
||||
├→ 3.8 Abschluss → 3.13 Abnahme → Epic 4
|
||||
3.11 → 3.12┘
|
||||
```
|
||||
|
||||
## 5. Implementation Handoff
|
||||
|
||||
**Klassifikation:** Moderate Backlog-Reorganisation, anschließend Developer-/Review-Ausführung.
|
||||
|
||||
- Product Owner: bestätigt Story-Schnitt und Scope-Grenze — erfolgt am 2026-08-20.
|
||||
- Developer: implementiert Stories in der angegebenen Abhängigkeitsreihenfolge.
|
||||
- Reviewer: prüft jede Story gegen ihre ausführbaren Negativ- und Positivbelege; Story 3.13 ist die Epic-Abnahme.
|
||||
- Epic 3 wird erst `done`, wenn Story 3.8 und Stories 3.9–3.13 `done` sind und das Story-3.13-Gate erfolgreich ist.
|
||||
|
||||
## 6. Checklist Record
|
||||
|
||||
- [x] Trigger und konkrete Audit-Evidenz verstanden
|
||||
- [x] Auswirkungen auf Epic 3, Epic 4 und Epic 5 geprüft
|
||||
- [x] PRD-/Architecture-Konflikte geprüft; keine Änderung erforderlich
|
||||
- [x] Direct Adjustment gegen Rollback und MVP-Neuschnitt bewertet
|
||||
- [x] Story-Schnitt, Reihenfolge und Handoff festgelegt
|
||||
- [x] Explizite Nutzerfreigabe erhalten
|
||||
- [x] Sprint-Status und Epic-Kontext synchronisiert
|
||||
+48
-8
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user