5 Commits
Author SHA1 Message Date
Michael TamseandClaude 8c43d3a09c feat: Story 3.9 Review-Loop-3-Abschluss (bmad-code-review, 4 Layer; kein Loopback)
- 3 Decision-Resolutionen (D-3.9-1/2/3 = Option 1/1/2 — empfohlene Optionen)
- 14 Patches angewandt (von 15): P-3.9-1 Escaper-„Fehlalarm" verworfen — die
  „Ausführungs"-Evidenz war durch die Bash-Tool-Transport-Schicht korrumpiert
  (Backslash-Ebene halbiert); od-Beweis + Negativ/Positiv-Kontrolle aus
  Datei-Bytes belegen: Escaper literal-sicher, run-sandbox.sh Z. 74/790 unverändert
- 2 Defers (Home Story 3.13, Präzedenz DET-1/2), 9 verworfen
- Sandbox Minimal-Härtung (D-3.9-3 Option 2): R-1..R-9 mit echter feuernder
  Mechanik + echten Negativ-Kontrollen; Exit 0 auf frischem /tmp-Root,
  Re-Run-Idempotenz bestätigt
- compiler.md §5.15 (Pkt. 1/2/5 + Revision 3.4-Wortlaut), I/O-Matrix M/D/R,
  frozen-Schließtag + I/O-Zelle (Change-Log-autorisiert, keine Neu-Verhandlung)
- AD-3 read-only & wiki/-Erhaltungs-Invariante verifiziert (Validator SUCCESS)
- sprint-status 3-9 → done; Step-05 Status-Sync + Step-06 Abschluss

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-21 10:53:03 +02:00
Michael TamseandClaude 73f2c9e71d feat: Story 3.9 (Loop-2) — Deterministische Relevanz- & Reconcile-Routing schließen, review reif
§5.15 „Deterministische Relevanz- & Reconcile-Routing (Story 3.9)" in schema/compiler.md
(Revision 3.4): geschlossene Termgewinnung (AC-1), symmetrische Normalisierung +
literal-sichere Suche (AC-2), eine exklusive Routing-Tabelle UPDATE→CREATE→ORPHAN/HOLD→NO_OP
(AC-3, NO_OP als Update-Unter-Entscheidung), Raw-Immutability-Guard M/D/R→Run-FAIL (AC-4),
reservierte Zielpfade index/log/source/README→deterministischer Hold (AC-5), Zwei-Run-Identität
nicht-vakuum inkl. praktisch ausgeübter at-Exzeption (AC-6). §3.2-Pkt.-3d-Anker, §5.14-Pkt.-5-Scope
und §7-Bullet nachgeführt.

Review-Loop-2: 2 bad_spec (BS-L2-1 NO_OP-Leere-Candidate-Liste, BS-L2-2 Status-Codes R/C)
durch Re-Ableitung behoben; Step-04-Re-Review (2 frische Layer + Verification Gap) ohne
neuen Loopback (F-6 Lowercasing-Pkt.-1, F8 Guard-Abbruch real, F9 ableitungsbasierte
Term-Erwartung, F-22/F-27 BUNDLE-BYTE-Nachweis angewandt). Sandbox R-1..R-9 PASS, Exit 0.

