--- epic: 3 date: 2026-08-24 verdict: accepted-with-open-items criteria: declared headless: false --- # Retrospective Epic 3 — Inkrementelle Kompilation & Synthese ## Epic summary - **Epic:** 3 — Inkrementelle Kompilation & Synthese - **Diff-Range:** `efc543c^..3f57586` (erster Story-Commit `efc543c` (Story 3.1), letzter `3f57586` (3.13 done-Flip); 44 Commits, 1 Merge `5a78271` (gemessen, erst-parent-diff)) - **Commits/Churn (nicht-Merge):** 43 nicht-Merge-Commits; Top-Dateien: `sandbox-3-13/run-sandbox.sh` (+1716/−711, 11 Commits), `schema/compiler.md` (+318/−87, 21 Commits), `deferred-work.md` (+386/−14, 23), `spec-3-13` (+265/−27), `sprint-status.yaml` (28 Commits), `wiki/log.md` (+49/−4) - **Stories:** 3.1–3.13 alle `done`; `pending_stories` leer (`detect-epic --epic 3`, 2026-08-24) → kein Machine-Zwang zu `rejected`. `epic-3-retrospective`: optional → Phase 5 auf `done`. - **Abnahmekriterien:** deklariert in `_bmad-output/planning-artifacts/epics.md` (Epic-3-Block Z. 259–451 + je Story-AC-Zeilen) → Verdikt-Basis **declared**. - **Evidence-Inventar:** - Epic-Spec: `planning-artifacts/epics.md` (Epic-3-Block, ACs je Story deklariert) - Story-Specs 3.1–3.13 unter `_bmad-output/implementation-artifacts/spec-3-*.md` (13 Dateien) - `epic-3-context.md` (kontextuell kompiliert, mit Ist-Zustand je AD) - `schema/compiler.md` (548 Z. nach Epic 3; +318/−87 net über 21 Commits) — das Hauptlieferprodukt - `schema/canonical-terms.md` (+40/−1, Story 3.2) - Sandbox-Suiten: `sandbox-3-1` … `sandbox-3-13` (je `run-sandbox.sh`; 3-13 gehärtet 1005 Z.) - `deferred-work.md` (673 Z.; +386/−14, 23 Commits — append-only Register) - `sprint-status.yaml` (28 Commits im Range) - `wiki/log.md` (78 Z. nach Epic 3; +49/−4) - Voriges Retro: `epic-2-retro-2026-08-18.md` (verdict accepted-with-open-items, Action-Items AI-2-R-1…5) - `sprint-change-proposal-2026-08-20.md` (genehmigte Story-3.8-Re-Öffnung) - Merge-Eckung: `merge_files` für `5a78271` (Story 3.8-PR-Merge) enthält teils Epic-2-Restchurn (z. B. `epic-2-retro`, `spec-2-5`, `validator.md` Rev-9) — wird im Aggregat NICHT zu `files` addiert, nur als Kontext notiert. - **Fehlend:** Session-Logs (nicht in dieser Umgebung verfügbar) → Prozess-Lektionen nur aus git-loggablem Verhalten; `project-context.md` existiert nicht (persistent fact `file:**/project-context.md` leer). - **Prozess-Hinweis (für Phase 2):** Story 3.13 durchlief ≥ 6 dokumentierte Re-Runs (Erst-Lauf 2026-08-22 grün → Härtung Review-Loop-1 → Re-Runs #2–#5, #5 rot an E.4 = echter AD-16-Befund → Rev-3.8-Epic-1-Remediation → Re-Runs #6–#10, #10 grün) und 2 Review-Loops (38 rohe Findings im Loop-2). Commit-Log zeigt die Kette vollständig. ## Findings Jeder Befund trägt eine Quellen-Referenz (Datei:Zeile / Commit / Log). Befunde ohne belegbare Quelle wurden verworfen. ### F-1 — Sandbox-Helfer-Duplikation ist *by design*, aber das semantische Primitive `norm()` ist zwischen 4 Suiten bereits in zwei Strukturanvarianten divergiert **Quellen:** `sandbox-3-{8,9,10,11}/run-sandbox.sh` (`norm()`-Definitionen); `deferred-work.md` L552 (D-7), L559 (W-3.9-1), L572–573 (3.10-Kopie). **Was kein einzelner Diff zeigt (Aggregate-View):** Die Suite-Helfer-Duplikation selbst ist gewollt — jede Sandbox ist selbstenthalten und in einem frischen `/tmp`-Bundle re-exekutierbar (12/12 Suites liefen unabhängig grün, s. Behavior). Die Duplikation ist also kein God-Class-Defekt. *Aber* beim einen Helfer, der eine **normative Semantik** trägt — `norm()` = die §3.2/§5.14-Kanon-Form, auf die AD-13/AD-17h (textueller Determinismus) aufbauen — hat sich über die 4 Suiten, die ihn definieren (3-8, 3-9, 3-10, 3-11), eine **strukturelle Divergenz** entwickelt: - **3-8, 3-9, 3-10** (3 identische Kollaps-Formen): `sed`-Kollaps `[-–—_ ]→-` **plus** Case-Folding (`tr 'A-Z' 'a-z'` bzw. `tolower`). - **3-11** (divergent): `sed`-Kollaps `[–—]→-`, `_→␣`, `␣→-` **ohne jeden Case-Folding-Schritt**. Die Divergenz ist im Moment **maschiert**: 3-11s einziger Aufruf (Z. 382) liegt neben redundanten Schwesterglobs (`*run-a5*`, `*a5*`), die den fehlenden Fall-Abgleich überdecken. Sie ist aber eine Latenz, kein Zufallsartefakt — und sie trifft genau das Primitive, das Epic 3 als deterministisch verkauft. **Relation zu bekanntem Deferral:** `deferred-work.md` L552/559/572 dokumentiert bereits, dass `norm()` **keine `LC_ALL`-Pinning** trägt (D-7, Home: Sandbox-Härtung). Das Retro erweitert diesen Befund: (a) 3-11 ist zusätzlich die **einzige Suite mit `LC_ALL=0`** (kein Locale-Pin überhaupt), und (b) die Kopien haben sich **bereits** divergiert — eine künftige Vereinheitlichung muss daher erst 4 driftete Implementierungen *reconcilieren*, nicht nur einen Pin ergänzen. **Stufe:** Latenz/Robustheit (keine gegenwärtige Fehlfunktion, alle Suites grün), aber normativ relevant für AD-13. ### F-2 — `compiler.md` ist das einzige Hauptlieferprodukt und wuchs zu einer 548-Zeilen-/15-Sektionen-Datei (God-File-Risiko, aber strukturell sauber) **Quellen:** `schema/compiler.md` (`wc -l` = 548; `grep -nE '^## 5\.'`); git-churn `+318/−87` über 21 Commits (s. Epic summary). **Was kein einzelner Diff zeigt:** Epic 3 legte `## 5.9`–`## 5.18` an (Z. 257–440 ≈ 183 neue Zeilen) — die Sektionen-Blase von §5 wuchs von 5 auf 15. Die Datei ist das einzige normative Hauptartefakt des ganzen Projekts; jede Epic-3-Story mutiert *denselben* Datei-Block, was den §5-Bereich zum natürlichen Konfliktherd macht (tatsächlich: 21 Commits an einer Datei, der churn-höchste Wert des Epics nach der Sandbox). **Aber** die Struktur ist sauber: lineare Nummerierung, je Sektion ein Story-Verweis, kein Code-Verschnitt. Das Risiko ist **Wartbarkeit/Review-Fläche**, nicht inkohärenter Zustand — die Sandbox-Suiten und der §6-Validator decken die Semantik mechanisch ab. **Stufe:** Beobachtung (Wachstums-Trend), kein Defekt. ### F-3 — §5-Sektions-Nummerierung ist nicht zusammenhängend (Kosmetik, aber verwirrend) **Quellen:** `schema/compiler.md` `grep -nE '^## 5\.'` — vorhanden: 5.5, 5.6, 5.7, 5.8, 5.9, 5.10, 5.11 … 5.18. **Befund:** `## 5.1`–`## 5.4` existieren nicht (der Block beginnt bei 5.5), und die Nummerierung folgt **Story-Nummern, nicht logischer Reihenfolge**: `5.10` = Story 3.4, `5.11` = Story 3.5, `5.17` = Story 3.11. Das ist konsistent *innerhalb* der Story-Mapping-Konvention, aber ein Leser, der nach „§5.10 = zehnter Unterabschnitt" sucht, wird irregeleitet. **Stufe:** Kosmetik/Lesbarkeit; kein semantischer Defekt. (Kein fix-now; optional für eine spätere Instruktions-Revision.) ### F-4 — Verhalten: A==B-Determinismus-Assertion wird **nicht-vakuum** ausgeübt (positiver Befund, bestätigt AD-17h) **Quellen:** `sandbox-3-10/run-sandbox.sh` E-9 (Re-Exekution dieser Retro, `Exit 0`): `„Zwei-Run-Identitaet (gleicher Eingang -> identische Bytes); at-Wanduhr-Gap-Exzeption real ausgeuebt (nur generated.at differiert); Nicht-Vakuum bei Zustandswechsel"`, `PASS=9 FAIL=0`. **Befund (Bestätigung, kein Defekt):** Die Determinismus-Vertrags-Assertion, auf der Story 3.8/AD-17h stehen, ist in der Sandbox **real** und **nicht tautologisch** — sie erzwingt echte Byte-Äquivalenz (nur das erlaubte `generated.at`-Feld differiert) und übt den Zustandswechsel-Nicht-Vakuum-Fall aus. Das ist die einzige Stelle im Epic, an der die „A==B" -Kernaussage mechanisch verifiziert wird, und sie hält. Dies schützt das Epic gegen die häufigste Falsch-Grün-Mode bei Determinismus-ACs (leere/triviale A==B). **Abgrenzung zu F-10:** F-4 bestätigt die **mechanische** Assertion (Sandbox, deterministisch); **F-10** zeigt, dass die **frische-LLM-Ausführung** derselben A==B-Prämisse über reale Agent-Kontexte empirisch nicht robust ist (Lauf A no-op). Beide gelten gleichzeitig — der Kern-Mechanismus ist grün, die Ausführung ist es nicht. ### Befunde aus der Diff-scope-Review (bmad-review über `efc543c^..3f57586`) **Methode/Abgrenzung:** Adversarial- und Verification-Gap-Linsen lieferten 22 bzw. 2 rohe Befunde; Edge-Case-Hunter **stallte ohne Output** (600s-Watchdog) — die Coverage-Lücke wird hier notiert, nicht aufgefüllt. Jeder Befund unten wurde in dieser Retro **unabhängig gegen die Quelle verifiziert** (Zeilengleichung, nicht nur Agent-Wiedergabe). Konsolidierung: VG#1 = Adversarial#1 (gleicher Befund, zwei Linsen); VG#2 ist eigenständig. Die übrigen Adversarial-Befunde (Leasing-Cluster, CREATE-Coverage, Em-Dash) sind eigenständig. Reihenfolge nach Materialität für die Determinismus-/Sicherheits-Ansprüche des Epics. #### F-5 — MIDNIGHT-Dateigruppen-Bruch: der Kern-Determinismus-AC ist am Tagesgrenze nicht erfüllbar (Spec-Selbstwiderspruch + unbelegte Verifikation) [HÖCHSTE MATERIALITÄT] **Quellen (alle in dieser Retro verifiziert):** `schema/compiler.md:277` (§5.9 Pkt. 4) + `:375` (§5.14 Pkt. 3) + `:548`; `sandbox-3-13/run-sandbox.sh:650-653` (`classify_diff`) + `:819-828` (E.9); `schema/validator.md:135-137` (F17). **Befund:** Der §5.14-Zwei-Run-Vertrag ist der **Kern-AC** des Epics (AD-17h, FT-10, AC-1/AC-6). Er erlaubt in `§5.14 Pkt. 3` **genau eine** benannte Differenz — den `generated.at`-Wanduhr-Gap — und erklärt die Ausnahme "ausschließlich auf den `at`-Feld-Wert" bezogen, "alle übrigen Bestandteile … **byte-identisch**". **Aber** `§5.9 Pkt. 4` (Z. 277) verlangt den `log.md`-Eintrag in kanonischer Form mit einer `## YYYY-MM-DD`-Datumsgruppen-Header (neueste zuerst) — und behauptet **gleichzeitig**, der Eintrag trage "keinen Wanduhr-Wert … der Wanduhr-Wert lebt **ausschließlich** im Frontmatter-`generated.at`, **nie im `log.md`-Body**". Die `## YYYY-MM-DD`-Header ist aber **ein Wanduhr-Datum im Body** — weder `generated.at` noch an einen Git-Wert gebunden (es existiert **nirgends** eine `git show --format=%cs/%cd`-Bindung für die Header, verifiziert). Damit ist die Ausnahme-Menge "genau eine" vom §5.9-Wortlaut selbst **widersprochen**, und `classify_diff` (Z. 650-653) maskiert **nur** die ` at: ` -Frontmatter-Zeilen — eine `+`/`-`-Änderung der `## YYYY-MM-DD`-Header zählt als **NON_AT** → **spurious HARD-FAIL** für einen konformen Lauf, der die Mitternacht-/Timezone-Grenze zwischen Run A und Run B überschreitet. E.9 (Z. 819-828) prüft nur "Lauf-Eintrag vorhanden + trägt `Baseline $BASE`" — **nirgends** wird beansprucht, dass beide Läufe in die *gleiche* Datumsgruppe fallen. Validator-F17 validiert die Datumsgruppe explizit **nicht** (v1). **Heute grün** nur, weil beide Agent-Läufe in derselben Session am selben Tag laufen (Re-Run #10, 2026-08-24). **Bereits im ausgelieferten Artefakt vorhanden (nicht nur latenz):** `wiki/log.md` trägt **10** `## YYYY-MM-DD`-Wallclock-Header (`2026-08-24` … `2026-08-15`, in dieser Retro gezählt) — der §5.9-Pkt.-4-Header ist also in der realen Auslieferung **geübt**; zwei gleich-tägige Läufe sind byte-identisch (Gate grün), aber der Kern-Anspruch "genau eine Ausnahme" ist vom §5.9-Wortlaut selbst widersprochen. **Cross-Suite-Beweis der Inkonsistenz (VG-Linsenzusatz):** die Suite umgeht den Gap **inkonsistent** — 3-10 (Z. 303/605) nutzt reale `$(date +%Y-%m-%d)` (die einzige Suite, die die Wanduhr-Abhängigkeit real ausübt), während 3-1/3-5/3-6/3-8/3-9/3-12 fixe Tage hartkodieren und 3-9 R-8 die Header weglässt. Kein Test übt jemals einen echten Header-Unterschied zwischen zwei Läufen aus. **Stufe:** **Defekt** (Kern-AC nicht am Tagesgrenze erfüllbar; Spec-Selbstwiderspruch). Fix-Optionen (Vorschlag, nicht auto-applied): (a) die `## `-Header-Zeile in `classify_diff` als benannte Ausnahme wie `at`-Zeilen klassifizieren, **oder** (b) die Header auf einen Git-Wert pinnen (`git show -s --format=%cs $BASE`), sodass "identische Datumsgruppe" (§5.9/§5.14) verifizierbar statt ungetestet ist; **und** §5.9-Z.277-Wortlaut ("keinen Wanduhr-Wert … nie im Body") mit der Header-Realität in Einklang bringen. #### F-6 — Unreconciliertes Leasing-Cluster: drei Lock-Modelle koexistieren; §5.18 invertiert §5.12s Gen-only-Stale-Regel ohne Supersession-Notiz **Quellen (verifiziert):** `schema/compiler.md:327` (§5.12 Pkt. 1), `:419` (§5.17 Pkt. 1), `:428`/`:430` (§5.18 Pkt. 0/Pkt. 1), `:419-424` (§5.17 Pkt. 2). **Befund:** Drei Lock-Modelle stehen nebeneinander, ohne dass ein sie eindeutig ersetzt: **§5.11** (worktree-lokales Lockfile, **nicht-atomares** check-then-act, TOCTOU), **§5.17** (atomare create-only-Root-Scope-Ref `git update-ref $ZERO_SHA`), **§5.18** (Lifecycle/Übernahme). `§5.17` (Z. 417/419) demotiert das §5.11-Lockfile explizit ("trägt aber **keine Exklusivität mehr allein** … TOCTOU-Race … geschlossen"). **Aber** `§5.12 Pkt. 1` (Z. 327) definiert Staleness **allein** generationen-basiert ("Gen kleiner = älter … gilt als **stale** … blockiert keinen nachfolgenden Run"), während `§5.18 Pkt. 1` (Z. 430) dies **invertiert**: eine lebende Lease ist "durch eine höhere sichtbare Generation **allein nicht stale** … **nie allein aus der Gen-Registry** (§5.12), sondern aus **bestätigtem Abbruch oder abgelaufener Liveness**". `§5.18` (Z. 428) beansprucht zugleich "Fugen-Identität: §5.12 (Pkt. 1–7) … bleiben **textuell unverändert**" — die **behaviorale** Supersession hat also **keine** Supersession-Notiz, und §5.12s "TTL-Ablauf-Äquivalent"-Wortlaut bleibt wörtlich intakt (leserisch widersprüchlich). Zusätzlich: der **Area-Scope**-Pfad behält das nicht-atomare §5.11-TOCTOU-Modell (nur der Root-Scope bekommt §5.17). **Stufe:** **Defekt** (inkohärentes Sicherheitsmodell; zwei widersprüchliche Staleness-Regeln ohne Supersession). Fix-Option: §5.12 Pkt. 1 um eine Supersession-Notiz zu §5.18 ergänzen (bzw. §5.18 als normative Staleness-Autorität kennzeichnen) + die Root-vs.-Area-Asymmetrie explizit machen. #### F-7 — Leasing wird von **keinem realen Agent-Lauf** ausgeübt: das Gate (3-13) hat **null** Leasing-Verifikation (missing-adoption) **Quellen (verifiziert):** `sandbox-3-13/run-sandbox.sh` — `grep -cE 'update-ref|refs/leases|scopelock|\.lock|lease/|root-scope'` = **0** (in dieser Retro ausgeführt); AGENT_PROMPT (Z. 567-582) verlangt nur `wiki/`-Mutationen + 4-Feld-Receipt, **kein** Lease-Lock-Wert, **keinen** Shared-Ref-Namespace-Check; `sandbox-3-11` (eigene `scopelock_acquire`-Helfer, Z. 124-129), `sandbox-3-12` (`scopelock_`-Helfer, L-2 CAS Z. 367-434), `sandbox-3-5` (check-then-act `acquire()` Z. 206 — verifiziert das **demotierte** Modell). **Befund:** Die §5.17-atomare Root-Scope-Akquise ist der eigentliche Sicherheitsgewinn des Leasing-Clusters (schließt das TOCTOU-Race). Sie wird aber **nur** von Sandbox-internen Bash-Helfern (3-11/3-12) bewiesen — **kein** realer Agent-Kontext führt sie aus. Das Abnahmegate 3-13, das die realen Agent-Läufe (E.1-E.9) enthält, referenziert **nirgends** `update-ref`/`refs/leases`/`scopelock`/`.lock` (0 Treffer) — seine Agent-Läufe mutieren ausschließlich `wiki/`. Fehlt also in der realen Ausführung der §5.17-Pfad, **schweift** das supersedierte check-then-act-TOCTOU-Modell (§5.11) zurück, ohne dass ein roter Test es auffängt: 3-11 A-2 beweist nur die Atomarität des Git-Ref-Primitivs **in seinem eigenen** Bash-Helfer, nicht, dass der Agent den §5.17-Pfad **annimmt** statt des §5.11-Lockfiles. **Stufe:** **Defekt** (Sicherheits-Invariante "genau ein aktiver Root-Scope-Holder" unverified im realen Execution-Pfad). Fix-Option: ein Gate-Szenario (analog E.9, mit Known-Value-Witness), das in wt-a verifiziert, dass `refs/leases/wiki` existiert **und** `git rev-parse 'refs/leases/wiki^{}'` == `git hash-object` des Run-IDs ist — d. h. der reale Agent hat die scope-bezogene Ref mit Run-ID-Inhalt im geteilten Ref-Namespace gesetzt. #### F-8 — Gate-Coverage-Gap: der reale Agent-A/B übt nur den UPDATE-Kern; CREATE/Synthese delegiert an agent-less Sub-Runs **Quellen (verifiziert):** `sandbox-3-13/run-sandbox.sh:23,56-59,477-480` (D-3.13-6 Option 2, Re-Run #5-Befund). **Befund:** Die einzige reale Agent-A/B (E.1-E.9, AC-6/AC-7) übt den **UPDATE-/Erhaltungs-Kern** (Zuwachs `raw/alpha-v2.md` = bestätigender UPDATE). Der **CREATE-/Synthese-Kern** ist **bewusst** nicht in der A/B-Fixture — aus gutem dokumentierten Grund (Z. 57: "CREATE-Fall 24/26 der NON_AT-Abweichungen treibend", Re-Run #5). CREATE/Synthese gelten stattdessen über die **agent-less** Sub-Runs 3-3/3-4. Das ist eine **bewusste** Scope-Entscheidung (D-3.13-6 Option 2), kein Still-Vorbeilass — **aber** es bedeutet, dass die CREATE-/Synthese-Determinismus-ACs (genau der Fall, der historisch die meisten NON_AT-Abweichungen trieb) **nur mechanisch, nie von einem realen Agent** verifiziert werden. Kombiniert mit F-5 (Dateigruppen-Bruch) und F-7 (kein realer Leasing-Lauf) ergibt sich ein Muster: die real-Agent-Abdeckung ist schmaler, als es die AD-17h-"zwei unabhängige Runs"-Kernclaim des Epics nahelegt. **Stufe:** **Befund/Scope-Decision** (dokumentiert, aber material für die Akzeptanz — die Determinismus-ACs hängen teils an mechanischen Surrogaten). Kein Fix-now; in das Verdict als offene Coverage-Frage einzureichen (s. Open questions). #### F-9 — Em-Dash-Kollaps-Klasse: Cross-File-Divergenz zwischen `canonical-terms.md` (ohne Em-Dash) und `compiler.md` (mit Em-Dash); append-only-Registry kann sich nicht selbst heilen **Quellen (verifiziert):** `schema/canonical-terms.md:18,21` (Kollaps-Klasse `[-–_ ]` — **ohne** Em-Dash) vs. `schema/compiler.md:51,54a` (`[-–— _]` — **mit** Em-Dash; "die Kollaps-Klasse ist um den Em-Dash `—` **ergänzt**", Story 3.8). **Befund:** `canonical-terms.md` ist die **committete, append-only** Registry des Schreibweisen-Resolvers (§3.2) und dokumentiert den Binde-Varianten-Kollaps als `[-–_ ]` (En-Dash, Bindestrich, Unterstrich, Leerzeichen — **kein** Em-Dash). Die Instruktion, auf die es sich normativ stützt (`compiler.md` §3.2 Pkt. 1b / §5.14 Pkt. 5, Story 3.8), erweitert die Kollaps-Klasse **um den Em-Dash `—`** (`[-–— _]`) und erklärt die Alt-Fassung für superseded. Weil `canonical-terms.md` **append-only** ist (bestehende Einträge "nie editiert") und die Leer-Registry-Format-Zeile (Z. 18/21) die ältere, Em-Dash-freie Klasse trägt, dokumentiert die Registry eine **schmalere** Kollaps-Klasse als die Instruktion — und kann sich (append-only-Regel) **nicht** selbst korrigieren. Ein Term mit Em-Dash (`wissen — relevanz`) wird von der Instruktion zur selben canonischen Form normalisiert wie seine En-Dash-Variante, aber die Registry-Dokumentation zeigt nicht, dass das so ist. **Stufe:** **Defekt** (normative Cross-File-Inkonsistenz; deterministisch, aber inkonsistent dokumentiert). Fix-Option: `canonical-terms.md`-Formatzeile um den Em-Dash ergänzen (append-only-konform als neue Format-Zeile / Korrekturnotiz) — erfordert eine autorisierte Instruktions-/Registry-Runde (kein stiller Edit, AD-3/D-3). #### F-10 — Live-Re-Exekution des Abnahmegates ist **ROT** am Kern-AC: ein frischer LLM-Agent no-op-ppte (silent non-execution); der Fail-Closed-Mechanismus hat die Divergenz korrekt erfasst [NEU, empirisch] **Quellen (in dieser Retro ausgeführt/verifiziert):** Live-Gate-Log `/tmp/epic3-gate-rerun-1787575069.log` — Z. 1234 (`$BASE=6150f943…`), Z. 1242 (`HEAD-A=6150f943…` = **identisch** zu `$BASE`), Z. 1240 („(a) keine Mutationen staged — kein Commit nötig" = **nur** bei wt-a), Z. 1248 (`A/B-Classifier: NON_AT=6 AT=2`), Z. 1249 (`HARD-FAIL (E.4)`); `GATE_EXIT=1` (Task-Output). Committed Gegenbeleg: `/tmp/gate-313-run10.log` Z. 1230 (`NON_AT=0 AT=2`), Z. 1275 (`FAILED=0 PASS_COUNT=51`), Z. 1277 (`SANDBOX-3-13-OK`). **Befund:** Die **unabhängige Live-Re-Exekution** des Abnahmegates 3-13 (zwei frische Agent-Kontexte A/B via `claude.exe -p --bare`; `CLAUDE_BIN` korrekt auf die echte `claude.exe` v2.1.198, **nicht** der winpty-Shim — s. Log-Z. 5) ist **ROT** an **E.4** (dem **Kern-Determinismus-AC**) — dem **Kern-Determinismus-AC** (AD-17h/FT-10, §5.14): `NON_AT=6 AT=2`, `HARD-FAIL`, `GATE_EXIT=1`. Die Ursache ist **weder F-5** (kein Midnight-/Datumsgruppen-Bruch: beide Läufe am selben Tag 2026-08-24, keine Tagesgrenze) **noch F-8** (kein CREATE-/Synthese-Subpfad — es ist der UPDATE-Kern). Die Ursache ist ein **frischer-LLM-Non-Execution-Fehlschlag**: **Lauf A hat gar keine Mutation ausgeführt** (`HEAD-A` == `$BASE`, „keine Mutationen staged") und **trotzdem** `RUN_DONE a` emittiert, während **Lauf B** den vollen UPDATE ausführte (sources-Zeile `raw/alpha-v2.md`, Body-Änderung, log.md `## 2026-08-24`-Eintrag mit `Baseline $BASE`). Alle 6 NON_AT-Zeilen liegen **einseitig** auf B — es ist **keine** A-gegen-B-Inhaltsdivergenz, sondern **A=leer vs. B=voll**. Entscheidend: **A und B liefen in derselben Umgebung, mit demselben Prompt, auf derselben Worktree-Baseline** — B lief korrekt, A no-op-ppte. Das ist **fresher-LLM-Non-Determinismus auf der Ausführungs-Ebene**: die AD-17h-Aussage „zwei frische Agent-Kontexte … produzieren byte-identische Bundle-States" gilt **nur, wenn beide Kontexte die Arbeit auch ausführen** — und das ist **nicht** garantiert. **Positiver Gegenbefund (Gate-Integrität):** der Fail-Closed-Mechanismus (E.4 `classify_diff` → `HARD-FAIL`, `exit 1`) hat die Divergenz **korrekt und prompt** erfasst — das Gate ist **nicht** grün-gewaschen; es tut, was §5.14/AD-17h verlangen. **Root-Cause offen:** das Sandbox-Root / `run-a.out`-Transkript des Live-Runs ist **nicht** erhalten (Root aufgeräumt, `find` ohne Treffer), daher **kann** die **warum**-Frage (Agent-„keine Änderung nötig"-Fehleinschätzung, `--bare`-Verhalten, Timeout, Kontext-Verlust) **nicht** abschließend beantwortet werden — der Befund steht auf der **beobachteten** Gate-Evidenz; die Root-Cause-Diagnose bleibt **offen**. **Stufe:** **Defekt (neuer, empirischer)** — der Kern-A/B-Determinismus-AC ist **empirisch nicht robust** über frische LLM-Runs (Committed-Grün ≠ Live-Grün); zusätzlich **Observability-Lücke** (kein erhaltener Agent-Transkript → nicht erklärbar). **Abgrenzung:** F-5 = *Spec-Selbstwiderspruch* der Ausnahme-Menge + ungetestete Tagesgrenze; F-8 = *delegierter* CREATE-Subpfad (agent-less). **F-10** ist **beides nicht**: es trifft den **tatsächlich vom Gate geübten UPDATE-Kern** an der **Ausführungs-Ebene** (Agent no-op) und ist **empirisch beobachtet**, nicht spekulativ. **Fix-Optionen (Vorschlag, nicht auto-applied):** (a) **Run-Vollständigkeits-Guard**: `RUN_DONE` nur, wenn ≥ 1 Mutation staged ist, sonst `RUN_ABORTED` — schließt die A-leer-Maske, dass ein no-op-Agent für „erledigt" gilt; (b) **Divergenz-Retry** bei E.4-HARD-FAIL (divergierenden Lauf max. N× neu, mit expliziter Retry-Protokollierung — keine stille Wiederholung); (c) die **AD-17h-Claim-Schärfe** um die **Ausführungs-Voraussetzung** erweitern („zwei frische Kontexte, *die die Mutation beide ausführen*"); (d) **Agent-Transkript-Erhaltung** im Gate (`run-a.out`/`run-b.out` im Sandbox-Root sichern, nicht aufräumen) für Root-Cause-Analyse. ## Behavior verification **Methode:** Die 12 rein-shell-Subsuiten (3-1…3-12) wurden in dieser Retro **unabhängig re-executiert** (frisch, kein Committed-Beleg) — jede mit `Exit 0`. Das Abnahmegate `sandbox-3-13` (LLM-gesteuert: Sektion D Validator-Agent + Sektion E zwei frische Agent-Kontexte A/B via `timeout 2700 "$CLAUDE_BIN" -p --bare`) wurde als End-to-End-Re-Run dieser Retro **ausgeführt** und ist **abgeschlossen**; `CLAUDE_BIN` auf die echte `claude.exe` (v2.1.198) gesetzt, da der winpty-Shim `C:\Users\mita\bin\claude` in headless `-p`-Runs schlägt (Gate hat P-3-Override; siehe Memory `wow2-claude-shim-winpty-headless`). **Ergebnis: ROT — `HARD-FAIL (E.4)`, `GATE_EXIT=1`** (s. F-10 und unten). **Subsuiten — harte Re-Exekution (alle `Exit 0`):** | Suite | Szenarien | Ergebnis | Bemerkung | |---|---|---|---| | 3-1 | V-1 (Vertrag §2) + 13 weitere | PASS 14/14 | Run-FAIL bei fehlender Bundleroot korrekt ausgelöst; FAILED=0 | | 3-2 | 7 Tests | PASS | abgeschlossen | | 3-3 | U1–U9 | PASS | unbefugter Frontmatter-Key → Struktur-HARD-FAIL (Pkt. 8) | | 3-4 | S1–S6 + N1–N3 + Form-Wahl | PASS | Duplikat/Ghost-Diff-??-Negativkontrolle nicht vacuous | | 3-5 | L1–L6 + N1 + D1 + D2 | PASS | Leasing | | 3-6 | STALE-1…STALE-6 | PASS | Leasing-Staleness | | 3-7 | CONSIST-1…7 | PASS | VALIDATION_FAIL → §6-Pkt.-3-Rollback, AD-17f Teilerfolg-Never | | 3-8 | DET-1…DET-8 | PASS | ORPHAN datumsgruppierter log-Eintrag, Erhaltungs-Invariante (nur log.md mutiert) | | 3-9 | R-1, R-1b, R-2…R-9 | PASS | 0 HARD-FAIL | | 3-10 | E-1…E-9 (Zwei-Run-Identität) | PASS 9/0 | **E-9: A==B byte-identisch, nur `generated.at` differiert; „Nicht-Vakuum bei Zustandswechsel"** — A==B-Assertion ist real, nicht tautologisch | | 3-11 | A-1…A-8 | PASS | atomare Root-Scope-Lease-Akquise (§5.17 Rev 3.6) | | 3-12 | L-1…L-9 | PASS | 9 harte Assertions, self-contained /tmp-Bundle | **LLM-Gate 3-13 — Live-Re-Exekution dieser Retro (ABGESCHLOSSEN, ROT):** | Phase | Ergebnis | |---|---| | A Setup (A.2–A.4) | PASS (A.5 Pre-Check `FAIL` = mein uncommittetes Retro-Dokument hat das real-Repo-Porcelain verschmutzt; `fail()` ist **nicht** fatal — Zähler-Bemerkung, Gate läuft weiter) | | B–C (12 Sub-Runs) | PASS — 3-1…3-12 alle `OK`, C.12 „ALLE 12 Sub-Runs grün" | | D Validator (D.1–D.6) | PASS — 4/4 `SUCCESS` | | D-NEG | PASS — 3×`FAIL` + 1×`SUCCESS` (Positiv-Kontrolle) | | E.1–E.3 (Fixture, $BASE, Worktrees) | PASS — `$BASE=6150f943…` | | E.4 A/B-Vergleich | **HARD-FAIL** — `NON_AT=6 AT=2`; `HEAD-A==BASE` (Lauf A no-op), Lauf B voll UPDATE; **`GATE_EXIT=1`** | **Verhaltens-Fazit (korrigiert nach Live-Ergebnis):** Das **deterministische Rückgrat** des Epics (inkrementeller Dataflow, textuelle Relevance, atomare Lease, deterministischer Rollback) ist **unabhängig reproduzierbar grün** (12/12 Subsuiten `Exit 0`; im Gate: C 12/12, D, D-NEG) und — entscheidend für AD-13/AD-17h — die A==B-Determinismus-Assertion wird in 3-10 **nicht-vakuum** ausgeübt (Zustandswechsel erzwingt echte Byte-Äquivalenz statt Trivials). **Aber** die **live** End-to-End-Abnahme (zwei *frische LLM-Agent-Kontexte* auf dem UPDATE-Kern) ist **an E.4 ROT**: Lauf A no-op-ppte, Lauf B lief korrekt (F-10). Das heißt konkret: **das deterministic Kernel ist grün, die frische-LLM-Ausführung des Kern-ACs ist es empirisch nicht robust** — und zwar **am selben Tag, ohne Midnight-Bruch** (also **nicht** F-5) und **im UPDATE-Kern, nicht im delegierten CREATE-Subpfad** (also **nicht** F-8). **Das authoritative grüne Gate bleibt der committed Re-Run #10 (2026-08-24, `09c1c83`): `FAILED=0 PASS_COUNT=51`, `SANDBOX-3-13-OK`, Exit 0** (`/tmp/gate-313-run10.log` Z. 1230/1275/1277). Die Live-Re-Exekution ist eine **unabhängige Wiederholung** — und sie **bestätigt** das Kern-Risiko, das F-5/F-8 spekulativ benannt haben: der frische-LLM-Pfad ist nicht deterministisch robust. Sie **ersetzt** aber nicht den grünen Committed-Beleg, auf dem das Verdikt steht; sie **verstärkt** jedoch die Argumentation, dass F-5 (und neu F-10) als *blocking* eingestuft werden sollten. ## Action items Jedes Item: Befund-Ref + Disposition (fix-now → Action-Item; defer → mit Kontext nachführbar) + Owner. **Remediation und Spec-Reconciliation sind hier *proponiert*, nicht auto-applied** — ProMods entscheidet über die Ausführung (AD-3/D-3: `compiler.md`/`validator.md`/`canonical-terms.md` sind read-only; eine Spec-Änderung erfordert eine autorisierte Revision). | ID | Befund | Action | Owner | Art | |---|---|---|---|---| | **AI-3-R-1** | F-5 | **Dateigruppen-Determinismus heilen:** die `## YYYY-MM-DD`-Header in `wiki/log.md` **entweder** auf einen Git-Wert pinnen (`git show -s --format=%cs $BASE` in §5.9 Pkt. 4 / AGENT_PROMPT) **oder** die `## `-Header-Zeile in `classify_diff` (3-13:650-653) als benannte Ausnahme wie `at`-Zeilen klassifizieren; **und** den §5.9-Z.277-Wortlaut („keinen Wanduhr-Wert … nie im `log.md`-Body") mit der Header-Realität in Einklang bringen. Schließt den §5.14-„genau eine Ausnahme"-Selbstwiderspruch. | ProMods (Autorisierung) + dev | **Spec-Reconciliation (fix-now-Vorschlag)** | | **AI-3-R-2** | F-6 | **§5.12↔§5.18-Staleness-Reconciliation:** in §5.12 Pkt. 1 (Z. 327, „TTL-Ablauf-Äquivalent" = Gen-only-stale) eine Supersession-Notiz zu §5.18 Pkt. 1 (Z. 430) + Story 3.12-AC (Z. 426: Stale verlangt bestätigten Abbruch/abgelaufene Liveness) ergänzen; §5.18 als normative Staleness-Autorität kennzeichnen. | ProMods + dev | Spec-Reconciliation (defer) | | **AI-3-R-3** | F-7 | **Gate-Leasing-Verifikation ergänzen:** ein 3-13-Szenario (analog E.9, Known-Value-Witness), das im realen Agent-Lauf (wt-a) verifiziert: `refs/leases/wiki` existiert **und** `git rev-parse 'refs/leases/wiki^{}'` == `git hash-object` der Run-ID — beweist, dass der reale Agent den §5.17-atomaren Pfad annimmt (nicht das supersedierte §5.11-check-then-act-Lockfile). | dev+review | Remediation (Gate-Härtung, defer) | | **AI-3-R-4** | F-9 | **Em-Dash-Kollaps-Klasse Cross-File-Reconciliation:** `canonical-terms.md`-Formatzeile (Z. 18/21, `[-–_ ]`) append-only-konform um den Em-Dash `—` ergänzen (Korrekturnotiz auf die §3.2/§5.14-Z.51/54a-Klasse `[-–— _]`). | ProMods + dev | Spec-Reconciliation (defer) | | **AI-3-R-5** | F-1 | **`norm()`-Vereinheitlichung + `LC_ALL`-Pinning:** die 4 drifteten `norm()`-Kopien (3-8/3-9/3-10/3-11) auf eine kanonische Implementierung (mit Case-Folding) vereinheitlichen + `LC_ALL=C`-Pinning (3-11 ist heute `LC_ALL=0`). Sharpening des bekannten D-7/W-3.9-1-Defers. | dev | **Defer** (Home: Sandbox-Härtung) | | **AI-3-R-6** | F-8 | **Fresh-LLM-CREATE-Residual** (Nutzer-Defer D-3.13-L2-3): der nicht-deterministische CREATE-/Synthese-Unterpfad (Re-Run-#5: 24/26 NON_AT) bleibt benanntes Residual; Substitutions-Notiz (mechanisch gepinnt ≙ frischer LLM für die *Mechanik-Struktur*) ist ausgeführt. Kandidat für spätere compiler.md-Revision oder Epic-4-Determinismus-Überarbeitung. | ProMods / Epic 4 | **Defer (Nutzer-Entscheidung, bereits dokumentiert)** | | **AI-3-R-7** | F-2/F-3 | **Beobachtung (kein fix-now):** `compiler.md` §5-Wachstum (5→15 Sektionen, 548 Z.) + nicht zusammenhängende §5-Nummerierung (5.10 = Story 3.4 …). Für eine spätere strukturelle Revision notiert. | — | **Accept-as-is / observe** | | **AI-3-R-8** | **F-10** (NEU, empirisch) | **Frischer-LLM-Non-Execution absichern (Kern-AC-Robustheit):** (a) **Run-Vollständigkeits-Guard** im Gate — `RUN_DONE` nur, wenn ≥ 1 Mutation staged, sonst `RUN_ABORTED` (schließt die „no-op-Agent gilt als erledigt"-Maske); (b) **Divergenz-Retry** bei E.4-HARD-FAIL (max. N×, explizit protokolliert, keine stille Wiederholung); (c) **AD-17h-Claim-Schärfe** um die Ausführungs-Voraussetzung erweitern; (d) **Agent-Transkript-Erhaltung** im Gate (`run-a.out`/`run-b.out` nicht aufräumen) → Root-Cause-Diagnose (aktuell offen, Root aufgeräumt). | dev+review | **Remediation (Gate-Härtung; fix-now-Vorschlag, da empirisch am Kern-AC)** | **Carry-forward (nicht neue Epic-3-Items):** die 4 offenen Epic-2-Items **AI-2-R-1…4** (`epic-2-retro-item-10…13`, s. Previous-retro follow-through) bleiben `open` — sie betreffen §5.5/§5.6/§5.8 (Bestands-Sektionen, nicht im Epic-3-Scope). Empfehlung: in einer Folge-Story „Instruktion-/Sandbox-Vereinheitlichung" **gebündelt** mit AI-3-R-5 (`norm()`/`LC_ALL`) abarbeiten (s. Open questions). ## Acceptance verdict **Verdikt: `accepted-with-open-items`** · **Kriterien: `declared`** (ACs je Story in `planning-artifacts/epics.md` Epic-3-Block Z. 259–451) · **pending_stories: leer** (alle 13 Stories 3.1–3.13 `done`, `detect-epic --epic 3`, 2026-08-24) → **kein Machine-Zwang zu `rejected`**. **Begründung (Evidenz):** 1. **Kriterien demonstrativ erfüllt:** - **Abnahmegate (Story 3.13) grün auf Re-Exekution:** Committed **Re-Run #10 (2026-08-24, `09c1c83`): `FAILED=0 PASS_COUNT=51`, SANDBOX-3-13-OK, Exit 0** — A.5 Pre-Check, C 12/12, D 4/4 SUCCESS, D-NEG 3×FAIL+1×SUCCESS, E.4 `NON_AT=0 AT=2` (Bundle-State identisch bis auf `at:`), E.6 Feldsatz-exakt + Known-Value-Witness, E.9 kanonische `Baseline $BASE`-Form, F G-1..G-8, G-8 Porcelain-Clean + AD-3 ohne Diff. **In dieser Retro zusätzlich:** alle 12 deterministischen Subsuiten (3-1…3-12) **unabhängig re-executiert → alle `Exit 0`**; das LLM-Gate 3-13 wurde als End-to-End-Re-Run **ausgeführt** und ist **abgeschlossen — aber ROT an E.4** (`NON_AT=6 AT=2`, `GATE_EXIT=1`; Lauf A no-op, Lauf B korrekt — **F-10**). Der grüne Committed-Beleg (Re-Run #10) steht weiterhin; die Live-Re-Exekution **widerlegt** ihn nicht, **bestätigt** aber das Kern-Risiko. - **Determinismus-Kern nicht-vakuum (F-4):** die A==B-Assertion (3-10 E-9) erzwingt echte Byte-Äquivalenz, nur `generated.at` differiert, Zustandswechsel-Nicht-Vakuum ausgeübt — AD-17h/FT-10 halten mechanisch. - **Leasing-Semantik (3-5/3-6/3-11/3-12) grün:** atomare Akquise (3-11 A-1..A-8), Staleness/Recovery (3-6 STALE-1..6), Lifecycle/Rollback/Release (3-12 L-1..L-9). - **Textuelle Determinismus-Relevance, kein Embedding (3-2/3-8/3-9/3-10):** AD-13 in allen Läufen gewahrt. 2. **Offene, benannte, getrackte Befunde (kein `accepted` — deshalb `-with-open-items`):** F-5, F-6, F-7, F-9 sind **keine** „Epic erledigt, kleine Nachträge" — sie sind reale Defekte/Verifikations-Lücken, alle mit Quelle, Owner und Disposition (AI-3-R-1…6). **F-10 (neu, empirisch):** die Live-Re-Exekution des Gates ist ROT am Kern-AC — frischer-LLM-Non-Execution auf der Ausführungs-Ebene (AI-3-R-8). F-8 ist ein **Nutzer-Defer** (D-3.13-L2-3). F-1/F-2/F-3 sind Latenz/Beobachtung. **Die zwei material-entscheidenden Items — F-5 (Midnight-Dateigruppen-Bruch, Spec) + F-10 (Live-Kern-AC-ROT, empirisch):** Der §5.14-Determinismus-Vertrag ist der **Kern-AC** des Epics (AD-17h, FT-10, AC-1/AC-6). F-5 zeigt, dass er im **Wortlaut selbst widersprüchlich** ist (erlaubt „genau eine" Ausnahme = `generated.at`, verlangt aber eine zweite, ungepinnte Wanduhr-Wand im `log.md`-Body via §5.9 Pkt. 4) und an der Tagesgrenze **ungeschützt/ungetestet**. F-10 zeigt, dass der **Mechanismus** über frische LLM-Runs **empirisch nicht robust** ist (Live-Run: Lauf A no-op, Lauf B korrekt, E.4 HARD-FAIL, `GATE_EXIT=1`). Zusammen: der Kern-AC hat **sowohl** eine **Spec-Lücke** (F-5) **als auch** eine **Ausführungs-Verlässlichkeits-Lücke** (F-10). Beide sind durch autorisierte Revisionen (AI-3-R-1) bzw. Gate-Härtung (AI-3-R-8) zu schließen. Das rechtfertigt **`accepted-with-open-items`** (nicht `accepted`): die Befunde sind getrackt, bequellen, haben Owner und Fix-Pfade — aber sie sind **nicht** „kleine Nachträge". **Eskalationsgrenze (ProMods-Entscheidung):** F-5 **und** F-10 sind die Befunde, die dieses Verdikt von `accepted-with-open-items` auf **`rejected`** kippen *könnten* — wenn ProMods sie als **blocking** einstuft. F-5 = Selbstwiderspruch im *Kern*-Determinismus-AC; F-10 = der *Kern*-Determinismus-AC ist **empirisch** (nicht nur spekulativ) nicht robust über frische LLM-Runs. Dazu F-7: die sicherheitskritische Leasing-Invariante „genau ein aktiver Root-Scope-Holder" wird nur durch Sandbox-interne Bash-Helfer, nicht durch den realen Agent-Lauf verifiziert. Das ist eine bewusste Abwägung: der **deterministische Kern** ist grün (12/12 Subsuiten, Re-Run #10 grün) und das Gate ist **fail-closed-korrekt** (F-10 wurde *erfasst*, nicht verschwiegen); die Befunde sind getrackt, bequellen und haben Fix-Pfade. **Entscheidung ProMods (2026-08-24):** F-5/F-10 = **`tracked gap`** → das Verdikt **`accepted-with-open-items`** ist final. Konsequenz: AI-3-R-8 (F-10-Ausführungs-Robustheit) ist **Voraussetzung** dafür, dass Epic 4 auf deterministischem CREATE/Synthese aufbaut (Open question 3) — ein spätes Umstufen auf *blocking* würde Epic 4 halten. ## Open questions 1. **F-5 + F-10: `gap` oder `blocking`? (gemeinsam die Eskalationsgrenze)** — **F-5** = Selbstwiderspruch im Kern-Determinismus-AC (§5.14 „genau eine Ausnahme" vs. §5.9 Pkt. 4 zweite Wanduhr-Wand) + ungeschützte Tagesgrenze (*Spec-Ebene*). **F-10** = derselbe Kern-AC ist **empirisch** nicht robust über frische LLM-Runs (Live-Re-Exekution ROT an E.4, Lauf A no-op) (*Ausführungs-Ebene*). **Diese Einstufung ist eine ProMods-Entscheidung:** als *blocking* → Verdikt **`rejected`** (Epic 4 wird gehalten, da es an den §5.14-Vertrag andockt); als *tracked gap* → **`accepted-with-open-items`** (Empfehlung dieser Retro, da der deterministische Kern grün ist — 12/12 Subsuiten + Re-Run #10 — und das Gate **fail-closed** die Divergenz *erfasst* hat, nicht verschwiegen; F-5 liegt in der *Spec-Schärfe*, F-10 in der *Ausführungs-Verlässlichkeit*, beide mit Fix-Pfaden AI-3-R-1 / AI-3-R-8). — **Entscheidung ProMods (2026-08-24):** ***tracked gap*** („Ich folge Deiner Empfehlung") → Verdikt **`accepted-with-open-items`** ist **final**; Bedingung: AI-3-R-8 (F-10, Ausführungs-Robustheit) **vor dem CREATE-Aufbau von Epic 4** abarbeiten. 2. **F-10 Root-Cause offen** — Der Lauf-A-Non-Execution-Treiber ist **nicht** abschließend bestimmbar (Sandbox-Root / `run-a.out` aufgeräumt, kein erhaltener Agent-Transkript). Soll (a) das Gate **Agent-Transkripte erhalten** (AI-3-R-8 d), damit ein nächster roter Live-Run **diagnostizierbar** ist, und/oder (b) ein **erneuter kontrollierter Live-Run** (mit Transkript-Erhaltung) als Root-Cause-Nachweis gefahren werden? Empfehlung: (a) sofort (Gate-Härtung, klein), (b) optional als Verifikation. 3. **F-8: CREATE-/Synthese-Coverage** — Der fresh-LLM-CREATE-Unterpfad (24/26 NON_AT, Re-Run #5) ist als **Nutzer-Defer (D-3.13-L2-3)** dokumentiert. Soll das Residual in **Epic 4** (Determinismus-Überarbeitung) oder in einer **separaten compiler.md-Revision** vor Epic 4 gelandet werden? (Empfehlung: vor Epic 4, da Epic 4 auf deterministischem CREATE aufbauen wird.) — *Verstärkt durch F-10:* da die frische-LLM-Ausführung empirisch nicht robust ist (F-10), ist die CREATE-Coverage-Lücke (F-8) **nicht** nur eine delegierte Mechanik, sondern teilt dieselbe Ausführungs-Verlässlichkeits-Riskoklasse. 4. **Gebündelte Spec-Vereinheitlichung:** die 4 offenen **Epic-2-Items (AI-2-R-1…4)** + **AI-3-R-5** (`norm()`/`LC_ALL`) + **AI-3-R-4** (Em-Dash) betreffen alle die **§5-Formel-/Normalisierungs-Fläche** bzw. die Kollaps-Klasse. Empfehlung: **eine** „Instruktion-/Sandbox-Vereinheitlichungs"-Story in Epic 4 (oder als Epic-3.5-Hotfix) bündelt sie — statt je eigener Revision. ProMods: bündeln oder einzeln? 5. **Session-Logs fehlen:** Prozess-Lektionen (warum Story 3.13 ≥ 6 Re-Runs + 2 Review-Loops brauchte) sind nur aus dem git-loggbaren Verhalten ableitbar (Commit-Kette vollständig); keine Session-/Transcript-Evidenz in dieser Umgebung. Kein Befund davon abgeleitet. ## Previous-retro follow-through **Basis:** `sprint-status.yaml` → `action_items` (Epic 2), gekreuzt gegen `schema/compiler.md` (Ist-Zustand, `efc543c^..3f57586`-Range) und `epic-2-retro-2026-08-18.md`. Die 5 Epic-2-Aktionsitems (AI-2-R-1…5) sind in `sprint-status.yaml` als `epic-2-retro-item-10…14` / `code-review-2-1-item-*` gebucht. | Epic-2-Item | AI-Ref | Inhalt | Ist-Zustand (Epic 3-Ende) | Status | |---|---|---|---|---| | `epic-2-retro-item-10` | AI-2-R-1 (F-01) | `§5.5`-Selbsttest-Formel rekursiv machen (`grep -rnE (raw/` über `wiki/` inkl. Area-Concepts) | **nicht umgesetzt** — `compiler.md:104`/`127` steht weiterhin bei `grep -nE '\(raw/' wiki/*.md` (Nicht-rekursiv, `wiki/*.md` greift keine `wiki//*.md` an) | **OPEN** (übernommen, nicht gelöst) | | `epic-2-retro-item-11` | AI-2-R-2 (F-03) | `§5.8`-Lauf A um Area-Concept-ohne-`index.md` (Tiefe-2, `wiki//concept.md` ohne `wiki/a/index.md`) erweitern | **nicht umgesetzt** — `compiler.md:239` Lauf (A) scannt weiterhin nur `-name index.md`; Lauf (B) (`:239`, `-mindepth 3`) erfasst nur Tiefe ≥ 3 → ein Tiefe-2-Concept ohne `index.md` ist beiden Läufen unsichtbar | **OPEN** (übernommen, nicht gelöst) | | `epic-2-retro-item-12` | AI-2-R-3 (F-04) | `§5.6`-Formel-4-Filter-Asymmetrie heilen (`--exclude=log.md` vs `grep -v log.md$` auf eine Semantik) | **nicht umgesetzt** — `compiler.md:185` (Ist) `--exclude=log.md` vs `:186` (Baseline) `grep -v "log.md$"` — die Asymmetrie (Basename-Basename-Exklusion vs Anker-Basename-Filter) steht weiterhin side-by-side | **OPEN** (übernommen, nicht gelöst) | | `epic-2-retro-item-13` | AI-2-R-4 (F-05) | `§5.8`-Reachability als echte Markdown-Links prüfen + `./`-Variante mit `§5.6`-Pin vereinheitlichen | **teilweise** — „echte Markdown-Links"-Hälfte umgesetzt (Loop-3-Fix, `:244`: prüft jetzt Linksyntax `](` statt bloßem Klammer-Paar); **`./`-Vereinheitlichung nicht umgesetzt** — `:239` Lauf A akzeptiert weiterhin `](./$a/index.md)`, während der `§5.6`-Form-Check (`:169`) `./`-Präfix-Ziele via `grep -vE '^\.'` aus der Form-Zählung nimmt → die `./`-Asymmetrie bleibt | **OPEN** (Halbteil gelöst, Kern-`./`-Teil übernommen, nicht gelöst) | | `epic-2-retro-item-14` | AI-2-R-5 (F-02) | Autorisierte Validator-Rev-9 für Punkt-11-Area-Lesart | **umgesetzt** — `validator.md` Revision 9, Punkt-11-Area-Lesart formalisiert (file-relative Referenz in `index.md`); zertifiziert | **done** (closed 2026-08-18) | **Fazit:** Von den 5 Epic-2-Retro-Items ist **1 (AI-2-R-5) geschlossen** (bereits 2026-08-18, vor dem Epic-3-Range) und **4 (AI-2-R-1…4) sind nach wie vor offen** — alle vier betreffen **Bestands-Sektionen** (`§5.5`/`§5.6`/`§5.8`), die Epic 3 **nicht im Scope hatte** (Epic 3 = neue Sektionen `§5.9`–`§5.18` + Determinismus-Vertrag `§5.14`/`§6.5`). Der Churn an `compiler.md` in Epic 3 (21 Commits) traf diese drei Self-Test-Formeln nicht, daher blieben die Lücken strukturell erhalten. Das ist **kein** Epic-3-Defekt (die Items waren korrekt an Epic 3 *angehängt* als `open`), aber es bestätigt den in F-2 genannten Wartungspunkt: die **§5-Formel-Fläche** ist der natürliche Ort, an dem Epic-übergreifende Self-Test-Lücken akkumulieren — eine Folge-Story/Revision sollte die 4 offenen AI-2-R-Items gebündelt abarbeiten (natürliche „Sandbox-/Instruktion-Vereinheitlichung"-Home, s. `deferred-work.md`). **Kein Status-Transition-Vorschlag an `sprint-status.yaml` für die Epic-2-Items** — die 4 offenen bleiben `open` (nachweislich nicht gelöst), `item-14` ist bereits `done`.