Files
wow20/_bmad-output/implementation-artifacts/epic-3-retro-2026-08-24.md
T
2026-08-24 16:36:42 +02:00

207 lines
42 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
epic: 3
date: 2026-08-24
verdict: accepted-with-open-items
criteria: declared
headless: false
---
# Retrospective Epic 3 — Inkrementelle Kompilation & Synthese
<!-- Skeleton — wird Phase für Phase gefüllt. -->
## 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.13.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. 259451 + 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.13.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), L572573 (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. 257440 ≈ 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 <lock-ref> <wert> $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. 17) … 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 | U1U9 | PASS | unbefugter Frontmatter-Key → Struktur-HARD-FAIL (Pkt. 8) |
| 3-4 | S1S6 + N1N3 + Form-Wahl | PASS | Duplikat/Ghost-Diff-??-Negativkontrolle nicht vacuous |
| 3-5 | L1L6 + 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.2A.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) |
| BC (12 Sub-Runs) | PASS — 3-1…3-12 alle `OK`, C.12 „ALLE 12 Sub-Runs grün" |
| D Validator (D.1D.6) | PASS — 4/4 `SUCCESS` |
| D-NEG | PASS — 3×`FAIL` + 1×`SUCCESS` (Positiv-Kontrolle) |
| E.1E.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. 259451) · **pending_stories: leer** (alle 13 Stories 3.13.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/<area>/*.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/<a>/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`.