Re-Derivation: deferred-work.md D-8/D-9 aufgegriffen; epic-3-context.md Z. 39 → Ist;
sprint-status.yaml Story-3.9 → review. AD-3 read-only + Erhaltungs-Invariante (nur
wiki/log.md) gewahrt. Suggested Review Order in Spec 3.9 angehängt.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-21 06:21:08 +02:00
Michael TamseandClaude 2f079ee3c8 feat: Story 3.8 Review-Loop-3-Abschluss (bmad-code-review Re-Run, 4 Layer; kein Loopback)
Triage: 4 decision-needed / 13 patch / 6 defer / 7 dismissed (u. a. Blind-Hunter
"alle Sandbox-SRO-Anker stale" widerlegt — alle 6 exakt vor den Loop-3-Edits).
Entscheidungen D-1..D-4 (alle Option 1): D-1 Schliessungs-Bullet macht den
"Bekannte Determinismus-Luecke"-Alt-Bullet superseded (append-only-Hinweis,
kein Umbruch); D-2 Story-Status-Flip auf done (Change-Proposal-Sequenzierung
betrafft das Epic-3-Abnahmegate 3.13, nicht die 3.8-Verankerung); D-3
autorisierte Neu-Verhandlung in geringfuegischem Umfang (Typo
"documenthuman" -> "document-human", Spec Re-Open-Delta-Zeile); D-4
Hold-Home = Story 3.10 (Epic 3), Korrektur-/Erweiterungs-Klassifikation =
Epic-4-Interface/Story 4.1 (S5.10 Pkt. 8 praezisiert).
Patches P-1..P-13: SRO-/Code-Map-Anker auf IST-Zeilen (compiler.md
375/376/377/477, Code Map 365-377/424ff/445/477, Sandbox 245/265/442/275/447/531);
symmetrische Term-/Body-Normalisierung (S3.2 Pkt. 2a + match_stufe_a, kein
host-abhaengiges -i); Receipt-Hashvergleich als re-executierbare
Zwei-Run-Formel (S5.14 Pkt. 2); Sandbox-Fresh-Kontext-Restluecke benannt
(mechanisch simuliert; Nachweis = 3.13-Abnahmegate); Manifest generated_by
wird konsumiert; at-Ausnahme hart assertiert (Wiederholungs-Schleife bei
Sekundenkollision, HARD-FAIL statt stiller PASS); "voellig pinbar"/"keine
offene Frage" ge scopet (Umlaut-Defer + 3.9-ACs bewusst offen); epics.md
AC-2 AD-16-Kopplung nachgefuehrt; review_loop_iteration 0 -> 2;
epic-3-context.md 3.9/3.11/3.12-Entscheidungen als Zielzustand markiert;
AD-17-Enum verifiziert (kein Edit noetig); Review-Loop-3-Change-Log-Eintrag.
Sandbox re-executiert: DET-1..DET-8 harte PASS, Exit 0; at-Ausnahme aktiv
(assertiert, real unterschiedliche Wanduhr-at-Werte); Witness nicht-vakuum.
Spec status: done, review_loop_iteration: 2; sprint-status 3-8 -> done
(Sequenzierungs-Hinweis: 3.9-3.12-Verankerungen + 3.13-Abnahme bleiben offen);
wiki/log.md Loop-3-Abschluss-Bullet; deferred-work.md 6 neue Defers.
AD-3 gewahrt: validator.md/wiki-compiler.md/adapters/raw/ unveraendert.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-20 19:12:40 +02:00
Michael Tamse 73d19cbcea @
feat: Story 3.8 Review-Loop-2-Härtung (bmad-code-review Re-Run, 3 Layer; kein Loopback) — DET-2 at-Ausnahme real ausgeübt, Manifest-Validierung, set -e; Step-05 done

Re-Review der Re-Open-Implementierung (3 Subagenten synchron: blind-hunter / edge-case-hunter-Retry / verification-gap): Triage keine intent_gap/bad_spec; 10 Patch / 0 defer / Rest Reject. Kern-Veranlassung: die drei Re-Open-ACs wurden als nicht wirklich ausgeübt erkannt — Manifest dekorativ (nie konsumiert), at-Maskierung vor dem Commit (stiller Ausschluss statt dokumentierter Ausnahme), Reception ohne Reihenfolge-/Entscheidungsfeld, Subshell ohne set -e (false-PASS-Risiko).

Sandbox-Patches (ausschließlich sandbox-3-8/run-sandbox.sh):
- DET-2 gehärtet: generated.at als reale Wanduhr-Ausgabe je Lauf committet (date -u) und als at_cell im Receipt festgehalten; Normalisierung auf AT erst beim Vergleich (Hash über 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; Zwei-Run-Abgleich byte-identisch für deterministische Bestandteile, nur Ausnahme-Cells at_cell/tree dürfen differieren (at-Varianz real demonstriert: getrennte Worktree-Läufe → verschiedene Wanduhr-at)
- Kanonisches Eingabemanifest konsumiert/validiert (abschnittsbewusste Extraktion sources:/output_visible_run_identity:, Baseline-Quellen-Existenz nach Input-Commit, HARD-FAIL bei fehlenden Keys) — nicht dekorativ
- Receipt um order:/decisions: erweitert (§5.14 Pkt. 2) + Receipt-Nicht-Vakuum-Guard
- Subshell set -e (jeder fehlende Schritt bricht rc≠0 ab → HARD-FAIL statt false-PASS)
- match_stufe_a literal-sicher (Term regex-escaped, §3.2-Pkt.-2a/§5.14 Pkt. 5) + CRLF-tolerante Body-Extraktion
- cand-Newline-Normalisierung (tr \n ,)
- log_bullet fail-hard (mktemp/mv-Fehler nicht geschluckt — verlorener log-Eintrag hätte Vakuum-Gleichheit durch identische Baseline-Hashes erzeugt)
- git worktree prune vor dem Add (Re-Run-Sicherheit); git clean fail-hard unter set -e

Verifikation re-executiert: run-sandbox.sh → DET-1..DET-8 harte PASS, Exit 0; at-Ausnahme aktiv (at_cell A != at_cell B), Witness nicht-vakuum; Validator-Verdikt (Rev 9, D-3): alle wiki/-Dateien SUCCESS (keine Inhalts-Mutation); Erhaltungs-Invariante §5.9 Pkt. 5 gewahrt (nur wiki/log.md); AD-3 read-only unverändert.

Spec: Change Log Review-Loop-2 (10 Patches), Verification-Pkt.-1 auf gehärteten Stand aktualisiert, Suggested Review Order auf neue Sandbox-Anker (238/257/267/409/414/498); Frontmatter status in-review → done. wiki/log.md Review-Loop-2-Abschluss-Bullet (zuerst-neuestes). sprint-status.yaml 3-8-… → review; last_updated 17:05.

Co-Authored-By: Claude <noreply@anthropic.com>
@
2026-08-20 14:00:53 +02:00
Michael TamseandClaude 96661836e9 feat: Story 3.8 Re-Open-Delta — Zwei-Run-Determinismus auf getrennte Worktrees/Manifest/Receipt umgestellt (genehmigtes Sprint-Change-Proposal 2026-08-20)
Re-Open-Scope (approved, ProMods; Epics-ACs Z. 357-370): zwei frische Agent-Kontexte in getrennt aufgebauten (sauberen) Worktrees (Q-6/A0-19 — eine zweite Ausführung in derselben Session genügt nicht), kanonisches Eingabemanifest (Baseline-Commit, geordnete Sources, output-sichtbare Run-/Zeit-/Identitätswerte), Run-Receipt außerhalb des Bundles (Candidates, Reihenfolge, Plan, Entscheidungen, Output-Hashes), keine hart codierten erwarteten Pläne/Concept-Bodies, keine pauschale verified-Maskierung (nur benannte at-Ausnahme).

- schema/compiler.md §5.14: Zwei-Run-Bestätigungs-Mechanik + §8-Revision-3.3-Klausel + Re-Open-Delta auf getrennte Worktrees/Manifest/Receipt/no-hardcode/no-masking umgestellt; §5.13-"in einer Session" unverändert (AD-6-Phasen-Disziplin, Fugen-Identität)
- sandbox-3-8/run-sandbox.sh: DET-2 auf zwei getrennte Worktrees (wt-a/wt-b) + manifest.yaml + receipts/-Dateien außerhalb des Bundles umgebaut; Candidate-Ableitung aus Git-State via deterministischem Stufe-a-Match (nicht hart codiert); Receipt-Abgleich als tatsächlicher Zwei-Run-Vergleich (diff der beiden Receipts, nicht je Lauf gg. Baseline); non-vakuum-Witness (Run-alpha-SHA != Baseline-alpha-SHA); Subshell für Worktree-cwd-Isolation. Exit 0, DET-1..DET-8 harte PASS
- spec-3-8: Re-Open-Delta-Intent, Tasks & AC-3/4/5, SRO auf Worktrees angepasst
- wiki/log.md: Story-3.8-Re-Open-Delta-Eintrag (Verankerung, Sandbox-Nachweis Exit 0, Erhaltungs-Invariante, Validator-Verdikt 7/7 SUCCESS, Revision 3.3)
- sprint-status.yaml: last_updated nachgeführt; Key 3-8 in-progress
- epic-3-context.md: neu kompiliert (Story-Liste/Stories 3.9-3.13 synchron)

Validator-Verdikt (human-mechanisch, schema/validator.md Rev 9, D-3 — kein CLI): alle wiki/-Dateien 7/7 SUCCESS (keine Inhalts-Mutation). Erhaltungs-Invariante §5.9 Pkt. 5: git status --porcelain -- wiki/ zeigt ausschließlich wiki/log.md. AD-3 read-only (validator/wiki-compiler/adapters/raw/canonical-terms) unverändert.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-20 13:08:28 +02:00
10 changed files with 1764 additions and 113 deletions
@@ -544,3 +544,17 @@ Noch nicht adressierte, aber real erkannte Arbeit — gesammelt aus Reviews. Ein
- 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 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. Relevanz und Reconcile-Routing sind textual-deterministisch ohne Embedding- oder Vector-Infrastruktur. Konkurrierende Producer koordinieren sich über eine atomare, worktree-übergreifende 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. 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-f/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/dh, A0-6/7/1216/18/19).
## Stories
@@ -15,7 +15,7 @@ Der Compiler verarbeitet neues Source Material gegen das bestehende Knowledge Bu
- Story 3.5: Leasing & Dirty-Tree-Schutz für konkurrierende Producer umsetzen
- 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 (wieder geöffnet)
- 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
@@ -24,33 +24,31 @@ Der Compiler verarbeitet neues Source Material gegen das bestehende Knowledge Bu
## 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 oder ungeprüftes Wissen wird ohne künstliche Gewissheit dargestellt; klassifikationspflichtige Widersprüche werden bis Epic 4 unverändert in einem strukturierten Hold erhalten (NFR-7).
- Relevanzbestimmung, Routing, Planung und nicht-konfligierende Mutationen 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 Relevanz und Reconcile-Routing (A0-18):** Ein geschlossenes Term-Ziehverfahren beziehungsweise ein explizites Term-Manifest, identische Normalisierung von Suchterm und Body sowie literal-sichere Suche führen zu einer nachvollziehbaren Candidate-Liste. Eine exklusive Routing-Tabelle unterscheidet `UPDATE`, `CREATE`, `ORPHAN/HOLD` und echten `NO_OP`; gleiches Eingabemanifest erzeugt dieselben Kandidaten und Entscheidungen.
- **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).
- **Atomare Root-Scope-Lease (AD-17a/b, A0-12/13):** Producer behalten `lease/<area>/<id>` als Branch-Konvention, akquirieren aber genau einen atomaren, scope-bezogenen Lock im clone-geteilten Zustand. Die Run-ID ist Lock-Inhalt, nicht Exklusivitätsschlüssel; unterschiedliche IDs und Worktrees konkurrieren um dieselbe Root-Scope (`wiki/` inklusive `log.md`, `index.md` und aller Root-Dateien).
- **Fail-closed Kollisionsgrenze:** 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, semantische Auflösung und Disagreement-Dokumentation sind Story 4.1/4.2 (AD-17c/g, A0-14/17).
- **Transaktionaler Dirty-Tree-/Rollback-/Release-Lifecycle (AD-6, AD-17d-f, A0-7/15/16):** Eine eindeutige Zustandsmaschine schützt getrackte und ungetrackte Fremdänderungen, restauriert bei FAIL explizit den Baseline-Commit und hinterlässt bei SUCCESS Mutation, zulässigen Nachweis, Lease-Freigabe und einen sauberen Worktree dauerhaft. Eine lebende Lease wird nicht allein durch Generationserhöhung stale.
- **Determinismus-Vertrag (AD-17h/FT-10, A0-19):** Ein kanonisches Eingabemanifest bindet Baseline, geordnete Sources und jeden output-sichtbaren Run-/Zeit-/Identitätswert. Zwei getrennte saubere Worktrees und frische Agent-Kontexte erzeugen denselben Bundle-State und rekonstruierbare Run-Receipts; hart codierte Pläne oder Concept-Bodies sind kein Nachweis.
- **Geteilte A0-21-Grenze:** Epic 3 beweist mit Story 3.10 den Incrementality-Teil — Erhaltung unabhängigen und weiterhin gültigen vorhandenen Wissens. Die spezifische Erhaltung und Konfliktbehandlung menschlicher Korrekturen (FT-9) bleibt bei Story 4.3.
- **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.
- **Epic-3-Abnahmegate:** Ein portables, fail-fast ausführbares Gate ruft den vollständigen autorisierten Bundle-Validator auf und lässt einen frischen Agent-Kontext die kanonische Instruktion `schema/compiler.md` über einer repräsentativen Fixture ausführen. Der Harness schreibt keine erwarteten Wiki-Ausgänge selbst. Ein unabhängiger Consumer-Smoke-Test prüft nur die Epic-5-Abhängigkeit und nimmt FR-15/FR-16 nicht vorweg. Ein Defizit des autorisierten Validator-Vertrags blockiert das Gate und verlangt eine separat genehmigte Epic-1-Remediation.
- **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-17df, 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.
- Story 3.9 liefert die deterministische Routing-Basis für Story 3.10. Parallel dazu liefert Story 3.11 die atomare Lease-Basis für Story 3.12.
- Story 3.8 wird nach 3.93.12 mit echten unabhängigen Runs abgeschlossen; Story 3.13 ist anschließend das finale Epic-Abnahmegate.
- AD-17c/A0-14 sind geteilt: Epic 3 verantwortet die No-Auto-Merge-/fail-closed-Sicherheitsgrenze, 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, Story 4.3 Human Curation/FT-9.
- 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.93.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.
@@ -7,10 +7,13 @@
# DET-1 BUNDLE_STATE_DEFINITION: ein Mini-Bundle erzeugen und die Bundle-State-
# Projektion deterministisch definieren/extrahieren (wiki/-Dateien + Plan-/
# Kandidaten-/Reihenfolge-Outputs; Extraktion zweimal -> identisch)
# DET-2 ZWEI_RUN_IDENTISCH (nicht-vakuum): zwei unabhängige Läufe über demselben
# committeten Baum -> identische Bundle-States bis auf at; die Assertion
# vergleicht echte Content-Hashes (nicht nur Vorhandensein); der Witness
# (wiki/alpha.md) weicht byte-weise von der Baseline ab (kein Vakuum)
# DET-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)
@@ -122,29 +125,46 @@ norm() { # $1 = Begriff (Kollaps-Form, NICHT registry-aufloesend — Kollaps-Sco
# 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)
body=$(awk 'BEGIN{n=0} /^---$/{n++; next} n>=2{print}' "$file")
# 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.
# Term-Normalisierung (§3.2 Pkt. 1b) ist lowercasing — der Match ist daher case-insensitiv.
if printf '%s' "$body" | grep -Eiq "(^|[^A-Za-z0-9])${term}([^A-Za-z0-9]|$)"; then
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)
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
' 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)
{ printf '%s\n' "$header"; printf '%s\n' "$line"; cat wiki/log.md; } > "$tmp" && mv "$tmp" wiki/log.md
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
}
@@ -220,22 +240,78 @@ echo "$B1" | sed 's/^/ /'
echo "RESULT: PASS — DET-1: BUNDLE_STATE_DEFINITION — Bundle-State = deterministische Projektion des committeten Git-States ((a) Baum gg. Baseline, (b) Kandidaten-, (c) Plan-/Reihenfolge-/Entscheidungs-Outputs); Extraktion zweimal byte-identisch (AD-17h/A0-19); keine eigene Engine (D-3/AD-11)"
# =====================================================================================
# DET-2 ZWEI_RUN_IDENTISCH (nicht-vakuum) — §5.14 Pkt. 2
# DET-2 ZWEI_RUN_IDENTISCH (nicht-vakuum, zwei getrennte Worktrees) — §5.14 Pkt. 2
# =====================================================================================
runlabel "DET-2: ZWEI_RUN_IDENTISCH (nicht-vakuum) — zwei unabhängige Läufe über demselben committeten Baum -> identische Bundle-States bis auf at; echte Content-Hashes (Witness weicht byte-weise von Baseline ab)"
run2() { # $1 = Run-Name ; führt die Instruktion über dem committeten Baum aus
isolate "$1"
cat > raw/alpha-v2.md <<'EOF'
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"
# Plan-/Kandidaten-Output (§5.14 Pkt. 2: identische Plan-/Kandidaten-/Reihenfolge-Outputs)
local plan
plan="cand=alpha;form=update;graphic=aktualisieren;baseline=$BASE"
# Mutations-Commit als ein commitierter Run-Ausgangszustand (unterschiedliches at je Run:
# A0-20-Konvention — der at-Wert ist Wanduhr, NICHT Teil des deterministischen Vergleichs)
cat > wiki/alpha.md <<'EOF'
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:
@@ -244,49 +320,126 @@ sources:
- resource: raw/alpha-v2.md
id: s3
generated:
by: wow-compiler/0.1.0
at: RUNAT
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
# at-Maskierung für den deterministischen Vergleich (§5.14 Pkt. 3): DET-2 demonstriert
# die Identität der NICHT-at-Bestandteile (Plan-, log-, index-, alpha-Content + TREE) —
# dafür wird die at-Zeile vor dem Hash auf ein festes Token normalisiert (die at-Varianz
# selbst ist die benannte Ausnahme, A0-20; ihre Behandlung demonstriert DET-4 positiv und
# negativ). Die Ausnahme ist dokumentiert, kein stiller Ausschluss; alle übrigen
# Bestandteile gehen byte-identisch in den Hash ein.
sed -i "s/^ at: .*/ at: AT/" wiki/alpha.md
log_bullet "- Determinismus-Bestätigung (Zwei-Run, §5.14 Pkt. 2): $plan; Baseline $BASE"
git add -A && git commit -qm "Run: alpha-Update ($1)"
# --- Bundle-State projizieren (deterministisch): echte Content-Hashes (nicht-vakuum) ---
echo "PLAN=$plan"
echo "SHA_ALPHA=$(git show 'HEAD:wiki/alpha.md' | sha256sum | cut -d' ' -f1)"
echo "ABS_BASELINE=$(git show "$BASE:wiki/alpha.md" | sha256sum | cut -d' ' -f1)"
echo "SHA_LOG=$(git show 'HEAD:wiki/log.md' | sha256sum | cut -d' ' -f1)"
echo "SHA_INDEX=$(git show 'HEAD:wiki/index.md' | sha256sum | cut -d' ' -f1)"
echo "TREE=$(git rev-parse 'HEAD:')"
# 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 (unabhängig) ---"
SA=$(run2 run2a)
echo "$SA"
echo "--- Lauf B (unabhängig, über demselben committeten Baum) ---"
SBV=$(run2 run2b)
echo "$SBV"
# Zwei unabhängige Läufe -> identische Bundle-States bis auf at
[ "$(echo "$SA" | grep '^PLAN=')" = "$(echo "$SBV" | grep '^PLAN=')" ] || { echo "HARD-FAIL (DET-2): Plan-/Kandidaten-Outputs weichen ab (AD-17h/A0-19, §5.14 Pkt. 2)" >&2; exit 1; }
[ "$(echo "$SA" | grep '^SHA_ALPHA=')" = "$(echo "$SBV" | grep '^SHA_ALPHA=')" ] || { echo "HARD-FAIL (DET-2): alpha-content-Hash weicht zwischen Runs ab (Byte-Differenz ausserhalb at, §5.14 Pkt. 3)" >&2; exit 1; }
[ "$(echo "$SA" | grep '^SHA_LOG=')" = "$(echo "$SBV" | grep '^SHA_LOG=')" ] || { echo "HARD-FAIL (DET-2): log.md-Hash weicht ab" >&2; exit 1; }
[ "$(echo "$SA" | grep '^SHA_INDEX=')" = "$(echo "$SBV" | grep '^SHA_INDEX=')" ] || { echo "HARD-FAIL (DET-2): index.md-Hash weicht ab" >&2; exit 1; }
[ "$(echo "$SA" | grep '^TREE=')" = "$(echo "$SBV" | grep '^TREE=')" ] || { echo "HARD-FAIL (DET-2): Bundle-Baum nach at-Maskierung weicht ab (Soll: byte-identisch, §5.14 Pkt. 2)" >&2; exit 1; }
# Nicht-vakuum-Witness: der produzierte Content weicht byte-weise von der Baseline ab
ABS_A=$(echo "$SA" | grep '^ABS_BASELINE=' | cut -d= -f2)
SHA_A=$(echo "$SA" | grep '^SHA_ALPHA=' | cut -d= -f2)
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 "RESULT: PASS — DET-2: ZWEI_RUN_IDENTISCH — zwei unabhängige Läufe über demselben committeten Baum produzieren identische Bundle-States (Plan-, log-, index-, alpha-Content-Hashes und Bundle-TREE byte-identisch, jeweils bis auf die benannte at-Ausnahme, die für den Vergleich maskiert ist); Vergleich nicht-vakuum (Witness vs. Baseline, echte Content-Hashes, §5.14 Pkt. 2, FT-10/AD-17h AC-1)"
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)
File diff suppressed because it is too large Load Diff
@@ -2,9 +2,9 @@
title: 'Story 3.8 — Determinismus-Vertrag (AD-17h) als Agent-Instruktions-Validator umsetzen'
type: 'feature'
created: '2026-08-20'
status: 'in-progress'
status: 'done'
baseline_commit: 'c4cdf4b93e17b3f84dff03a4bd5608251be56268'
review_loop_iteration: 0
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'
@@ -12,11 +12,22 @@ context:
<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. 357370):
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. 357370) 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 (Vergleichs-Operandum = committeter Baum; identische Plan-/Kandidaten-/Reihenfolge-Outputs; kein neuer Prozess/Server/MCP, D-3), (3) die **Ausnahme-Menge** des Bundle-State-Vergleichs (der `generated.at`-Wanduhr-Gap als dokumentierte A0-20-Konvention; sonst byte-identisch) und (4) die **Abweichungs-Klassifikation** (jede Abweichung außerhalb der Ausnahme = AD-16-Klassifikationsdefekt, textuell benannt, NFR-4). Die Zwei-Run-Bestätigung wird als **Sandbox-Szenario** mechanisch demonstriert; die bekannten Lücken (Em-Dash, Kollaps-Reichweite, Match-Scope, Orphan) werden als **geschlossene, deterministische Regeln** in die Instruktion gehoben — keine offenen Fragen verbleiben, die die Zwei-Run-Identität gefährden.
**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
@@ -26,7 +37,7 @@ context:
- Der `generated.at`-Wanduhr-Gap **bleibt als dokumentierte Ausnahme** bestehen (A0-20-Konvention, §5.9 Pkt. 2, §5.10 Pkt. 8, unverändert bindend bis Ask-First-Wechsel). §5.14 **definiert** die Behandlung von `at` im Bundle-State-Vergleich (Ausnahmemenge), ändert aber **nicht** das `generated.at`-Verhalten selbst.
- Bei einer Abweichung zweier Runs: die Abweichung **ist** ein AD-16-Klassifikationsfehler (kein akzeptables Rauschen, FT-10/AD-17h-AC); die textuelle Benennung (NFR-4) ist verpflichtend.
- Die **normalisierenden Lücken-Schließungen** (Em-Dash in der Kollaps-Klasse, Kollaps-Reichweite bei Läufen/führenden/trailenden Separatoren, Wortgrenzen-/Frontmatter-Scope der Stufe-a-Erhebung) werden als **deterministische Regel-Ergänzungen** in §3.2 umgesetzt — **append-only/kein Umbruch** des bestehenden §3.2-Wortlauts; die Orphan-Politik (§5.10 Pkt. 8) wird zu einer deterministischen Reconcile-Orphan-Regel präzisiert.
- Die Bestätigung ist **agent-instruction-basiert (D-3, Q-6)**: ein Agent führt die Instruktion aus und bestätigt in einer Session die Zwei-Run-Identität — kein dedizierter Validator-Prozess, keine extra Runtime.
- 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.
@@ -52,7 +63,7 @@ context:
## 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. 364381 ca.); §0-Phasen-Listentext **unverändert**; §5.13 Pkt. 7 „Home Story 3.8" — wird auf §5.14-**Anker** umgehängt (die `generated.at`-Gap-Ausnahme ist jetzt in §5.14 definiert statt nur deklariert; Home-Verweis bleibt, wird aber auf die §5.14-Definition verlagert); §3.2 Normalisierungs-Lücken (Em-Dash in Kollaps-Klasse Z. 51; Kollaps-Reichweite; Match-Scope Z. 55) — als Regel-Ergänzungen aufgelöst; §5.10 Pkt. 8 Orphan-Politik Z. 301 — zur deterministischen Reconcile-Orphan-Regel präzisiert; §7 (`Z. 409ff.`) Determinismus-Vorbehalt „Em-Dash-Lücke an Story 3.8 übergeben" — **aufgelöst**, Verankerung in §5.14 benannt; §8-Normreferenz `AD-17h` (`Z. 430`) auf **§5.14-Anker** angehoben (mit der `at`-Ausnahme-Nennung); Revisionslog-Eintrag **Revision 3.3** nach Z. 461. Anker (IST-Zeilen nach Implementierung): §5.14-Sektion Z. 364; §7-Determinismus-Bullet nach Z. 420; §8-AD-17h in Z. 430; Revisionslog **Revision 3.3** nach Z. 461.
- `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. 365377); §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. 15 = 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).
@@ -70,11 +81,15 @@ context:
- [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 die Determinismus-Enforcement fehlt, then lebt sie als Agent-Instruktions-Validator (§5.14) und ist als mechanisch durch die Sandbox bestätigt (Q-6, A0-19; AC-3).
- Given der 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
@@ -100,15 +115,98 @@ context:
**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. 357370): 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.93.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. 364381 ca." → 365377, „§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. 6167, 9495, 101, 262263, 321329, 357408) 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.93.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. 364381"→365377 (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; der Produzent führt die Instruktion zweimal über demselben committeten Git-State aus und vergleicht die Bundle-States; re-executierbare Formeln), (c) **Ausnahme-Menge** (allein `generated.at`-Wanduhr-Gap, dokumentiertes A0-20; Nichts sonst), (d) **Abweichungs-Klassifikation** (jede Differenz außerhalb der Ausnahme = AD-16-Klassifikationsfehler; textuell benannt NFR-4; kein stiller Vorbeilass). Damit ist die bisher „offen verankerte" AD-17h-Eigenschaft (viele Rückverweise, kein normativer Ort der Bestätigung) zu einem **instruierten, mechanisch bestätigbaren Verfahren** verdichtet.
**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 unabhängige Läufe über demselben committeten Baum → identische Bundle-States bis auf `at`; die Assertion vergleicht echte Content-Hashes (nicht nur Vorhandensein)
- 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
@@ -121,13 +219,13 @@ context:
## Verification
**Commands (re-executierbar, ab Workspace-Root):**
1. `bash _bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh` — expected: DET-1..DET-8 harte PASS/Fail, Zwei-Run-Identität nicht-vakuum, Exit 0.
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.
**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
@@ -138,9 +236,9 @@ context:
- [compiler.md:365](../../schema/compiler.md#L365) — §5.14-Überschrift, Intro mit §5.13-Seam und AD-3-Schutzliste inkl. `adapters/`.
- [compiler.md:369](../../schema/compiler.md#L369) — Pkt. 1 Bundle-State-Definition: committete Baum-Projektion, `generated.at` als benannte Ausnahme (A0-20), FT-10/AD-17h/AC-1.
- [compiler.md:370](../../schema/compiler.md#L370) — Pkt. 2 Zwei-Run-Bestätigungs-Mechanik: zweimal über denselben committeten Git-State, Run-A↔Run-B-Abgleich (Beispiel `git diff`), keine Wanduhr-Steuerung.
- [compiler.md:374](../../schema/compiler.md#L374) — Pkt. 3 Ausnahme-Menge: allein der `generated.at`-Wanduhr-Gap; alle übrigen Bestandteile byte-identisch (kein stiller Ausschluss).
- [compiler.md:375](../../schema/compiler.md#L375) — Pkt. 4 Abweichungs-Klassifikation: jede Differenz außerhalb der Ausnahme = AD-16-Klassifikationsdefekt, kein Rauschen (NFR-4, Zustands-Restaurations-Invariante).
- [compiler.md:376](../../schema/compiler.md#L376) — Pkt. 5 Normalisierungs-/Match-/Orphan-Schließung: Verankerung auf §3.2-Pkt.-1b / §5.10-Pkt.-8, Erhebungen vollständig pinbar.
- [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)**
@@ -150,14 +248,20 @@ context:
**§7/§8-Nachweis**
- [compiler.md:476](../../schema/compiler.md#L476) — Revisionslog Revision 3.3: §5.14-Verankerung, §7-Determinismus-Vorbehalt aufgelöst, §8-AD-17h-Normreferenz auf §5.14-Anker, Abschlussklausel (AD-3/D-3/keine neue §7-Klasse).
- [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:152](../../_bmad-output/implementation-artifacts/sandbox-3-8/run-sandbox.sh#L152) — DET-1..DET-8-Szenarien (Bundle-State, Zwei-Run-identisch nicht-vakuum, Zwei-Run-Abweichung, `at`-Gap, Em-Dash, Kollaps, Match-Scope, Orphan); Läufe Exit 0 mit 8 harten PASS-Assertionen.
- [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.
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 12:18
last_updated: 08-21-2026 10:16
project: wow20
project_key: NOKEY
tracking_system: file-system
@@ -58,8 +58,8 @@ 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: in-progress
3-9-deterministische-relevanz-und-reconcile-routing-schliessen: 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.93.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
+1 -1
View File
@@ -363,7 +363,7 @@ So dass Relevanz-, Routing-, Planungs- und Mutationsentscheidungen reproduzierba
**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 Determinismusfehler behandelt und der Run gilt als fehlgeschlagen — nicht als akzeptables Rauschen (AD-17h).
**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.
+37 -12
View File
File diff suppressed because one or more lines are too long
+6
View File
File diff suppressed because one or more lines are too long