# Changelog

Alle nennenswerten Änderungen am Bundle werden hier dokumentiert.
Format orientiert sich an [Keep a Changelog](https://keepachangelog.com/),
Versionierung folgt [SemVer](https://semver.org/).

## [Unreleased]

## [0.28.0] — 2026-06-12 — Backlog-Welle: INSTALL.md-Klarheits-Paket, Drift-Check-Richtung, Bundle-Scope-Fixes

Gebündelte Backlog-Abarbeitung (Stefan-Entscheid 2026-06-12, Endspurt-Welle; Brief mit Critic-Protokoll in `.maintainer/docs/V0.28.0-BACKLOG-WELLE-BRIEF.md`). Topf-2-Theoriefälle (UNC-Pfad, Integrationstest-Mocking, `_is_cache_artifact`) gleichzeitig als won't fix gestrichen.

### Hinzugefügt

- **INSTALL.md-Klarheits-Paket** (aus 3-Brillen-Review 2026-06-12): Phase-8-Hinweis, dass `.codex/config.toml` im Staging bewusst Staging-Pfade trägt (Korrektur erst Schritt 12c); Schritt-12c-Präzisierung, dass der Korrekturfall allein `.codex/config.toml` ist (`.claude/settings.json` war nie defekt); returncode-Hinweise in 12c — rc2 genau einmal mit `--force` wiederholen (sicher, Spiegel sekundenfrisch aus dem Bundle; Ursache praktisch immer Cloud-Sync-Zeitstempel), rc1 nie mit `--force`. BOOTSTRAP.md verweist auf Schritt 12c und den einmaligen Codex-Hook-Trust. Pins: `test_schritt_12c_finaler_sync_lauf` (vertieft), `test_phase_8_staging_pfade_hinweis`, `test_bootstrap_verweist_auf_schritt_12c`.
- **Richtungs-Logik im `bundle_version_drift_check`-Hook:** je Drift-Eintrag gerichtete Empfehlung — Vault-Skill älter als Bundle → `/skill-update <name>`, neuer → `/skill-to-bundle <name>`, unparsebare Version → richtungsblinder Fallback wie bisher. Pins: drei neue Richtungs-Tests. Bekannte Einschränkung dokumentiert (Brief): `/skill-update` schreibt nur den Spiegel, nicht die SSoT — bleibt Backlog.

### Geändert

- **Runbook-Befund 3 (templates/-Sichtbarkeit) als by design geschlossen:** Der sichtbare `templates/`-Ordner ist Nutzer-Funktion (Inhalts-Vorlagen zum Befüllen); die Schritt-13-Erfolgsmeldung erklärt ihn jetzt. `templates/README.md` beschreibt das reale Installationsverhalten statt eines nie implementierten Auto-Kopierens. Pin: `test_schritt_13_templates_hinweis`.

### Behoben (Critic-Funde, beide per pathspec-Simulation auf Disk bestätigt)

- **`templates/README.md` erreichte das Bundle nie** — das verzeichnisweite `README.md`-Pattern in `.bundleignore` matchte sie weg; Negation `!templates/README.md` liefert die einzige Nutzer-Erklärung des Ordners jetzt aus.
- **Maintainer-Commands schifften kaputt:** `.claude/commands/skill-update.md` und `skill-to-bundle.md` (rufen das nie ausgelieferte `.maintainer/scripts/` auf, deklarieren sich selbst als „nicht im Bundle") sind jetzt via `.bundleignore` ausgeschlossen; `vault-gap-analysis.md` bleibt (`bundle_command: true`). Pins: `test_bundleignore_scope.py`.

### Validierung

- pytest **582 → 590 passed**, 8 Skips, Umlaut-Hartwand grün.
- Live-Lauf: echter Install in `C:\Temp\probe-v0280` (lokal gebautes Bundle, Profil `allgemein`) — komplette Pipeline Exit 0 inkl. Schritt 12c (kein `--force` nötig), config.toml ohne `.tmp_install`-Treffer, `templates/README.md` im Vault, `.claude/commands/` ohne Maintainer-Commands, Spiegel 28+28, AGENTS.md substituiert, Richtungs-Logik live bewiesen (älter → nur `/skill-update`, rc-Version → Fallback).

## [0.27.0] — 2026-06-12 — Befund-4-Fix: finaler sync-Lauf (Schritt 12c), Sichtbarkeits-Korrektur

Mini-Welle aus zwei Posten (Generalprobe-Befund 4 vom 2026-06-11 plus Sichtbarkeits-Entscheid; Brief mit Critic-Protokoll in `.maintainer/docs/V0.27.0-RELEASE-WELLE-BRIEF.md`).

### Hinzugefügt

- **Schritt 12c in INSTALL.md — finaler sync.py-Lauf gegen den Vault-Root** (Befund 4, MED, nur Codex): `.codex/config.toml` entsteht in Phase 7/8 im Staging und trägt absolute Hook-Pfade mit `…/.tmp_install/…`; nach dem atomaren Move (Schritt 11) zeigten die Codex-Hook-Pfade ins gelöschte Staging und heilten sich ohne Skill-Drift nicht selbst (`sync_drift_check` ist unter Codex inaktiv). Der neue Schritt 12c (nach 12b, vor 13) regeneriert `.claude/settings.json`, `.codex/config.toml` und `.docs/sync-state.json` mit dem echten Vault-Pfad — `--profile` bleibt Pflicht, returncode 2 ist Abbruch-Kriterium. Claude Code war nie betroffen (`$CLAUDE_PROJECT_DIR`). Schritt-13-Erfolgsmeldung konsistent nachgezogen. Pin: `test_schritt_12c_finaler_sync_lauf`.

### Geändert

- **Privates GitHub-Repo nicht mehr als „öffentlich abrufbare" Bundle-Quelle verlinkt** (Sichtbarkeits-Befund, Stefan-Entscheid 2026-06-12: Repo bleibt privat): installation-log-Template und Prosa in INSTALL.md zeigen auf `https://bootstrap.lehnisch.de/v<version>/bundle.zip`, der GitHub-Link ist von der öffentlichen Bootstrap-Seite (`tools/render_index.py`) entfernt. Pins: `test_keine_privaten_repo_links`, `test_render_index_no_private_repo_link`.

### Validierung

- pytest **579 → 582 passed**, 8 Skips, Umlaut-Hartwand grün.
- Live-Lauf: echter Install in `C:\Temp\probe-v0270` (lokal gebautes Bundle, Profil `allgemein`) — Befund-4-Zustand im Staging reproduziert (config.toml mit `.tmp_install`-Pfad), Schritt 12c Exit 0, danach 0 `.tmp_install`-Treffer, Hook-Pfade auf echtem Vault-Root, Spiegel 28+28, `active_profile=allgemein`. Kein `--force` nötig (copytree erhält mtimes, per Disk und live bestätigt).

## [0.26.0] — 2026-06-11 — Install-Härtung 3: Profil-treuer Auto-Fix, Codex-Pfade absolut, Headless-Pin gebündelt

Mini-Welle aus drei Posten (IH2-Beifang-Befund plus zwei Backlog-Posten aus dem Abschluss-Review; Briefs, Critic- und Validierungs-Protokolle in `.maintainer/docs/INSTALL-HAERTUNG-3-BRIEFS.md`).

### Geändert

- **`sync_drift_check`-Auto-Fix reicht `active_profile` als `--profile` durch** (Posten 1, MAJOR, IH2-Beifang): der Session-Start-Auto-Fix rief sync.py ohne `--profile` — bei Nicht-allgemein-Vaults kippte das `active_profile` in sync-state.json still aufs alphabetisch erste Profil und schrieb die falsche Skill-Aktivierung (Befund-Klasse wie Dossier-Befund 3). Jetzt: Profil aus `.docs/sync-state.json`, Fallback ohne Datei/Key/lesbares JSON wie bisher; unbekanntes Profil scheitert laut (Block mit Repair-Hinweis) statt still zu kippen. 4 neue Pins inkl. Integrationstest mit echtem sync.py (am Alt-Stand nachweislich rot). Live bewiesen: `claude -p`-Session-Start in karpathy-Test-Vault, Auto-Fix läuft mit `active_profile=karpathy`, Profil stabil.
- **`aggregate_hooks` emittiert config.toml-Commands (Codex) mit absolutem Vault-Pfad** (Posten 2): posix-Form in Quotes (`uv run "<vault>/.skills/…"`), sync-zeitig bekannt — das relative Format hing an derselben unbelegten Spawn-cwd-Annahme wie die Claude-Seite vor IH2 Posten 5. Interaktiv live bewiesen (Desktop-App, Leerzeichen-Pfad-Testvault): Hook-Spawn über den gequoteten Pfad, Umlaut-Trigger-Match, Injektion per Codex-Session-Transkript (developer-Message). Methoden-Update: Beweis über `transcript_path` aus dem Firing-Log — gpt-5.5 zitiert injizierte developer-Messages nicht mehr wörtlich. config.toml ist damit sichtbar maschinenspezifisch; Pfad-Änderung löst einmalig den Codex-Hook-Trust-Reprompt aus.
- **Headless-Pin auf einen Union-Driver gebündelt** (Posten 3, Test-Mechanik): statt 9 `uv run --no-project`-Prozessen lädt EIN Driver mit der Dep-Union alle Entrypoints per `runpy.run_path` (Modulebenen-Code läuft, `main()` nicht). Union-Masking neutralisiert ein neuer statischer AST-Pin: jeder Nicht-Stdlib-Import muss in den PEP-723-Deps deklariert sein (Mapping `yaml`→`pyyaml`, `frontmatter`→`python-frontmatter`, fail-loud bei unbekannten Imports). Der tzdata-Pin bleibt als einzige Wache seiner Klasse (zoneinfo ist Stdlib, Union enthält tzdata immer). Negativ-Beweise: AST-Pin-Selbsttest, Driver ohne tzdata scheitert am guard-Hook. Testdatei-Laufzeit ~20s → <1s.

### Validierung

- pytest **571 → 577 passed**, 8 Skips, Umlaut-Hartwand grün.
- Live-Läufe: `claude -p` in `C:\Temp\ih3-p1-vault` (Posten 1); interaktive Codex-Probe in `C:\Development\00_Tests\ASB Codex Abs Pfad` (Posten 2, Firing-Log + Transkript-Beweis).
- Beifang dokumentiert (beobachten, nicht gefixt): Codex-Desktop-App kennt `/hooks` nicht mehr als Slash-Command und bietet Migration von Claude-Hooks nach `.codex/hooks.json` an — Hinweis auf einen parallelen Hook-Mechanismus neuerer App-Versionen.

## [0.25.0] — 2026-06-11 — Install-Härtung 2: Fremd-Maschinen-Blocker, Vault-Patches upstream, Hook-Pfad-Härtung

Mini-Welle aus acht Posten (Probe-Bootstrap-Befunde P1–P3 plus fünf arbitrierte Posten aus dem Review der Vault-Update-Welle 0.24.0; Briefs, Critic- und Validierungs-Protokolle in `.maintainer/docs/INSTALL-HAERTUNG-2-BRIEFS.md`). Beseitigt den letzten bekannten Fremd-Maschinen-Blocker vor der Sarah-Demo und kollabiert die drei gewollten Vault-Vorsprünge zurück ins Bundle.

### Hinzugefügt

- **PEP-723-Header für `build_index.py`** (Posten 1, P2/BLOCKER-Kandidat): INSTALL.md Phase 7.5 crashte auf jeder fremden Maschine mit `ModuleNotFoundError: yaml` — im Repo maskierte das Projekt-Env den Defekt. Pin-Test `test_uv_run_inline_deps.py` (27 Assertions): jedes uv-run-Skript (7 Hooks + sync.py + build_index.py) startet headless unter `uv run --no-project` ohne Import-Fehlerklasse, plus statischer zoneinfo→tzdata-Pin (plattformunabhängig, der Headless-Lauf fängt tzdata nur auf Windows). Negative Proben gegen die v0.24.0-Stände belegt.
- **sync.py-Robust-Patch upstream** (Posten 2, verbatim aus dem Produktiv-Vault): `_force_writable_and_retry`/`_robust_rmtree`/`_robust_rename` heilen OneDrive-Read-only und transiente WinError 5/32 in allen 8 rmtree/rename-Callsites von `_atomic_mirror_copy`. Pin-Test `test_sync_robust_fs.py` (5 Tests) inkl. Quelltext-Pin gegen nackte Callsites.
- **`frontmatter_validator` `exempt_files`** (Posten 3, verbatim aus dem Produktiv-Vault): `AGENTS.md`/`CLAUDE.md`/`INDEX.md` sind konstruktionsbedingt ohne Frontmatter und bleiben jetzt editierbar (z.B. /skill-new-Tabellen-Update). 3 neue Pins inkl. Block-Regression für nicht-exempte Dateien.
- **`tzdata` in `guard_notebooklm_delete`-Inline-Deps** (Posten 4): ohne sie crashte der Lösch-Schutz auf Windows bei JEDEM Aufruf (ZoneInfo auf Modulebene) — der Hook war im Vault komplett tot, bis der Review-Fix kam; jetzt upstream und vom Posten-1-Pin dauerhaft erzwungen.
- **`external_global_recommendations.allgemein: [notebooklm]`** (Posten 8d, P6): `notebook-research` ist allgemein-aktiv und delegierte ins Leere. Neuer generischer Pin: jeder profil-aktive Skill mit externem `depends_on` MUSS im Empfehlungs-Key stehen (schließt die Befund-Klasse, nicht nur den Einzelfall).

### Geändert

- **`aggregate_hooks` emittiert settings.json-Commands mit `"$CLAUDE_PROJECT_DIR/"`-Präfix in Quotes** (Posten 5, MAJOR, im Produktiv-Vault reproduziert): relative Pfade ließen Schutz-Hooks bei abweichender Spawn-cwd STILL nicht feuern. config.toml (Codex) bleibt bewusst relativ — Codex setzt die Variable nicht, Format-Wechsel erst nach interaktivem Codex-Live-Test (Backlog). Szenario-Resolver (scenario_02/03) expandieren die Variable jetzt wie die Laufzeit und splitten per shlex — dabei eine stille Test-Fehlklasse beseitigt (scenario_03 wertete uv-Spawn-Fehler Exit 2 als „block"-Erfolg). Live bewiesen per echtem `claude -p`-Session-Start: Drift-Auto-Fix feuert über das neue Format.
- **Cache-Artefakte aus der Drift-Klassifikation gefiltert** (Posten 6, MAJOR, im Produktiv-Vault real passiert): `__pycache__`/`.pytest_cache`/`.pyc` zählen nicht mehr als Quell-/Spiegel-Inhalt — vorher löste jeder lokale Skript-Lauf bei JEDEM Session-Start einen sync-Schreiblauf aus. Filter an allen drei Stellen derselben Wurzelursache (`sync_drift_check._max_mtime`, `sync._skill_has_drift`, copytree-ignore in `_atomic_mirror_copy`). Live bewiesen: Session-Start mit künstlich frischem `__pycache__` schreibt nicht mehr.
- **INSTALL.md Phase 1 auf Starter-Notizen-Scope** (Posten 7, P1): Frontmatter-Validierung nur noch `.templates/<baum>/PARA/**/*.md`; Template-Root-Steuerdateien und `.skills/` explizit ausgenommen — ein wortgetreuer Agent brach vorher mit „Bundle defekt" ab (35 von 65 Bundle-Dateien folgten bewusst anderen Schemata).
- **INSTALL.md-Beifang** (Posten 8): Phase-10-Log nennt den Feldpfad `bundle.version` (P3); Phase-10b-Begründung ohne nicht-existente `CHANGELOG.md` (P4); Phase 8 dokumentiert den Command-Präfix. **README**: v0.24.0-Einzeiler in Status & Reife.

### Validierung

- pytest **537 → 571 passed** (+34 neue Pins), 8 Skips (zoneinfo-Parametrisierung), Umlaut-Hartwand grün.
- Live-Läufe gegen frisch gebautes Bundle in `C:\Temp\ih2-testvault` (echte Fremd-Umgebung ohne Projekt-Env): setup-para/setup-root/sync Exit 0, build_index zieht pyyaml aus dem Header, `07 Anhänge` mit echtem ä; zwei echte `claude -p`-Session-Starts (Cache-Filter negativ, Hook-Feuern positiv kontrolliert).
- Neuer Beifang-Befund dokumentiert (nicht gefixt, arbitrieren): `sync_drift_check`-Auto-Fix ruft sync.py ohne `--profile` — bei Nicht-allgemein-Vaults würde der Session-Start das Profil still umkippen (Briefs-Dokument, Abschnitt Beifang-Befund).

## [0.24.0] — 2026-06-11 — Install-Härtungs-Welle 1: Doku-Code-Übergaben repariert, templates-Feld lebendig

Sammel-Release der Install-Härtungs-Welle (Posten 1–8 aus dem Vier-Brillen-Review-Dossier v0.23.0, Briefs + Critic-/Validierungs-Protokolle in `.maintainer/docs/INSTALL-HAERTUNG-1-BRIEFS.md`). Schließt die fünf Install-Bruchstellen an den Übergabepunkten Doku→Code, die das Versprechen „alle 7 Profile installierbar" für Fremd-Nutzer auf `allgemein` begrenzten, plus Architektur-Vereinfachung und Doku-Nachzieher.

### Hinzugefügt

- **`sync.py resolve_template_dir(vault, profile)`** (Posten 6): macht das bisher tote `theme_profiles.<profil>.templates`-Feld lebendig — Stufe 1 Manifest-Mapping (fail-loud bei leerem Feld), Stufe 2 direkter Baum-Name für Maintainer-/Test-Pfade (`default`), Stufe 3 ValueError mit bekannten Profilen. `main()` löst vor `--setup-para`/`--setup-root` auf; `install_root_files`/`materialize_profile_tree` nehmen semantisch `template_dir`. Live validiert: alle 7 Profile setup-para + setup-root + sync Exit 0 gegen frisch gebautes Bundle, Umlaut-Ordner intakt, beratung/business materialisieren Starter-Notizen.
- **README-Versions-Marker im Bump-Skript** (Posten 1): `bump_bundle_version.py` zieht die `Aktueller Tag:`-Zeile (Version + Released) und die Quickstart-Bundle-URL per Regex mit (Touch-Zählung 35 → 38 mit released). Pin-Test `test_readme_version_consistency.py` erzwingt README == bundle.json plus unzip-Verbot.
- **`image`-Key in `external_global_recommendations`** (Posten 4): `nano-banana-image` + `openai-image-gen`; `automation` um `elevenlabs-api` ergänzt (gleiche Befund-Klasse). Pin-Test `test_anwender_scope_recommendations.py` (3 Tests): jeder profil-aktive anwender-Skill muss im Empfehlungs-Key stehen — sonst kündigt `trigger_enforcer` Skills an, die das Skill-Tool nicht laden kann.

### Geändert

- **README.md auf Release-Stand regeneriert** (Posten 1, war v0.19.5-fixiert): Kopf-Zeile, Quickstart-URL, UTF-8-sicheres Entpacken (python zipfile / Expand-Archive statt verbotenem Git-Bash-unzip), Skill-Inventar-Überschrift versionslos, Status & Reife verdichtet auf Einzeiler + CHANGELOG-Link.
- **INSTALL.md Profil-Abfrage freigeschaltet** (Posten 2): Schritt 2 fragt alle 7 Profile per zweistufiger `AskUserQuestion` ab (Tool-Limit 4 Optionen/Frage) mit Kurzbeschreibungs-Tabelle; Phase-10-Log-Template parametrisiert. Die B.1-MVP-Sperre („nur allgemein") ist Geschichte.
- **INSTALL.md Phase 7 mit `--profile`-Pflicht** (Posten 3): ohne Argument fiel `sync.py` still auf das alphabetisch erste Profil zurück — ein karpathy-Install bekäme die falsche Skill-Aktivierung.
- **INSTALL.md Phase 4.5/9 anwender-Kette geschlossen** (Posten 4): Fallunterscheidung Bundle-eigener anwender-Skill (AskUserQuestion → bei Ja Installation nach `~/.claude/skills/` in Phase 9) vs. externe Empfehlung; Phase 9 vom toten `scope: global`-Text auf die reale anwender-Mechanik umgeschrieben.
- **`.commands/skill-activate.md` gegen Code-Realität neu geschrieben** (Posten 5): Profil aus `sync-state.json::active_profile` statt hartkodiertem `allgemein`, `--profile` in allen sync-Aufrufen, ehrlicher „Was Aktivierung bewirkt"-Block (active_skills/Trigger + MCP-Aggregation; Spiegelung ist kein Aktivierungs-Effekt, Deaktivierung löscht keine Spiegel).
- **manifest.json Profil-Mapping** (Posten 6): `beratung` → eigener `beratung`-Baum, `business` → eigener `business`-Baum; faktisch falsche default-Template-Descriptions korrigiert.
- **INSTALL.md Phase 1/2/3 auf Baum-Auflösung** (Posten 6), **Phase 8 auf Code-Realität** (Posten 7d: aggregate_hooks/aggregate_mcp laufen im Phase-7-Lauf, Phase 8 = Verifikations-Schritt), **Phase-5-Liste auf manifest.json-Bestand** (7d), **Schritt 12b Lösch-Ort präzisiert** (7a), **auditor-judge.md tmp-Pfad host-neutral** (7b).
- **build_index.py** (Posten 7c): `_codex_mirror_fallback`-Docstring-Invariante korrigiert (Suffix-Check greift auch bei Override mit Default-Wert); tote `is None`-Zweige in `collect_skills`/`collect_commands` entfernt.
- **Doku-Status nachgezogen** (Posten 8): AUDITOR-MIGRATION-SPEC L-1 GESCHLOSSEN-Vermerk, CODEX-WAVE-1B Empfehlung 4 ERLEDIGT-Vermerk, FOLGE-WELLEN-ROADMAP Phase-2-Zeilen von real belegten Versionsnummern auf „offen".

### Entfernt

- **5 Byte-Spiegel-Template-Bäume** (Posten 6): `.templates/allgemein|automation|content|image|karpathy/` (70 Dateien) — ersetzt durch Manifest-Auflösung. Bundle 1.44 → 1.10 MB. Spiegel-Pins in `test_template_profiles.py` durch Auflösungs-Pins ersetzt (Ziel existiert + vollständig, keine Waisen-Bäume, 3 Resolve-Stufen) — kein Abdeckungsverlust.

### Validierung

- pytest **528 → 537 passed** (+14 neue Pins, −6 alte Spiegel-Pins, +1 Resolve-Suite), Umlaut-Hartwand grün.
- Eval-Suiten: 35/36 PASS (30 Skill-Suiten, 6 Cross-Skill-Suiten). Bekannter Altbestand-FAIL `authentic-portrait` 6/7 (Layer-Reihenfolge) reproduziert identisch auf Tag v0.23.0, von dieser Welle unberührt → Backlog.
- Live-Simulation: alle 7 Profile setup-para + setup-root + sync Exit 0 (Posten-6-Protokoll im Briefs-Dokument).

## [0.23.0] — 2026-06-11 — Backlog-Abarbeitung 1: Sarah-Defekte, Pfad-Fixes, 7 installierbare Profile, Welle-3-Commands

Sammel-Release der Abarbeitungs-Session (Posten 1–7, Briefs + Critic-Protokolle in `.maintainer/docs/BACKLOG-ABARBEITUNG-1-BRIEFS.md`). Pflicht-Mengenziel 1–4 plus komplette Kür 5–7.

### Hinzugefügt

- **Vier Profil-Bäume `automation`, `content`, `image`, `karpathy`** als Byte-Spiegel von `.templates/default/` (Stefan-Entscheid; analog allgemein-Hotfix v0.19.6). Vorher brach `sync.py --setup-para/--setup-root` für diese Profile hart ab — `theme_profiles.<profil>.templates` ist totes Metadatum, der Code liest `.templates/<profil>/` direkt. Live validiert: setup-para + setup-root für alle vier Profile Exit 0. Damit sind **alle 7 deklarierten Profile installierbar**. Spiegel-Pins in `test_template_profiles.py` parametrisiert (ersetzt `test_allgemein_profil_existiert` + `test_allgemein_ist_byte_identischer_spiegel_von_default` ohne Abdeckungsverlust).
- **`.commands/auditor-judge.md` ins Bundle** (Stefan-Entscheid Option A, schließt AUDITOR-MIGRATION-SPEC L-1): byte-identische Übernahme aus `.claude/commands/`, wird von `sync.py mirror_commands` in Anwender-Vaults gespiegelt (live verifiziert).
- **INSTALL.md Schritt 12b** (Sarah-Befund 2): löscht nach dem atomaren Move die Original-Downloads `BOOTSTRAP.md`, `bundle.zip`, `bundle.zip.sha256` aus dem Vault-Root; Schritt-7-Whitelist um die Setup-Artefakte erweitert, Phase-10b-Querverweis. Pin-Test `test_schritt_12b_entfernt_download_artefakte`.
- **Codex-Spiegel-Fallback in `build_index.py`** (`_codex_mirror_fallback`): fehlt der `.claude`-Default-Spiegel, liest der INDEX-Scan den inhaltsgleichen `.agents/`-Spiegel (CODEX-WAVE-1B-Befund P2). Vier neue Unit-Tests.

### Geändert

- **PARA-Template-Ordner `01 TaskNotes` → `TaskNotes`** in allen Profilen (Sarah-Befund 1): die ausgelieferte AGENTS.md verlangt den Ordner ohne `01`-Präfix. Pin-Test gegen Rück-Drift; `EXPECTED_PARA` im Szenario-Test angepasst; INSTALL.md Phase 2 präzisiert.
- **getmyinvoices/SKILL.md:** alle 66 `.claude/skills/getmyinvoices/`-Pfade auf die SSoT `.skills/getmyinvoices/` umgestellt (Spiegel ist AUTO-GENERATED, nicht zum Ausführen).
- **linkedin-ideen:** externe Abhängigkeit `external-ai.py` an fünf Stellen host-agnostisch formuliert (Claude-Code-Pfad plus Codex-Hinweis statt hartem `~/.claude`-Pfad).
- **Welle-3-Commands frame-agnostisch:** auditor (Judge-Pass: Slash-Command unter Claude Code, Anweisung aus `.commands/auditor-judge.md` unter Codex), migration (Aktivierung via `.commands/skill-activate.md`-Workflow), video-creator (drei `/clear`-Stellen als „frische Session, unter Claude Code per `/clear`").

### Erledigt ohne Code (verifiziert)

- **Drift-Skills-Promotion obsolet:** Produktiv-Vault-SSoT und beide Spiegel enthalten für `getmyinvoices`, `gmi-accountant`, `session-log` keine Zeile, die das Bundle nicht kennt; die mtime-Drift vom 2026-06-08 war ein OneDrive-Wackler (Delta 0s, unabhängig verifiziert). **Die `sync.py --force`-Sperre gegen den Produktiv-Vault ist aufgehoben.** Nachsorge: Bundle-Stand der drei Skills in den Vault + Dual-Mirror-Sync (fehlende `.agents/`-Spiegel).
- **AGENTS.md Slice 4 (CLAUDE.md-Stub):** durch den Produktiv-Cutover bereits erfüllt — Vault-CLAUDE.md ist byte-identisch zum Template-Stub mit AGENTS.md als Source of Truth. Doku nachgezogen (CODEX-COMPATIBILITY §5.1, FOLGE-WELLEN-ROADMAP).
- **Testvault-Hygiene:** AP2-DEBUG-Instrumentierung im `ASB-Codex-Hook-Testvault` per Bundle-Stand + frischem sync-Lauf entfernt, `.codex/config.toml` regeneriert.
- **Branch-Cleanup:** `codex-welle-2` + `ap2-dual-output` gelöscht (nur lokal vorhanden gewesen; Stefan-OK).

### Bilanz

- pytest **514 → 528 passed** (+14), Umlaut-Hartwand grün, Evals getmyinvoices 11/11, linkedin-ideen 21/21, index-rebuild 20/20, auditor 20/20, migration 18/18, video-creator 3/3.
- Jeder Posten als Mini-Welle mit Brief, Critic-Pass und adversarialem Critic; Posten 3 zusätzlich mit unabhängigem Verifikations-Subagent.

## [0.22.0] — 2026-06-10 — AP2-Mini-Welle: trigger_enforcer unter Codex aktiviert

Abschluss der Codex-Welle-2-Reihe: Der `trigger_enforcer`-Hook (UserPromptSubmit) läuft jetzt unter Codex. Der Flip `codex: false → true` erfolgte erst nach einem grünen interaktiven Desktop-App-Test (4/4 Kriterien) — `codex exec` bleibt für Hook-Verifikation ungültig (CODEX-COMPATIBILITY §7).

### Hinzugefügt

- **Host-Detection in `trigger_enforcer.py`:** Codex verwirft JSON-Hook-Output mit unbekannten Top-Level-Keys komplett (live per Session-Transkript bewiesen). Diskriminator `turn_id` (nur im Codex-Payload vorhanden, live verifiziert; in der offiziellen Claude-Code-Hook-Spezifikation nicht): unter Codex pures `{"hookSpecificOutput": {"hookEventName": "UserPromptSubmit", "additionalContext": …}}`, unter Claude Code Dual-Objekt (Bundle-Eval-Konvention plus `hookSpecificOutput`). Kein-Treffer-Pfad unverändert `{"action": "allow"}`.
- **stdin-UTF-8-Fix (F14-Erweiterung):** Codex liefert den Hook-Payload als rohe UTF-8-Bytes; Python-stdin defaultet unter Windows auf cp1252 — Umlaut-Trigger („verständlich machen", „session schließen") matchten unter Codex nicht. Fix: `sys.stdin.reconfigure(encoding="utf-8")`. Pin-Test mit erzwungenem cp1252-Default und `ensure_ascii=False`-Payload.
- **7 neue Pin-Tests** in `tests/unit/test_trigger_enforcer.py` (Dual-Output, Umlaut, cp1252-stdin, Codex-Pfad mit/ohne Treffer, Flip-Pin `test_hook_yaml_codex_flag_is_true`).
- **Spec** `.maintainer/docs/AP2-MINI-WELLE-DUAL-OUTPUT-SPEC.md` mit vollständigem Live-Test-Protokoll (§5.1–§5.4) inkl. verifiziertem Codex-Input-Schema (`session_id`, `turn_id`, `transcript_path`, `cwd`, `hook_event_name`, `model`, `permission_mode`, `prompt`).

### Geändert

- **`.skills/trigger_enforcer/hook.yaml`:** `tool_support.codex: true` — erster unter Codex aktiver Bundle-Hook. `sync.py` schreibt den Eintrag damit in jede generierte `.codex/config.toml`.
- **`CODEX-COMPATIBILITY.md`** §2.1/§3/§7 aktualisiert: beide AP2-Baustellen (Output-Format, Input-Schema) erledigt; Hook-Status-Tabelle korrigiert (sechs von sieben Hooks `codex: false`).

### Bilanz

- pytest **507 → 514 passed** (+7), Umlaut-Hartwand grün.
- Interaktiver Codex-Test (Desktop-App, gpt-5.5): drei Proben, 4/4 Kriterien grün — Hook feuert, Input-Schema kompatibel, Kontext-Injektion wörtlich belegt, kein PowerShell-Crash.


## [0.21.0] — 2026-06-10 — Codex-Welle 2: Hook-Aktivierungs-Vorstufe (AP1 + AP3)

Welle 2 der Codex-Aktivierung. AP1 und AP3 sind umgesetzt; AP2 (trigger_enforcer-Flip) wurde per Live-Diagnose als headless nicht verifizierbar erkannt und als eigene Mini-Welle ins Backlog verschoben.

### Hinzugefügt

- **AP1:** `sync.py` schreibt `[features] multi_agent = true` in jede generierte `.codex/config.toml` (Stub- und Hook-Pfad). Drei tomllib-Pin-Tests in `tests/unit/test_sync_hooks.py`. `multi_agent` ist in Codex CLI 0.137.0 bereits stable mit Default `true` — der explizite Eintrag macht das Bundle robust gegen Default-Änderungen.
- **AP3:** `features.codex_subagent_fallback` (Default `false`) in den SKILL.md von `projekt-mentor`, `gmi-accountant` und `linkedin-ideen`, plus „Wenn true: seriell“-Klausel an der jeweiligen Dispatch-Stelle. Das gmi-accountant-Pflicht-Gate bleibt erhalten (Hauptagent prüft selbst statt Subagent); projekt-mentor ist bei den Modell-Angaben (opus/haiku) frame-agnostisch formuliert.

### Geändert

- **Doku-Fix Befund 0e:** `CODEX-COMPATIBILITY.md` §3/§6 + Quirk 11 — `.codex/config.toml` wird seit F2 **immer** generiert, nicht nur bei `codex: true`-Hooks.
- **Versions-Drift geheilt:** Die Releases 0.19.5 bis 0.20.0 liefen ohne Bump-Skript; alle 31 SKILL.md-`bundle_version`-Felder sowie `bundle.json`/`manifest.json` standen noch auf 0.19.4. Mit diesem Release per `bump_bundle_version.py` auf 0.21.0 gezogen (35 Touches).

### Nicht durchgeführt (Backlog)

- **AP2 (trigger_enforcer `codex: false → true`):** Drei echte `codex exec`-Läufe (CLI 0.137.0, gpt-5.5) haben bewiesen, dass `codex exec` repo-lokale `.codex/config.toml`-Hooks nicht ausführt — weder UserPromptSubmit noch SessionStart. Hook-Firing ist headless prinzipiell nicht verifizierbar; das grüne Live-Test-Gate vor dem Flip ist damit nur interaktiv (Desktop-App/TUI) erreichbar. Diagnose in `CODEX-COMPATIBILITY.md` §7. Offene Baustellen der AP2-Mini-Welle: Output-Format-Fix von `trigger_enforcer.py` auf `hookSpecificOutput`-Dual-Output, interaktiver Codex-Test, Input-Schema-Abgleich.

### Bilanz

- pytest **507 passed**, Umlaut-Hartwand grün.

## [0.20.0] — 2026-06-07 — Profil-Vorlagen-Pilot (`beratung`) + deterministische PARA-Materialisierung

Erste Welle des Profil-Ausbaus: Das bereits deklarierte, aber leere Theme-Profil `beratung` bekommt echten, differenzierten Inhalt und wird zur Blaupause für die übrigen fünf Profile. Zusätzlich wandert die PARA-Materialisierung beim Setup von agent-interpretierter Handarbeit (INSTALL.md Phase 2) auf einen deterministischen Subcommand — eine Robustheits-Verbesserung für jede Installation, nicht nur für `beratung`.

### Hinzugefügt

- **`.templates/beratung/`** als erstes inhaltlich gefülltes Profil: eigener AGENTS.md-Einnord-Block (Profil-Fokus Beratung, Marker `<USER_NAME>`/`<USER_INTRO>` erhalten), `CLAUDE.md`/`INDEX.md` byte-identisch zu `default/`, PARA-Skelett plus drei Starter-Notizen mit gültigem Pflicht-Frontmatter und Wikilinks: `00 Kontext/Beratungsangebot.md`, `02 Projekte/_Mandat-Vorlage.md`, `03 Bereiche/Akquise.md`.
- **`sync.py` Funktion `materialize_profile_tree()` plus CLI `--setup-para`**: kopiert den kompletten `.templates/<profil>/PARA/`-Baum (Ordner und Dateien) deterministisch und atomar (`.tmp` plus `replace`) ins Vault-Root, mit fail-loud-`ValueError` bei fehlendem PARA-Verzeichnis und `blocked`-Liste statt Überschreiben. Dotfile-sicherer Temp-Name (`<name>.tmp`) gegen Waisen-Artefakte bei Abbruch.
- **`tests/unit/test_profile_beratung.py`** mit 16 Tests (Profil-Existenz, AGENTS.md-Marker plus Profil-Fokus, Byte-Identität CLAUDE/INDEX zu `default`, Starter-Notiz-Frontmatter, `materialize_profile_tree` inklusive echtem `beratung`-Profil mit Umlaut-Pfad `07 Anhänge` und Waisen-`.tmp`-Guard).

### Geändert

- **`INSTALL.md` Phase 2** von manueller PARA-Ordner-Anlage auf `sync.py --setup-para --profile <profil>` umgestellt. Single-Source-Mechanik analog `--setup-root`: deterministisch, atomar, kein Agent-Ermessen. Für Profile ohne Starter-Notizen (`allgemein`, `default`) identisches Ergebnis wie zuvor (zehn PARA-Wurzelordner mit `.gitkeep`).

### Bilanz

- pytest **459 → 475 passed** (+16).
- Live-Lauf `--setup-para --profile beratung` gegen Wegwerf-Vault (Materialisierung plus Idempotenz-BLOCKED) und echtes Bundle-Build verifiziert, dass `.templates/beratung/` inklusive Starter-Notizen und Umlaut-Ordner im ZIP ankommt.
- Setup-Flow-Default unverändert: INSTALL.md Schritt 2 setzt weiterhin `allgemein` ohne Rückfrage; `beratung` ist als Capability verfügbar, die Profil-Auswahl-UX bleibt einer Folge-Welle vorbehalten.

### Bekannte offene Lücken (Folge-Wellen)

- Restliche fünf Profile (`automation`, `business`, `content`, `image`, `karpathy`) inhaltlich füllen — `beratung` ist die Blaupause.
- `manifest.json::theme_profiles.<profil>.templates` ist totes Metadaten (kein Code liest es) und für `beratung` faktisch falsch (`"default"`); entweder nutzbar machen oder entfernen (als Task festgehalten).

## [0.19.6] — 2026-06-06 — Template-Profil-Drift-Hotfix (`--profile allgemein`)

Schließt den Demo-Blocker aus der Bootstrap-Mini-Welle 2026-05-30: Das Bundle deklariert in `manifest.json` das Theme-Profil `allgemein` und INSTALL.md Phase 3 dokumentiert `sync.py --setup-root --profile allgemein`, doch ausgeliefert wurde nur `.templates/default/`. `install_root_files` baut den Template-Pfad direkt aus dem Profilnamen (`.templates/<profil>/`), fand `.templates/allgemein/` nicht und brach mit Exit 1 ab. Für begleitete Installationen (Sarah, künftige Mandate) lief der dokumentierte Pfad damit vor dem ersten Setup-Schritt in die Wand.

### Hinzugefügt

- **`.templates/allgemein/`** als 1:1-Byte-Spiegel von `.templates/default/` (AGENTS.md, CLAUDE.md, INDEX.md, PARA-Skelett mit `.gitkeep`). Fix-Weg A (Spiegel statt Mapping-Auflösung): minimal, MVP-konform (INSTALL.md exponiert im B.1-MVP ausschließlich `allgemein`), und die übrigen sechs noch ungefüllten Profile brechen weiter mit sauberem Exit 1 ab statt still generischen default-Inhalt auszuliefern.
- **Zwei Pin-Tests `tests/unit/test_template_profiles.py`**: `test_allgemein_profil_existiert` und `test_allgemein_ist_byte_identischer_spiegel_von_default` (pinnt Datei-Set plus Byte-Inhalt, schlägt fehl sobald `default/` ohne `allgemein/` driftet — schließt das einzige Manko der Spiegel-Lösung).

### Geändert

- **Drei Migrations-Tests in `tests/unit/test_migrate_v2_vault.py`** (`test_patche_claude_baum_idempotent_ohne_drift`, `test_luecke_b_db_verzeichnis_ohne_dateiname_wird_umgeschrieben`, `test_same_parent_db_dir_ist_no_op_kein_drift_match`) mit `@pytest.mark.skipif(sys.platform != "win32", ...)` markiert. `migrate_v2_vault.py` ist Windows/OneDrive-spezifisches Cutover-Tooling (via `.bundleignore` nicht im Bundle), dessen Pfad-/Drift-Semantik nur auf Windows gültig ist; die drei Tests scheiterten auf dem `macos-latest`-CI-Runner an Windows-Pfad-Asserts und blockierten den Release-Gate (`test`-Job vor `build`). Etabliertes Repo-Muster (vgl. `tests/unit/test_config_loader.py`). Auf Windows laufen alle drei unverändert.

### Bilanz

- pytest **457 → 459 passed** (+2 Profil-Spiegel-Pins).
- **Versionierung:** Bundle-Inhalt-Version kommt wie bei v0.19.5 allein aus dem Tag (`build_bundle.py` patcht `bundle.json`/`manifest.json` in-memory); Source-Felder bleiben unangetastet. Kein Skill-Touch, kein Eval-Diff.
- Privacy-Pin `test_bundle_zip_has_no_private_path_leak` unverändert grün — der Spiegel enthält keine privaten Pfade.

### Bekannte offene Lücken (Folge-Wellen)

- Volle Profil-Schleife für die sechs weiteren Manifest-Profile (`automation`, `beratung`, `business`, `content`, `image`, `karpathy`) erst sinnvoll, wenn die Profile inhaltlich gefüllt sind (eigene Welle).
- Manifest-vs-Bundle-Konsistenz-Lint (build-time) als Backlog.

## [0.19.5] — 2026-05-28 — User-Discovery (Pages-Root-Index + README-Refresh)

Schließt die Brille-γ-HIGH-Lücke aus dem v0.19.4-Drei-Meta-Brillen-Post-Reife-Audit: `bootstrap.lehnisch.de/` (Root-Pfad) lieferte 404 und das README zeigte Stand v0.14.2 mit veralteter 23-Skills-Inventar-Tabelle. Begleitete Installationen (Sarah, Olaf, künftige Beratungs-Mandate) wären vor dem ersten Setup-Schritt gegen die User-Discovery-Wand gelaufen. Welle adressiert das User-Außen-Zahnrad — das Maintainer-Innen-Zahnrad blieb von v0.19.4 unverändert.

### Hinzugefügt

- **`tools/render_index.py`** als neues Maintainer-Skript (225 LOC, Stdlib only, UTF-8 ohne BOM). Rendert Designsystem-konformes `pages_final/index.html` aus Inline-Template — Cream-Page-Hintergrund (`#F8F6F2`), Mona Sans + Inter via Google Fonts, `.gold-dot`-Span am Headline-Ende (kein Buchstaben-Punkt), `.eyebrow`-Label „Agentic Second Brain", Quickstart-curl-Block in `surface.sunken` (`#EFECE5`), `.sig-line`-Teal-Gold-Verlauf, vier Weiterlesen-Links (BOOTSTRAP.md, bundle.zip, SHA-256-Sidecar, CHANGELOG.md, GitHub-Repo). CLI-Args `--tag/--version/--output` mit TAG_RE/VERSION_RE-Validierung und Idempotenz-Check (byte-identische Skips). Tokens verbatim aus `tokens.json` v1.5.0 / `globals.css`.
- **Drei Pin-Tests `tests/unit/test_render_index.py`**: `test_render_index_replaces_placeholders` (Platzhalter-Replacement gegen Subprocess-Call), `test_render_index_carries_designsystem_anchors` (Substrings `class="gold-dot"`, `class="eyebrow"`, `Mona Sans`, `#18273A`, `#F8F6F2`, `#FBF9F5`), `test_render_index_no_forbidden_colors` (kein `#FFFFFF`, kein Tailwind-Slate/Gray/Zinc, kein `Manrope`).

### Geändert

- **`.github/workflows/release.yml` Job `promote` Step „Stage Pages output"** um Render-Block für `pages_final/index.html` erweitert. Version aus `bundle.json::version` (Top-Level, nicht `bundle.version` — Brief-Drift-Korrektur durch Implementer beim Lesen der echten ZIP-internal-Struktur).
- **`README.md` durchgängig auf v0.19.4-Stand gebracht**: Z. 5 Bundle-Version `v0.14.2 → v0.19.4` plus Released-Datum, Z. 9 Skill-Zahl `23 → 31 kuratierte Skills` mit Profil-Liste um `image` (Bild-API-Wrapper) und `beratung` (neue-praesentation) erweitert, Z. 22 Quickstart-URL `v0.14.2 → v0.19.4`, Z. 32 Heading `23 Bundle-Skills → 31 Bundle-Skills`, Tabelle Z. 34-66 alphabetisch aus `manifest.json::skills` regeneriert (alle 31 Zeilen, Aktiv-Spalte gegen `default_active.allgemein` gespiegelt — 15 aktiv plus 16 inaktiv), Z. 84 Architektur-Satz `23 Skills / fünf Theme-Profile → 31 Skills / sieben Theme-Profile`, Status-Block oben zwei kompakte Sammeleinträge `v0.19.5` plus `v0.19.4` vor v0.14.2-Zeile.

### Bilanz

- pytest **378 → 381 passed** (+3 Pins für `tools/render_index.py`).
- Cross-Skill **26/26 PASS** unverändert, Owner-Eval-Suiten **18/18 PASS** unverändert, Stefan-Lock-Drift live **0 Treffer** unverändert.
- Bundle-Skills **31** unverändert (kein neuer Skill, kein Migrations-Touch).
- **Versionierungs-Klarstellung:** Bundle-Inhalt (`manifest.json::version`, `bundle.json::version` im ZIP) bleibt `0.19.4`. Der Tag `v0.19.5` adressiert ausschließlich die Pages-Distribution-Schicht (Root-Index + README-Refresh). Begründung: kein Skill-Touch, kein Eval-Diff, kein Bundle-Bump nötig — wäre Scope-Drift. Konsequenz für User: `bootstrap.lehnisch.de/v0.19.5/bundle.zip` liefert dasselbe Skill-Set wie `v0.19.4/bundle.zip`, plus die neue Pages-Discovery-Schicht.
- **Erster 200 OK auf `bootstrap.lehnisch.de/` Root** seit Bundle-Anfang (vorher durchgängig 404 — Brille-γ-HIGH-Lücke geheilt). `bootstrap.lehnisch.de/v0.19.5/bundle.zip` Live (1.44 MB, SHA-256 via Sidecar verifiziert). CI-Pipeline 4/4 grün (test + build + promote + verify).
- Drift-Wand-Lesson `feedback_brief_ascii_substitute_drift` **24. Bestätigung**: Hauptagent-Selbst-Drift in Initial-Commit-Message (Bash-Hereroc) trotz expliziter Brief-Regel-Wiederholung (`ergaenzt/Schliesst/gamma/brachen`) — vor Push per `git commit --amend` geheilt. Lokal-only-Amend war hier korrekte Heilung (kein Published-Commit).
- Brief-Drift gegen reale Datei-Struktur als neue Spielart: Brief sagte `bundle.json['bundle']['version']` (nested wie in `manifest.json`), real ist Top-Level `bundle.json['version']`. Implementer hat beim Code-Schreiben gegengelesen und korrigiert.

### Bekannte offene Lücken (Folge-Wellen + Backlog, priorisiert)

- **v0.20.0 Codex-Hook-Aktivierung** (Spec eingefroren, vier v0.19.3→v0.19.4-URL-Patches gepatcht). Mit v0.19.5 ist die User-Discovery-Schicht fertig — v0.20.0 ist jetzt Demo-fähig für Sarah/Olaf.
- Backlog unverändert aus v0.19.4 (Multi-Version-Pages-Hosting, GitHub-Actions Node.js 20→24 Deprecation Q3/2026, Bundle-Drift-Reaktions-Routine, Aggregations-Smoke-Test als Komfort-Wrapper).

## [0.19.4] — 2026-05-28 — Setup-Pfad-Reparatur (Hosting + AGENTS-Doppel + UTF-8-Entpack + CI-Reparatur R11)

Pre-Welle zur Codex-Hook-Aktivierungs-Welle v0.20.0. Drei strukturelle Setup-Pfad-Defekte aus Phase A der Codex-Welle 2026-05-28 vor v0.20.0 geschlossen — sonst hätte v0.20.0 Hooks auf defektem Substrat aktiviert. Während Phase D (Hosting) entdeckter Architektur-Befund R11: Release-Workflow seit v0.17.10 (10 Tags) CI-rot wegen Umgebungs-Drift, daher noch nie ein erfolgreicher Pages-Deploy. Welle umfasst Befund-Reparaturen plus CI-Wiederbelebung plus erstem grünem Pages-Deploy seit Bundle-Anfang.

### Hinzugefügt

- **`.bundleignore`-Zeile `/AGENTS.md`** (führender Slash zwingend — `AGENTS.md` ohne Slash würde User-Variante `.templates/default/AGENTS.md` aussperren, Spec §2.2 R3). Schließt Befund 2: Maintainer-Variante landet nicht mehr im Bundle, User-Setup ohne `--force` läuft.
- **Test-Pin `tests/unit/test_bundle_zip_contents.py`** mit Source-Code-Grep-Pin auf `info.flag_bits |= 0x800` in `tools/build_bundle.py` (NICHT ZIP-Inhalt-Pin — tautologisch laut Lesson `brief-drift-gegen-spec.md`). Schützt UTF-8-Flag-Setzung gegen Refactoring-Verlust.
- **uv-stderr-Filter `_filter_uv_noise`** in `tests/unit/test_bundle_version_drift_check.py`. Filtert `Installed N packages in Xms`-Zeilen aus CI-Cache-Miss-Output. R11-Wurzel A.
- **`pytest.mark.skipif`-Modul-Marker** in `tests/unit/test_designsystem_render.py`. Skippt 5 Tests auf Runnern ohne installiertes Playwright. Playwright-Browser-Install in CI ist out-of-scope (würde Cross-Platform-Setup verlangen). R11-Wurzel B.

### Geändert

- **`INSTALL.md` Schritt 9** explizit auf UTF-8-sichere Entpack-Mechanik festgelegt: Python `zipfile.ZipFile.extractall()` als Default, PowerShell `Expand-Archive` und 7z als Alternativen, Git-Bash `unzip` (InfoZIP) explizit verboten. Schließt Befund 3.
- **`INSTALL.md` Phase 3 Klarstellungs-Text** „Tritt in Phase 3 normalerweise nicht auf" auf „Tritt seit Build-Test in v0.19.4 nicht mehr auf" angepasst (Spec §2.2 Schritt 3).
- **`BOOTSTRAP.md` Schritt 2** um Entpack-Hinweis-Block ergänzt: Setup-Agent entpackt via Python `zipfile`, garantiert UTF-8-Sicherheit für `07 Anhänge` mit echtem `ä`.
- **Bundle-Bump v0.19.3 → v0.19.4** über `.maintainer/scripts/bump_bundle_version.py`. Achter Realeinsatz, 35 Touches (31 SKILL.md `bundle_version` + 4 JSON-Felder).
- **Codex-Hook-Aktivierungs-Spec §4 Schritt 2** URL `bootstrap.lehnisch.de/v0.19.3/` → `bootstrap.lehnisch.de/v0.19.4/` gepatcht (Phase G Schritt 1, schließt Spec-Risiko R7).
- **Phase G Schritt 2 (Smoke-Test-Erweiterung um sieben DoD-Sub-Schritte) gestrichen** (Meta-Brille-β-Verdikt nach Welle-Abschluss). Die sieben DoD-Sub-Schritte (a-g) sind durch drei existierende Mechanismen lückenlos redundant abgedeckt: (1) Schritte a+b+c durch `release.yml` verify-Job (curl + SHA-256-Roundtrip-Match gegen Build-Hash, 5-Retry, Issue-Open bei Failure); (2) Schritte d+e+g durch Live-Setup-Vault-Lauf in Phase-A-Substrat-Drift-Check der Implementer-Welle; (3) Schritt f durch Bundle-Skill-Eval-Suite (`run_evals.py vault-gap-analysis` im bestehenden setup_smoke_test.py). Aggregations-Skript ohne semantischen Gewinn, Mock-Fixture-Refactor-Aufwand nicht gerechtfertigt. Spart eine v0.19.5-Mini-Welle. Setup-Pfad-Reparatur-Spec §4 Phase G Schritt 2 entsprechend final gepatcht. Aggregations-Skript bleibt Backlog ohne Welle-Bindung.

### Bilanz

- pytest **378/0** (+2 neue Pins in `tests/unit/test_bundle_zip_contents.py`: (1) Befund-2-Pin `test_bundle_zip_excludes_root_agents_md_but_keeps_template` als ZIP-Inhalt-Assertion via `zipfile.namelist()`; (2) Befund-3-Pin `test_build_bundle_keeps_utf8_flag_line` als Source-Code-Grep auf `info.flag_bits |= 0x800` in `tools/build_bundle.py` — kein ZIP-Inhalt-Pin, weil tautologisch laut Lesson `brief-drift-gegen-spec.md`).
- Cross-Skill **26/26 PASS** unverändert, Owner-Eval-Suiten **18/18 PASS** unverändert, Stefan-Lock-Drift live **0 Treffer** unverändert.
- Bundle-Skills **31** unverändert.
- **Erste erfolgreiche CI-Pipeline seit v0.17.10** (10 Tags zurück). Erster Live-Pages-Deploy auf `bootstrap.lehnisch.de/v0.19.4/bundle.zip` (HTTP 200, SHA-256 verifiziert via Sidecar). DNS + HTTPS-Cert + Pages-Konfig waren intakt — nur das Deploy-Artifact fehlte wegen R11.
- Drift-Wand-Lesson `feedback_brief_ascii_substitute_drift` **23. Bestätigung**: 0 Drifts in 6 Code-Touches plus 2 Spec-Touches plus 4 Doku-Reife-Touches; ein echter Drift (`tatsaechlich`) im Phase-G-Schritt-2-Versuchs-Patch sofort durch `test_no_umlaut_substitutes`-Pin gefangen und per Replace-Pass geheilt.
- Vier-Brillen-Post-Tag-Audit (Z Wirkung / E Doku-Konsistenz / D Drift / B Reife) durchlaufen.

### Bekannte offene Lücken (Folge-Wellen + Backlog, priorisiert)

- **v0.19.5 User-Discovery — `pages_final/index.html` + README-Refresh** (Brille-γ HIGH, vor v0.20.0 empfohlen). `https://bootstrap.lehnisch.de/` (Root) liefert 404, README zeigt v0.14.2-Stand mit veralteter Skill-Inventar-Tabelle. Bricht „begleitete Installationen Sarah/Olaf" vor erstem Setup-Schritt. Aufwand 45-60 min, kein Stefan-Hands-On. Siehe FOLGE-WELLEN-ROADMAP-v0.19.5-Zeile.
- **Multi-Version-Pages-Hosting** (Brille-γ MED + Brille-β EINFACHER-MOEGLICH). Nach v0.20.0-Tag-Push überschreibt `actions/upload-pages-artifact@v4` das Pages-Verzeichnis komplett — `bootstrap.lehnisch.de/v0.19.4/bundle.zip` geht offline. Bricht User-Vault-Recovery und `bundle_version_drift_check`-Heilungspfad bei langsam migrierenden Beratungs-Mandaten. Realistisch erst Pflicht, wenn mehrere User-Vaults im Feld sind. Lösung: gh-pages-Branch-Checkout vor Stage-Step oder GitHub-Release-Assets als versionierter Archive-Mechanismus. Eigene Backlog-Welle.
- **GitHub-Actions Node.js 20 Deprecation** (Force-Upgrade ab Juni 2026 auf Node 24). Backlog für eigene CI-Wartungs-Welle vor Juni 2026.
- **Bundle-Drift-Reaktions-Routine im Stefan-Vault** (Brille-γ LOW). `bundle_version_drift_check`-Hook feuert bei Drift, aber Vault-seitige Routine unter `08 Systemsteuerung/Routinen/` zur Heilung fehlt. Mini-Touch im v0.20.0-Backlog.
- **Stefan-Lock-Liste 00-Index** (Brille-γ LOW). Stefan-Locks aktuell verstreut in Lessons-Topic-Bodies, keine zentrale numerierte 1-N-Liste. R11 hätte Stefan-Lock 15 ausgelöst.
- **Quirk 13 thematisch nach `INSTALL.md` umziehen** (Brille-β UEBER-ENGINEERING). CODEX-COMPATIBILITY.md Quirk 13 ist generisches Windows-Setup-Verhalten ohne Codex-Spezifik. Kosmetisch, kein Block.
- **uv-Noise-Inhalts-Check statt Regex** (Brille-β EINFACHER-MOEGLICH). Aktueller `_filter_uv_noise`-Regex braucht Wartung bei neuen uv-Output-Varianten. Inhalts-Check (`"warning"/"error" not in err`) wäre robuster gegen künftigen Tool-Output-Drift. Opportunistischer Fix bei nächstem Touch der Test-Datei.

## [0.19.3] — 2026-05-27 — AGENTS.md-Operationalisierung Slice 3 — Installer-Phase-3 Code-Backend

Dritte der drei strukturellen Aktivierungs-Lücken aus Wave K im AGENTS.md-Strang geschlossen. `INSTALL.md` Phase 3 ist nicht mehr reine LLM-Agent-Anweisung, sondern ein deterministischer `sync.py`-Subcommand. Externe User-Vaults bekommen AGENTS.md / CLAUDE.md / INDEX.md beim Setup jetzt durch mechanischen CLI-Aufruf, nicht durch manuelle Setup-Agent-Aktion. Slice 4 (CLAUDE.md-Stub-Konversion) und Architektur-Design.md-Spec-Update zu `TaskNotes/` bleiben als eigene Folge-Wellen offen.

### Hinzugefügt

- **`install_root_files(vault, profile, answers, force=False)` in `.skills/sync.py`** — neue Funktion, schreibt AGENTS.md / CLAUDE.md / INDEX.md aus `vault/.templates/<profile>/` ins Vault-Root. Substituiert `<USER_NAME>` und `<USER_INTRO>` ausschließlich in AGENTS.md; CLAUDE.md und INDEX.md werden byte-identisch zum Template kopiert. Atomarer Write via `.tmp` + `replace` (analog `sync-state.json`-Pattern). Idempotenz-Block bei existierenden Zieldateien ohne `--force`. Raise `ValueError` bei fehlendem Template-Verzeichnis, fehlender Template-Datei, fehlendem Pflicht-Marker (`<USER_NAME>` / `<USER_INTRO>`) oder fehlender Antwort (`USER_NAME` / `USER_INTRO`) — fail-loud statt stille Fehl-Substitution.
- **Neuer CLI-Subcommand `sync.py --setup-root`** in `main()`. Pflicht-Flags: `--profile <name>`, `--answers <pfad-zu-json>`. Erwartetes Antwort-JSON-Schema: `{"USER_NAME": "...", "USER_INTRO": "..."}`. Exit-Code-Konvention: 0 bei Erfolg (Stdout `setup-root: written=[...]`), 1 bei Spec-Verstoß (`ValueError`-Pfade: fehlende Flags, kaputte JSON, fehlende Pflicht-Felder, fehlende Marker), 2 bei BLOCK durch existierende Zieldatei ohne `--force` (analog `sync`-BLOCK-Konvention).
- **Neue Test-Datei `tests/unit/test_sync_setup_root.py`** mit 7 Pin-Tests: Substitution greift, fehlender Marker raise, fehlende Antwort raise, doppelter Aufruf blockt, `--force` überschreibt, keine `.tmp`-Reste nach Erfolg, nicht-existentes Profil raise. pytest steigt damit auf **376/0** (+7 neue Pins).

### Geändert

- **`INSTALL.md` Phase 3** umgeschrieben von „Lies die Templates und schreibe die gefüllten Versionen" (LLM-Agent-Anweisung) auf konkreten CLI-Aufruf `uv run .tmp_install/.skills/sync.py --setup-root …`. Setup-Agent legt vorher `.tmp_install/.docs/answers.json` an. Erwartete Stdout-Zeile und Fehler-Exit-Codes explizit dokumentiert, damit Codex und Claude Code die Fehlerfälle ohne Re-Read der Funktion einordnen können.
- **`.maintainer/docs/CODEX-COMPATIBILITY.md` §5.1** als Slice 3 erledigt markiert. Slice 4 bleibt als einzige offene AGENTS.md-Operationalisierungs-Lücke vermerkt.
- **`.maintainer/docs/FOLGE-WELLEN-ROADMAP.md`** Slice-3-Zeile auf erledigt, neue v0.19.3-Zeile chronologisch eingereiht.
- **Bundle-Bump v0.19.2 → v0.19.3** über `.maintainer/scripts/bump_bundle_version.py`. Siebter Realeinsatz.

### Bilanz

- pytest **376/0** (+7 neue Pins), Cross-Skill **26/26 PASS** unverändert, Owner-Eval-Suiten **18/18 PASS** unverändert, Stefan-Lock-Drift **0 Treffer** unverändert.
- Bundle-Skills **31** unverändert (sync.py-Erweiterung ist kein neuer Skill, sondern ein Subcommand auf dem bestehenden Setup-Tool).
- Drift-Wand-pytest grün — `feedback_brief_ascii_substitute_drift` **19. Bestätigung**.

### Bekannte offene Lücken (eigene Folge-Wellen)

- **Slice 4 — CLAUDE.md-Stub-Konversion in Stefans Vault** (~0,3-0,5 M): unverändert offen.
- **Architektur-Design.md TaskNotes-Spec-Update**: in dieser Welle bereits in Stefans Vault-Datei erledigt (Vault-Realität gewinnt, `01 TaskNotes/` → `TaskNotes/`), Sektion 4 und Sektion 16 Eintrag 4 sind angepasst.
- **Vault↔Template-Body-Identität**: weiter Slice-4-Backlog.

## [0.19.2] — 2026-05-27 — AGENTS.md-Operationalisierung Slice 1+2 (Wave-K-Folge)

Zweite der drei strukturellen Aktivierungs-Lücken aus Wave K teilweise geschlossen: Bundle-Maintainer-Repo und Stefans Produktiv-Vault haben jetzt eine Root-`AGENTS.md`. CLAUDE.md bleibt in beiden Welten unangetastet — die formale Stub-Konversion ist explizit Slice 4 und Folge-Welle. Sub-Projekt-A-Vision „AGENTS.md als Single Source of Truth, CLAUDE.md als Stub" ist damit zur Hälfte operationalisiert (zwei AGENTS.md-Dateien existieren, CLAUDE.md ist noch nicht zum Stub konvertiert).

### Hinzugefügt

- **`AGENTS.md` am Repo-Root des Bundle-Maintainer-Repo** als tool-neutrale Maintainer-Disziplin-Datei. Inhalt: Quell-Repo-Selbstverortung, Projektziel als Erinnerung, Wellen-Disziplin (Spec-First, Critic-Pass, Pre/Post-Tag-Brillen, Stop-Schwellen), Bump-Skript-Aufruf, Endlosschleifen-Wand, Drift-Wand-Disziplin, Token-Effizienz, Verweise auf zentrale Maintainer-Docs (`CODEX-COMPATIBILITY.md`, `FOLGE-WELLEN-ROADMAP.md`, `BUNDLE-MODE-READINESS.md`, `PATTERNS/MULTI-ACHSEN-AUDIT.md`, `BOOTSTRAP.md`, `INSTALL.md`). Index-Stil, kein Wissens-Klon. Frontmatter mit `agent_ready: true`. Wird von Claude Code und OpenAI Codex gleichermassen gelesen.
- **`AGENTS.md` am Root von Stefans Produktiv-Vault** (`C:\Users\stefa\OneDrive\03 Resources\00_MySecondBrain_Obsidian\AGENTS.md`) als tool-neutrale Source-of-Truth für die Vault-Regeln. Inhalt aus `.templates/default/AGENTS.md` mit Substitution `<USER_NAME>` → „Stefan Lehnischs Vault" und `<USER_INTRO>` → Drei-Satz-Destillat aus `00 Kontext/Über mich.md` (Finance-Leader, Karpathy-Methoden, Spec-First-Disziplin). Header-Hinweis-Absatz erklärt das Verhältnis zu CLAUDE.md (AGENTS.md SSoT bei Konflikten, CLAUDE.md ergänzt CC-spezifika). Frontmatter mit `agent_ready: true`.
- **Neuer pytest-Test `test_repo_root_agents_md_exists_and_points_to_template`** in `tests/unit/test_agents_md_consistency.py`. Prüft (1) Existenz `AGENTS.md` am Repo-Root und (2) Verweis auf `.templates/default/AGENTS.md` als User-Vault-Variante (Verweis-Pin gegen versehentliche Inhalts-Duplikation). pytest steigt damit auf **369/0** (vorher 368).

### Geändert

- **`.templates/default/AGENTS.md` Z. 15 + Z. 24** (Bundle-Template): `TaskNotes/` ohne `01`-Präfix (Vault-Realität gewinnt — Stefan-Klärung in dieser Welle). Vault-Wurzel-Sauber-Regel um `TaskNotes/` ergänzt. Schließt eine Pfad-Inkonsistenz zwischen Spec/Template und Realität, die der Critic-Subagent als Architektur-Befund aufgedeckt hatte. Architektur-Design.md-Spec-Update (sie listet weiterhin `01 TaskNotes/`) steht als eigene Folge-Welle aus.
- **`.maintainer/docs/CODEX-COMPATIBILITY.md` §5.1** als Slice-1+2-erledigt markiert, Slice 3 + Slice 4 als weiterhin offen vermerkt.
- **`.maintainer/docs/BUNDLE-MODE-READINESS.md`** Aktivierungs-Lücken-Bilanz auf 2 von 3 (zu Slice-1+2-Tiefe).
- **`.maintainer/docs/FOLGE-WELLEN-ROADMAP.md`**: Slice 1+2 als erledigt, Slice 3 und Slice 4 als eigene Folge-Wellen mit Token-Korridor eingetragen.
- **Bundle-Bump v0.19.1 → v0.19.2** über `.maintainer/scripts/bump_bundle_version.py`. Sechster Realeinsatz.

### Schiedsrichter-Bilanz (Memory-Lesson `feedback_schiedsrichter_brillen_false_positive_pflicht` 7. Bestätigung)

Critic-Subagent meldete 3 HIGH + 4 MED + 3 LOW. Schiedsrichter-Verifikation: 1 von 3 HIGH war False Positive (V-1: behaupteter Stub-Alias auf `[[CLAUDE]]` existiert in der Datei nicht). 4 In-Scope-Fixes angewendet (Memory-Lesson-Verweis aus Maintainer-Repo raus, Snapshot-Zahlen raus mit Verweis auf CHANGELOG, User-Vault-Variante-Sektion konsolidiert, §5.1-Status-Vermerk ergänzt). 3 Befunde als Slice-3/4/Folge-Welle-Backlog dokumentiert.

### Bilanz

- pytest **369/0** (+1 neuer Test), Cross-Skill **26/26 PASS** unverändert, Owner-Eval-Suiten **18/18 PASS** unverändert, Stefan-Lock-Drift **0 Treffer** unverändert.
- Bundle-Skills **31** unverändert.
- Drift-Wand-pytest grün — `feedback_brief_ascii_substitute_drift` **18. Bestätigung** (kein Selbst-Drift in dieser Welle nach den zwei Lernfällen in v0.19.1 + Hook-Stub-Probe-Bereinigung).
- Realer Token-Verbrauch: ~0,2 M (Spec-Korridor war 0,15-0,25 M, getroffen).

### Bekannte offene Lücken (eigene Folge-Wellen)

- **Slice 3 — Installer-Phase-3 Code-Backend** (~0,2-0,4 M): `INSTALL.md` Phase 3 ist Doku, Code fehlt. Externe User-Vaults bekommen AGENTS.md beim Setup nur durch manuelle Setup-Agent-Aktion.
- **Slice 4 — CLAUDE.md-Stub-Konversion in Stefans Vault** (~0,3-0,5 M): Löst latente Drift-Gefahr CLAUDE↔AGENTS (beide am selben Vault-Root, AGENTS.md sagt „bei Konflikten gilt AGENTS.md", CLAUDE.md sagt das nicht).
- **Vault↔Template-Body-Identität**: Stefan-Vault-AGENTS.md und `.templates/default/AGENTS.md` sind im Body byte-identisch. Bei Template-Änderungen muss die Vault-Datei manuell nachgezogen werden — Backlog für Slice-4-Welle oder eine eigene Sync-Routine.
- **Architektur-Design.md** im Stefan-Vault listet weiterhin `01 TaskNotes/`. Eigene Folge-Welle (Spec-Update gegen Vault-Realität).

### Geändert (Maintainer-Cleanup, kein Tag, post v0.19.1, 2026-05-27)

- **`.claude/settings.json` aus dem lokalen Maintainer-Workspace entfernt.** Die Datei enthielt nur einen PreToolUse-Test-Stub mit Verweis auf `python tools/hook_payload_probe.py`, die Probe-Datei existierte nie. Befund aus Wave K: `.claude/` ist via `.gitignore` Z. 29 grundsätzlich ausgeschlossen, die Stub-Datei war also nie im Repo tracked — sie existierte ausschließlich auf Stefans lokalem Maintainer-Workspace und konnte dort einen Hook auf nicht-existente Probe triggern. Frische Clones bekommen die Datei seit jeher nicht. Wave-K-Folge-Welle „Hook-Stub-Probe-Bereinigung" damit erledigt; Maintainer-Repo trägt explizit keinen produktiv-aktivierten Hook-Zustand mehr — konsistent mit Sub-Projekt-A-Vision (Maintainer-Repo = Quell-Repo, kein User-Vault; echte Hook-Wirkung entsteht erst beim User-Vault-Setup via `sync.py`).
- **`.maintainer/docs/CODEX-COMPATIBILITY.md`** Quirk 12 und §5.3 aktualisiert (Stub entfernt statt „existiert nicht").
- **`.maintainer/docs/BUNDLE-MODE-READINESS.md`** Aktivierungs-Lücken-Zeile aktualisiert: 1 von 3 erledigt, AGENTS.md + Codex-Hook-Aktivierung weiter offen.
- **`.maintainer/docs/FOLGE-WELLEN-ROADMAP.md`** Zeile für Hook-Stub-Probe-Bereinigung auf erledigt.
- Kein Bundle-Skill-Diff, kein Version-Bump, kein Tag. Reiner Maintainer-Cleanup.

## [0.19.1] — 2026-05-27 — Profile-Drift-Fix (Wave-K-Post-Tag-Reife-Patch)

Mini-Welle als Reife-Patch auf den Hot-Backlog-Befund der Post-Tag-Brille Z aus Wave K: `bundle.json::profiles` listete sechs Profile, `manifest.json::theme_profiles` führte sieben (zusätzlich `karpathy`). Ein Installer, der `bundle.json::profiles` als kanonische Liste nimmt, hätte fünf `karpathy`-default-active-Skills (`auditor`, `curator`, `reflector`, `session-log`, `vault-gap-analysis`) ignoriert. Wave-J-Erbe-Drift, durch Wave-K-Audit aufgedeckt, in Wave K bewusst nicht mitgenommen (Scope-Disziplin: Wave K = Verifikations-Welle). v0.19.1 schließt den Drift und installiert eine permanente Pin-Test-Wand gegen Wiederholung.

### Hinzugefügt

- **`.skills/_cross_skill_evals/run_bundle_profiles_consistency_eval.py`** als neue Cross-Skill-Eval-Suite mit einer Assertion `bundle_profiles_match_manifest_theme_profiles`: `set(bundle.json::profiles) == set(manifest.json::theme_profiles.keys())`. Eigene Suite statt Anhang an `run_audit_bundle_fingerprint_eval.py` (dort thematisch `neue-praesentation`-fokussiert). Cross-Skill-Suite-Anzahl steigt damit auf sechs (Wave-J-Backlog B7 — Schwellenwert-Diskussion bleibt offen).

### Geändert

- **`bundle.json` Z. 9-16**: Profil-Liste um `"karpathy"` ergänzt, alphabetisch nach `"image"`. Jetzt sieben Profile (`allgemein`, `automation`, `beratung`, `business`, `content`, `image`, `karpathy`), kongruent mit `manifest.json::theme_profiles.keys()`.
- **Bundle-Bump v0.19.0 → v0.19.1** über `.maintainer/scripts/bump_bundle_version.py`. Fünfter Realeinsatz des Bump-Skripts.

### Bilanz

- pytest unverändert, Cross-Skill **26/26 PASS** (5 Bestandssuiten + neue Profile-Konsistenz-Suite), Owner-Eval-Suiten **18/18 PASS** unverändert.
- Drift-Wand-pytest direkt nach jedem Write grün — `feedback_brief_ascii_substitute_drift` **17. Bestätigung** (einmaliger Replace-Pass im neuen Suite-Docstring nötig, `waehrend` → `während`; gezielt statt Komplett-Rewrite).
- Bundle-Skills **31** unverändert.

## [0.19.0] — 2026-05-27 — Wave K: Codex-Erstkontakt (Sub-Projekt E)

Verifikations-Welle, kein Skill-Bau, keine Skill-Inhalts-Änderung. Sub-Projekt E aus dem Steckbrief geschlossen. Live-Verifikation des Bundle-Stands `v0.18.1` unter OpenAI Codex (Desktop-App auf Windows 11, Modell „5.5 Hoch") mit Stefan an der Tastatur. Slots K-0 bis K-7 plus Post-Tag-Vier-Brillen-Audit auf zwei Sessions aufgeteilt: Session 1 trug die Live-Phase (Setup, AGENTS.md-Discovery, decomplex-Funktions-Test, Hook-Verhaltens-Test), Session 2 trug die Doku-Phase (Lessons + Bundle-Doku + Critic-Pass + Reife-Fixes + Doku-Touches + Bump + Tag + Post-Tag-Audit).

### Hinzugefügt

- **`.maintainer/docs/CODEX-COMPATIBILITY.md`** als nüchterne Maintainer-Referenz mit §1 Codex-Setup-Konventionen, §2 Discovery-Verhalten (inkl. acht-Zeiliger Befund-Tabelle für AGENTS.md plus sieben Hooks mit präzisen `hook.yaml`-Zeilenrange-Belegen), §3 Hook-Aktivierungs-Status (`tool_support.codex`-Flag-Position pro Hook), §4 Kurz-Liste der zwölf Quirks, §5 Migrations-Pfad für Folge-Wellen (AGENTS.md-Operationalisierung, pro-Hook-Aktivierung, Hook-Stub-Probe-Bereinigung).
- **`.maintainer/docs/V0.19.0-WAVE-K-CODEX-SPEC.md`** (Spec v3 nach Sonnet-Critic-Pass auf v1+v2) als Welle-Spec mit Slot-Tabelle, Stop-Schwellen, Pre-/Post-Tag-Brillen-Plan, Test-Plan für `decomplex`-Funktions-Test.
- **`.maintainer/docs/V0.19.0-WAVE-K-K3-K4-BEFUNDE.md`** als Roh-Material-Sicherung aus Session 1: zwölf Codex-Verhaltens-Quirks (C-Q1 bis C-Q12), drei Architektur-Befunde (AGENTS.md-SSoT-Lücke, `tool_support.codex` by-design false, Maintainer-Repo nicht produktiv), vier UI-Beobachtungen, vier Tool-Trace-Auszüge verbatim, DoD-Bilanz K-0 bis K-4. Quelle für die Lessons-Destillation in Session 2.
- **`02 Projekte/Second Brain Installationspaket/Lessons/codex-erstkontakt-quirks.md`** (Stefan-Vault) als handlungsorientierte Lesson-Topic-Datei mit fünf Wenn-Dann-Blöcken (Vor jeder Codex-Session, Skill-Ausführung mit Pfad-Verweis, Hook-Aktivierungs-Vorbereitung, AGENTS.md-Aktivierung, Codex als Hook-Architektur-Audit-Tool).

### Erkenntnisse (DoD-Bilanz)

- **Codex tut kein Auto-Discovery von Bundle-Skills.** Klassische deutsche Trigger-Wörter ohne expliziten Pfad-Verweis lösen `decomplex` nicht aus (Quellen-Panel leer, null Tool-Calls). Mit Pfad-Verweis `.skills/decomplex/SKILL.md` läuft der Skill lehrbuchmäßig (Tool-Trace `Get-Content` in 8 s, Drei-Teile-Struktur, drei der fünf Kernregeln voll plus eine halb).
- **AGENTS.md liegt nirgendwo am Root.** Weder Bundle-Maintainer-Repo noch Stefan-Produktiv-Vault tragen die Datei. Sub-Projekt-A-Vision (AGENTS.md als Cross-Tool-Single-Source-of-Truth) ist konzeptionell konsistent, operativ nicht aktiviert.
- **`tool_support.codex: false` für alle sieben Hooks by-design.** Flag liegt in `.skills/<hook>/hook.yaml` (Z. 6-8 in fünf Hooks, Z. 7-9 in `frontmatter_validator`, Z. 14-16 in `wikilink_validator` wegen `exempt_types`-Block), nicht in `manifest.json`. Codex versteht die Hook-Architektur auf Aufforderung vollständig (29 Tool-Calls in 1 m 19 s, korrekte Hook-Tabelle inkl. Aggregations-Mechanik aus `sync.py`).
- **K-3-DoD-Caveat:** Spec verlangte mindestens 2 von 3 Test-Prompts mit Skill-Aktivierung. Real gefahren: 1 von 3 (Prompt #1 ohne Pfad: 0/2 DoD-Kriterien, Prompt #1.5 mit Pfad: 2/2 DoD-Kriterien). Prompts #2 + #3 nicht gefahren — Hypothese „Codex tut kein Auto-Discovery, kann aber bei Pfad-Verweis voll" strukturell belegt, weiteres Probieren hätte keine neue Information geliefert. Fallback-Klausel aus Spec §1.3 Punkt 2 („Lessons-Doku §1.1 Punkt 5 trägt die DoD allein") greift; `codex-erstkontakt-quirks.md` + `CODEX-COMPATIBILITY.md` tragen den DoD.

### Architektur-Lücken-Bilanz

Drei Lücken zwischen Sub-Projekt-A-Vision und Bundle-Stand identifiziert, **nicht** in Wave K aktiviert (Scope-Disziplin):

1. AGENTS.md-Operationalisierung: keine Root-Datei im Maintainer-Repo, keine im Stefan-Vault — Folge-Welle v0.19.x.
2. Codex-Hook-Aktivierung: alle sieben Hooks `codex: false` — Folge-Welle v0.19.x mit pro-Hook-Live-Verifikation, PowerShell-Kompatibilität, `.codex/config.toml`-Generierungs-Test.
3. Hook-Stub-Probe-Bereinigung: `.claude/settings.json` im Maintainer-Repo zeigt auf `tools/hook_payload_probe.py`, die Datei existiert nicht — Cleanup-Mikro-Welle.

### Geändert

- **`.skills/_cross_skill_evals/run_audit_bundle_fingerprint_eval.py`** Z. 111-115: Pin `neue_praesentation_referenced_in_manifest_json` akzeptiert jetzt zusätzlich `0.19.x` (vorher hardcoded `0.17.x`/`0.18.x`). Stop-Schwelle-6-Trigger nach Bump auf v0.19.0 (Pin schlug vor Fix mit „bundle.version nicht aus 0.17.x oder 0.18.x" fehl). Minimal-Fix in Wave-K-Scope, Architektur-Generalisierung (SemVer-Format-Check statt Minor-Range) ins v0.19.x-Backlog vermerkt.
- **Bundle-Bump v0.18.1 → v0.19.0** über `.maintainer/scripts/bump_bundle_version.py`: 35 Touches (31 SKILL.md `bundle_version` + 4 JSON-Felder in `bundle.json` + `manifest.json::bundle`). Vierter Realeinsatz des Bump-Skripts. Pre-Bump-Gate Cross-Skill 25/25 grün, Post-Bump-Verifikation 25/25 grün nach Pin-Fix.

### Bilanz

- pytest **368/0** unverändert.
- Cross-Skill **25/25 PASS** nach Pin-Fix (5 Suiten unverändert).
- Owner-Evals **15/15 + 3/3 = 18/18 PASS** unverändert.
- Stefan-Lock-Drift live **0 Treffer** unverändert.
- Bundle-Skills **31** unverändert (keine Skill-Migration, keine Skill-Inhalts-Änderung).
- Memory-Lesson `feedback_subagent_token_budget_realistisch_30_50_prozent` **22. Bestätigung** (Sonnet-Critic-Pässe Session 2 ~55 + 58 K vs. Brief-Korridor 70-110 K — sauber unter Brief).
- Memory-Lesson `feedback_schiedsrichter_verifiziert_brille_befund` **9. Bestätigung** (CRIT-Befund Lessons-Datei „BLUF-Kurzfassung als Kernregel" via Disk-Read der SKILL.md Z. 96-102 verifiziert, Critic-Befund war korrekt).
- Memory-Lesson `feedback_brief_ascii_substitute_drift` **16. Bestätigung** (Drift-Wand-pytest direkt nach beiden Writes grün, kein Heilungs-Pass nötig).

## [0.18.1] — 2026-05-27 — Wave J Reife-Patch: Bundle-Integrität (Manifest-Vollständigkeit) + Doku-Drift

Reife-Patch nach Post-Tag-Vier-Brillen-Audit auf v0.18.0. **Brille Z CRIT (Z1):** `manifest.json::skills` enthielt nur 29 Einträge — `elevenlabs-api` und `video-creator` waren als SKILL.md vorhanden, aber im Manifest nicht registriert. Konsequenz: Bundle-Reader-Installer hätte die zwei neuen Skills nicht erkannt. **Brille B HIGH/MED:** `_lib/api_keys.py::get_elevenlabs_key`-Docstring trug noch `TODO(wave-j v0.18.0)`-Marker und „Wave-J-Stub"-Formulierung, obwohl WJ-3 + WJ-5 die Konsumenten angeschlossen haben. **Brille D MED-Konvergenz:** Datums-Drift CHANGELOG/ROADMAP/Steckbrief auf `2026-05-24` (Implementer-Phase), während `bundle.json::released` + `manifest.json::bundle.released` korrekt `2026-05-27` tragen (tatsächlicher Bump- und Tag-Tag).

### Hinzugefügt

- **`manifest.json::skills::elevenlabs-api`** (alphabetisch zwischen `decomplex` und `getmyinvoices`): `scope: anwender`, `bundle_skill: true`, `default_active.content: true` + `automation: true`, `depends_on: []`, neun Trigger-Wörter (`elevenlabs`, `tts`, `voiceover`, `scribe`, etc.). Closes Brille Z Z1 für elevenlabs-api.
- **`manifest.json::skills::video-creator`** (alphabetisch nach `vault-gap-analysis`): `scope: vault`, `bundle_skill: true`, `default_active.content: true`, `depends_on: [elevenlabs-api, nano-banana-image, natur-sprech-check]`, acht Trigger-Wörter. Closes Brille Z Z1 für video-creator.

### Geändert

- **`_lib/api_keys.py::get_elevenlabs_key`** Docstring: TODO entfernt, „Wave-J-Stub" → „Konsumiert von elevenlabs-api (seit v0.18.0)" mit Hinweis auf direkten Wrapper `find_api_key.py` + transitive `generate_tts.py`/`generate_scribe.py` + Negativ-Pin für `generate_music.py`-Stub. Modul-Docstring Z. 30-33 „Wave-J-erwartete Konsumenten (v0.18.0)" → „Wave-J-Konsumenten (seit v0.18.0)" (Past tense statt prospektiv).
- **`bump_bundle_version.py`** Docstring Z. 12 `(29 Files)` → `(31 Files seit Wave J v0.18.0)`.
- **`CHANGELOG.md`** + **`FOLGE-WELLEN-ROADMAP.md`** + Vault-Steckbrief: Datums-Drift `2026-05-24` → `2026-05-27` für v0.18.0-Release-Tag (Implementer-Phase blieb `2026-05-24`).
- **`FOLGE-WELLEN-ROADMAP.md`** v0.18.0-Zeile-Status: „Implementer-Phase erledigt 2026-05-24, Tag offen" → „erledigt 2026-05-27".
- **`FOLGE-WELLEN-ROADMAP.md`** v0.19.0-Zeile (in v0.18.0 frisch eingefügt): `elevenlabs-api/run_evals.py`-Umbau-Touch explizit ergänzt (`elevenlabs_api_music_stub_existence` → `elevenlabs_api_music_call_existence` als Positiv-Pin).

### Bilanz

- pytest **368/0** unverändert.
- Cross-Skill **25/25 PASS** unverändert (5 Suiten).
- Owner-Evals **15/15 + 3/3 = 18/18 PASS** unverändert.
- Stefan-Lock-Drift live **0 Treffer** unverändert.
- Bundle-Skills **31 effektiv + 31 im Manifest** (vorher 29 im Manifest = Drift).
- Memory-Lesson `feedback_hauptagent_schiedsrichter_revidiert_verdict` **2. praktische Anwendung** (Reife-Patch nach Audit-CRIT-Substanz, kein eigenmächtiger Scope-Drift).

### Backlog v0.19.0 / Wave-K

Aus Post-Tag-Audit Brille B (Blinde Flecken) verschoben statt sofort gefixt:
- B6: `BUENDEL_J_PRIVATE_PATTERNS_ELEVENLABS_API`-Docstring-Maintainer-Hinweis bei SKILL.md-Content-Touch.
- B2: CRLF/BOM/Trailing-Newline-Drift-Wand für SKILL.md-Frontmatter.
- B8: `sys.path`-Header-Drift-Wand für `_lib`-Konsumenten.
- B5: Voice-ID-Stabilitäts-Smoke-Test gegen `GET /v1/voices/{id}` (Live-API).
- B4: `authentic-portrait`-Bundle-Status formell entscheiden.
- B7: Cross-Skill-Suite-Anzahl-Schwellenwert in ROADMAP.
- B10: tote Wikilinks auf `.maintainer/docs/*` im Bundle (V0.17.11-Spec-Verweis in elevenlabs-api/SKILL.md).
- A-MED (Pre-Tag): pytest-Pin für `BUENDEL_J_PRIVATE_PATTERNS_ELEVENLABS_API` `list[str]`-Typ-Check.

## [0.18.0] — 2026-05-27 — Wave J: Co-Migration video-creator + elevenlabs-api

Erste Co-Migration des Bundles. Beide Wave-J-Skills werden gleichzeitig integriert: `elevenlabs-api` als Neubau (Bundle-Skill mit eigener `run_evals.py`, drei references-Dateien, fünf scripts, eigenem assets-Ordner), `video-creator` als Migration (10-Sub-Skill-Orchestrator mit 22 Stefan-Lock-Patterns aus v0.17.9). Bundle-Skills **29 → 31**. HARD-LOCKs §8.1 (Music-Endpoint = Stub Phase 1, Vollausbau v0.19.0) und §8.2 (Voice-ID = nur Premade via Config, kein Cloning) durch Stefan-Entscheidungen 18+19 geschlossen.

### Hinzugefügt

- **`elevenlabs-api` Bundle-Skill** (Wave-J-Neubau, 14 neue Dateien):
  - `SKILL.md` mit Frontmatter `bundle_version: 0.18.0`, drei Sub-Skill-Naming `elevenlabs-api scribe/tts/music`
  - `skill.config.example.yaml` mit Default-Voice-ID `JBFqnCBsd6RMkjVDRZzb` (George, kuratierte Premade-Voice)
  - `requirements.txt` mit `requests>=2.31`
  - `references/tts.md` + `scribe.md` (aktive Endpoint-Doku) + `music.md` (TBD-Stub für v0.19.0)
  - `scripts/find_api_key.py` (Wrapper auf `_lib/api_keys.get_elevenlabs_key`), `generate_tts.py` (39 LoC), `generate_scribe.py` (40 LoC), `generate_music.py` (Stub mit `NotImplementedError("Music-Pfad: v0.19.0 — Endpoint-Verifikation und Account-Tier-Klärung ausstehend")`), `__init__.py`
  - `eval/elevenlabs-api.eval.json` (4 Cases: tts-/scribe-/music-stub-existence + config-voice-id-default)
  - `assets/.env.example` (`ELEVENLABS_API_KEY=`), `assets/README.md`
  - `run_evals.py` (314 LoC, 15 Assertions inkl. `elevenlabs_api_bundle_stefan_lock_isolation`)
- **`video-creator` Bundle-Skill** (Migration aus Vault, 221 Z. Bundle-SKILL.md):
  - Vault → Bundle 1:1 plus Frontmatter `bundle_version: 0.18.0`, Sub-Skill-Tabelle Z. 60-61 Bundle-Naming, "Stefans Stimme" → "konfigurierbare Voice-ID (Default Premade)"
  - 12 Wikilinks sanitisiert (1 Bucket-(i) `[[linkedin-finalize]]`, 11 Bucket-(ii) Klartext + Vault-Quellen-Anhang)
  - 3 Block-Exclude-Marker (`<!-- bundle-stefan-lock-scan-exclude-start/end -->`): 1× Vault-Quellen-Anhang (WJ-2-Owner) + 2× Personen-Pflicht-Block (Z. 27-45) und Render-Pfad+Engine-Fit+Historie (Z. 103-129) als Hauptagent-Schiedsrichter-Patch nach WJ-4-Befund
  - `run_evals.py` (205 LoC, 3 Assertions inkl. `video_creator_bundle_stefan_lock_isolation` mit Block-Exclude-Regex)
- **`BUENDEL_J_PRIVATE_PATTERNS_ELEVENLABS_API`** in `_lib/test_utils.py` als `list[str]` (0 Patterns, Negativ-Pin gegen künftigen Drift — API-Wrapper hat keine Stefan-privaten Tokens).
- **Wikilink-Sanitisierungs-Inventar** `.maintainer/docs/V0.18.0-WJ-1-WIKILINK-INVENTORY.md` für WJ-2-Owner.

### Aktualisiert

- **`_cross_skill_evals/run_api_keys_consistency_eval.py` (WJ-7):**
  - `EXPECTED_DIRECT_CONSUMERS` 2 → 3 (`elevenlabs-api/scripts/find_api_key.py`)
  - `EXPECTED_TRANSITIVE_CONSUMERS` 1 → 3 (`elevenlabs-api/scripts/generate_tts.py`, `generate_scribe.py`)
  - `generate_music.py` NICHT in der Liste (HARD-LOCK §8.1 Negativ-Pin)
  - Schicht 2 AST-Tree-Scan automatisch erweitert auf 3+3 Treffer
  - `transitive_consumer` Single → `transitive_consumers` Tupel mit Loop
- `bundle_version: 0.18.0` in allen 31 SKILL.md-Frontmattern, `bundle.json`, `manifest.json` (durch Bump-Skript in WJ-Tag-Slot).
- `manifest.json`: `elevenlabs-api` und `video-creator` alphabetisch einsortiert.

### Werte-Bilanz

- **pytest 368/0** in 3 konsekutiven Bulk-Läufen (68-72s, umgebungs-unabhängig).
- **Cross-Skill 25/25 PASS** über 5 Suiten unverändert (`run_api_keys_consistency_eval` weiterhin 8/8 mit erweiterter Konsumenten-Whitelist).
- **2 neue Owner-Eval-Suiten:** `elevenlabs-api/run_evals.py` 15/15 PASS, `video-creator/run_evals.py` 3/3 PASS.
- **Stefan-Lock-Drift live 0 Treffer:** 22 BUENDEL_J_VIDEO_CREATOR-Patterns (nach Block-Exclusion) + 14 BUENDEL_I_NEUE_PRAESENTATION-Patterns + 0 BUENDEL_J_ELEVENLABS_API-Patterns.
- **Bundle-Skills 29 → 31.**
- **Memory-Lesson `feedback_subagent_token_budget_realistisch_30_50_prozent` 19. Bestätigung:** 5 Sonnet-Owner real ~385K von Spec-Schätzung 800-1200K Subtotal (Briefs mit absoluten Pfaden + disjunktem Scope + Pflicht-Sätzen §1 + 6 Stop-Schwellen verbatim).
- **Memory-Lesson `feedback_brief_ascii_substitute_drift` 14. Bestätigung** (kam aus Wave-J-Spec-Bau, Default-Heilungs-Sequenz dokumentiert in `02 Projekte/Second Brain Installationspaket/Lessons/spec-bau-selbst-drift-pattern.md`).

### Spec-Quellen

- `.maintainer/docs/V0.18.0-WAVE-J-SPEC.md` (Spec-v2, 12 §-Sektionen, nach Sonnet-Critic-Pass mit 4 disjunkten Achsen 105K Token, 2 HIGH + 3 MED + 3 LOW eingearbeitet)
- `.maintainer/docs/V0.17.11-WAVE-J-ARCHITECTURE-SPEC.md` (Eingangs-Doku)
- `.maintainer/docs/V0.18.0-WJ-1-WIKILINK-INVENTORY.md` (WJ-1-Inventar)

## [0.17.13] — 2026-05-24 — Post-Tag-Reife-Patch: Test 10 cp1252-Robustheit + CHANGELOG-Header-Heilung + Brillen-MEDs

Post-Tag-Vier-Brillen-Audit für v0.17.12 fand zwei HIGH-Befunde (Test 10 FAIL auf Windows-Hosts ohne `PYTHONUTF8=1` durch cp1252-stderr-Mismatch im subprocess-Reader; CHANGELOG-`## [0.17.11]`-Header durch [0.17.12]-Insert verschluckt) plus mehrere konvergente MEDs. Reife-Patch v0.17.13 schließt beide HIGHs plus die kostengünstigen MEDs vor erstem Wave-J-Implementer-Code-Touch. Memory-Lesson `feedback_hauptagent_schiedsrichter_revidiert_verdict` greift: Post-Tag-Audit-Substanz revidiert frühere Tag-frei-Entscheidung.

### Hinzugefügt
- Keine neuen Slots oder Features.

### Aktualisiert
- **H-1 Test-Robustheit (`tests/unit/test_bump_bundle_version.py`):** `_run`-Helper bekommt `errors="replace"` in `subprocess.run(..., text=True, encoding="utf-8", errors="replace")`. Schützt vor `UnicodeDecodeError` wenn das Bump-Skript bei fehlendem venv eine Fehlermeldung mit Umlauten (`prüfen`, `Notfall-Override`) auf stderr schreibt und der Test-Host ohne `PYTHONUTF8=1` läuft. Test 10 ist damit umgebungs-unabhängig grün.
- **H-2 CHANGELOG-Heading-Heilung:** `## [0.17.11] — 2026-05-23 — Mini-Welle: Wave-J-Architektur-Spec + uv-Linkdir-Reparatur` wieder eingefügt zwischen [0.17.12] und v0.17.11-Inhalt. Keep-a-Changelog-Format konsistent, automatische Versionsparser können 0.17.11 wieder von 0.17.12 abgrenzen.
- **M-1 (Z) CHANGELOG-§-Nummer:** Rückverweis `V0.17.12-Spec §2.5` korrigiert auf `§2.1` (Konsumenten-Tabelle liegt in §2.1, nicht §2.5).
- **D-MED-1 Spec-Werte-Konsistenz:** `V0.17.12-AST-PREBUMP-SPEC.md` §5 DoD: `pytest 365/x` (Formel) → `pytest 365 → 368 passed` (verbatim). Dokumenten-Leser findet 368 jetzt direkt in der Spec.
- **B-M-1 Spec-Test-11-Mechanismus:** `V0.17.12-AST-PREBUMP-SPEC.md` §3.5 Test-11-Beschreibung an Code-Realität angepasst — Mechanismus ist `if not args.apply: return 0` vor Gate-Aufruf, nicht "leeres `_cross_skill_evals/`". Stop-Schwellen-Falsifikation jetzt korrekt beschrieben.
- **E-MED-1 Lessons-Typ-Konsistenz:** Vier v0.17.11-Lessons (`replace-pass-statt-komplett-rewrite.md`, `mindest-15-min-diagnose-vor-welle-abbruch.md`, `git-stash-statt-checkout-welle-rollback.md`, `uv-python-linkdir-segfault-pep-723.md`) von `type: notiz` auf `type: ressource` umgestellt. Konsistent mit allen älteren v0.17.5/v0.17.6/v0.17.9-Lessons im selben Ordner.

### Werte-Bilanz
- pytest **368 passed** unverändert. Test 10 jetzt umgebungs-unabhängig grün (verifiziert: `.venv/Scripts/python.exe -m pytest tests/unit/test_bump_bundle_version.py` ohne `PYTHONUTF8=1` liefert 11/11 in 3.10s).
- Cross-Skill **25/25 PASS** unverändert.
- Bundle-Skills **29** unverändert.
- Memory-Lesson `feedback_hauptagent_schiedsrichter_revidiert_verdict` **1. praktische Anwendung** dieses Projekts.

### Post-Tag-Audit-Bilanz v0.17.12 (führte zu diesem Reife-Patch)
- Brille Z (Repo-Doku-Konsistenz): 2 HIGH (H-1 Test 10 / H-2 CHANGELOG-Header) + 2 MED + 2 LOW.
- Brille E (Vault-Konsistenz): 0 HIGH + 1 MED (Lessons-Typ-Drift) + 3 LOW.
- Brille D (Werte-Konsistenz): 0 HIGH + 1 MED (Spec-365/x vs CHANGELOG-368) + 1 LOW.
- Brille B (Spec-Aktivierung): 0 HIGH + 1 MED (Test-11-Mechanismus-Beschreibung) + 3 LOW.
- **Konvergenz-Cluster H-1 + M-2 (Z)**: B.7.3-Gate-Verifikation. Test 10 ist Herz des Gates, Pre-Tag-3-Achsen-Brille hatte das übersehen (kein FAIL bei dieser Brille-Session aufgrund des `PYTHONUTF8=1`-Prefix im Bash-Aufruf). Lehre: Test-Helper sollten umgebungs-robust sein, nicht von Caller-Env-Vars abhängig.

## [0.17.12] — 2026-05-24 — Mini-Welle: AST-Tree-Scan-Härtung + Cross-Skill-Pre-Bump-Gate

Pre-Wave-J-Refactor-Welle schließt die letzten zwei offenen Hardening-Slots vor Wave J (Stefan-Entscheidungen 11+12+13 vom 2026-05-22). A.7.1 macht die manuelle CONSUMER_*-Ergänzungs-Pflicht bei Wave-J-Migration obsolet. B.7.3 verhindert Wiederholung des v0.17.11-Versuchs-Crashs (Bump war erfolgreich, danach pytest rot). Hauptagent-deterministisch mit Pre-Audit-Vier-Brillen-Welle Z/E/B/R parallel und konsolidierten Reife-Patches im selben Welle-Bau.

### Hinzugefügt
- **A.7.1 Pin-7-AST-Tree-Scan-Härtung** in `.skills/_cross_skill_evals/run_api_keys_consistency_eval.py`. Pin 7 ist ab v0.17.12 zweischichtig:
  - **Schicht 1 (Whitelist):** unverändert — `CONSUMER_*`-Konstanten prüfen Disk-Realität verbatim plus Abwesenheit von `importlib.util.spec_from_file_location(`-Bootstrap.
  - **Schicht 2 (AST-Tree-Scan, neu):** `_collect_ast_consumers(SKILLS_ROOT)` läuft `os.walk(SKILLS_ROOT, followlinks=False)` über `.skills/**/*.py` außer `SCAN_EXCLUDED_DIRS = ("_lib", "_cross_skill_evals", "tests")` und `SCAN_EXCLUDED_NAMES = ("test_*.py",)`. Erfasst `ast.ImportFrom`-Knoten mit Modul `_lib.api_keys` (direkt) bzw. `find_api_key` (transitiv) plus `ast.Import`-Treffer mit `_lib.api_keys` (heute leer, künftige Drift-Wand). Diff gegen `EXPECTED_DIRECT_CONSUMERS` (zwei Pfade) + `EXPECTED_TRANSITIVE_CONSUMERS` (ein Pfad). Pfad-Ausgabe via `path.relative_to(SKILLS_ROOT).as_posix()` — kein absoluter Pfad-Leak (Brille-R-HIGH-Disziplin aus v0.17.5). Erkennt Wave-J-Drift automatisch sobald `elevenlabs-api/scripts/*.py` einen neuen `from _lib.api_keys import` einführt — kein manueller CONSUMER_*-Touch mehr nötig.
  - Negativ-Pin für `video-creator/scripts/*` kostenlos durch Whitelist-Diff (Architektur-Spec §5.3 + §6.2 Brille-C-C.2b).
- **B.7.3 Cross-Skill-Pre-Bump-Gate** in `.maintainer/scripts/bump_bundle_version.py`. Im `--apply`-Pfad führt das Skript vor dem ersten Disk-Touch (`_apply_changes`) eine Subprocess-Welle gegen alle fünf Cross-Skill-Evals aus. Strict-Variante (Stefan-Entscheidung 2026-05-24): Interpreter ist `.venv/Scripts/python.exe` (Windows) oder `.venv/bin/python` (POSIX), **kein** `sys.executable`-Fallback. Bei fehlendem Interpreter oder FAIL einer Suite: Bump verweigert mit **Exit-Code 6** und gefilterter FAIL-Ausgabe (repo_root-Pfade via `_scrub_repo_root` durch `.` ersetzt, max. 200 Zeilen). Neues CLI-Flag `--skip-cross-skill-gate` nur für Tests und dokumentierte Notfälle. Selbst-verifiziert am eigenen v0.17.12-Bump (vierter realer Skript-Einsatz, 33 Touches mit Gate-PASS-Vorspann).
- **AST-Scan-Sabotage-Probe als Wirkungs-Beleg:** `spy_consumer.py` (bewusst nicht `test_*` benannt, sonst Pin-Schein-Risiko durch eigene Exklusion) in temporärem `.skills/_sabotage_dummy/scripts/` löste Pin 7 FAIL aus mit `unexpected_direct=['_sabotage_dummy/scripts/spy_consumer.py']` — POSIX-relativ, kein Drive-Letter-Leak. Cleanup via `rm -rf .skills/_sabotage_dummy` ohne `git stash` (Working-Tree-Implementation hätte gestasht und Eval gegen alten Stand laufen lassen — Memory-Lesson `feedback_sabotage_probe_braucht_stash_vor_rollback`).
- **Drei neue Pin-Tests** für B.7.3 in `tests/unit/test_bump_bundle_version.py`:
  - Test 9 `test_apply_with_cross_skill_gate_skipped_via_flag` schützt das CLI-Flag.
  - Test 10 `test_apply_without_venv_python_exits_6` verifiziert Strict-Verhalten (kein `sys.executable`-Fallback).
  - Test 11 `test_dry_run_skips_cross_skill_gate_automatically` schützt Dry-Run-Performance (Mechanismus: leeres `_cross_skill_evals/` würde Gate mit FileNotFoundError und Exit 6 abbrechen, also belegt Exit 0 dass Gate gar nicht aufgerufen wurde).
- **Spec-v2** als `.maintainer/docs/V0.17.12-AST-PREBUMP-SPEC.md` mit Pre-Audit-Konsolidat aus vier Brillen (7 HIGH + 13 MED + 10 LOW) eingearbeitet: 11 Pflicht-Fixes (Umlaut-Drift, sys.executable-Fallback raus, run_evals.py-Scope-Klarstellung, ast.Import-Diff-Logik, Sabotage-Datei-Naming-Fall, SCAN_EXCLUDED_DIRS um `tests`, Test-11-Mechanismus, relative_to(SKILLS_ROOT)-Output, os.walk(followlinks=False), §6-Stop-Schwellen erweitert um Token-Budget + Sicherheits-Eskalation, §5-DoD um Docstring-Touch + drei-Bulk-Lauf).
- **Vier neue Vault-Lessons-Topic-Files** als E-H1-Reife-Patch in `02 Projekte/Second Brain Installationspaket/Lessons/`:
  - `replace-pass-statt-komplett-rewrite.md` (Brille-B-B.1)
  - `mindest-15-min-diagnose-vor-welle-abbruch.md` (Brille-B-B.2)
  - `git-stash-statt-checkout-welle-rollback.md` (Brille-B-B.6)
  - `uv-python-linkdir-segfault-pep-723.md` (uv-Diagnose-Erkenntnis)

### Aktualisiert
- 29 SKILL.md + `manifest.json` + `bundle.json`: `bundle_version: 0.17.11 → 0.17.12` via `bump_bundle_version.py --apply` (**vierter realer Skript-Einsatz** — erstmals mit Pre-Bump-Gate-Self-Verifikation, 33 Touches in einem Schritt).
- `bundle.json::released` + `manifest.json::bundle.released`: `2026-05-23 → 2026-05-24`.
- `.maintainer/docs/FOLGE-WELLEN-ROADMAP.md` v0.17.12-Block von „geplant" auf „erledigt" mit Welle-Bilanz.
- `.maintainer/docs/BUNDLE-MODE-READINESS.md` Stand-Block 2026-05-23 um zwei HARD-LOCK-Tabellenzeilen erweitert (§8.1 Music-Endpoint Conf 90 + §8.2 Voice-ID Conf 88 — Z-MED-3-Reife-Patch). Plus neuer Stand-Block `## Stand 2026-05-24 nach v0.17.12` mit AST-Scan-Konsumenten-Tabelle-Rückverweis auf V0.17.12-Spec §2.1 (B-02-Reife-Patch).
- `02 Projekte/Second Brain Installationspaket/Second Brain Installationspaket.md` Steckbrief-Status um Stand-Zeile 2026-05-23 (v0.17.11) ergänzt; Lessons-Verknüpfung von „bis v0.17.8" auf „bis v0.17.11" (E-H2/E-L1-Reife-Patch).
- `02 Projekte/Second Brain Installationspaket/Lessons/00-Lessons.md` Frontmatter `updated: 2026-05-24`, neuer Abschnitt „Aus v0.17.11" mit Datei-Slug-Wikilinks zu den vier neuen Topic-Files (E-2-Reife-Patch).
- Drei v0.17.9-Lessons Umlaut-Substitut-Fixes via Replace-Pass (E-M1-Reife-Patch): `pre-tag-drei-achsen-brille-fuer-mini-wellen.md`, `schiedsrichter-disk-grep-self-hits-abziehen.md`, `stefan-lock-verifikations-subagent-token-realismus.md`. Memory-Lesson `feedback_brief_ascii_substitute_drift` **13. Bestätigung**.

### Werte-Bilanz
- pytest **365 → 368 passed** (+3 Pin-Tests für B.7.3: Tests 9/10/11). Drei konsekutive Bulk-Läufe vor Bump je 368/0 (74.77s / 74.78s / 70.26s), Stefan-Lock-14-PASS-Schwelle erfüllt.
- Cross-Skill **25/25 PASS** unverändert über 5 Suiten — Pin 7 ab jetzt mit AST-Scan-Schicht 2 aktiv, 113 Dateien gescannt, drei Konsumenten wie erwartet.
- Bundle-Skills 29 unverändert.
- Drift-Wand-Self-Check Spec-Datei `V0.17.12-AST-PREBUMP-SPEC.md`: null Umlaut-Substitute nach Replace-Pass (sechs Treffer aus Brille-Z/R gefixt).
- Token-Aufwand v0.17.12 (real): ~0,4-0,5 M (Spec-Draft + Pre-Audit-Vier-Brillen + Spec v2 + Implementation A.7.1 + B.7.3 + Sabotage-Probe + Vault-Reife-Patches + Bump-Selbst-Verifikation + Doku-Touches).

### Memory-Lessons
- `feedback_brief_ascii_substitute_drift` **13. Bestätigung** (Brille-Z/R fanden sechs Treffer in Spec-Datei; Replace-Pass-Fix ohne Re-Drift).
- `feedback_sabotage_probe_braucht_stash_vor_rollback` praktisch validiert: erste Sabotage-Probe mit `git stash` stashte unbeabsichtigt eigene Implementation und produzierte falschen PASS — Stop-Signal, Rollback, zweiter Versuch ohne Stash sauber.
- `feedback_replace_pass_statt_komplett_rewrite` (v0.17.11 NEU) **1. Re-Anwendung** in v0.17.12 für Spec-Umlaut-Drift.

## [0.17.11] — 2026-05-23 — Mini-Welle: Wave-J-Architektur-Spec + uv-Linkdir-Reparatur

Mini-Welle schließt die letzte offene **Wave-J-Vorlauf-Pflicht (c)** aus v0.17.8 Mid-Audit. Architektur-Spec klärt das Verhältnis von `agents_elevenlabs`, `elevenlabs-api` und `video-creator` als verbindliche Eingangs-Doku für Wave J v0.18.0. Zugleich löst diese Welle den **Stefan-Lock 14** (uv-Bulk-Race plus trigger_enforcer-Einzelcrash) durch Root-Cause-Diagnose und Reparatur des uv-Python-Minor-Version-Symlinks. Hauptagent-deterministisch mit Bestandsaufnahme-Subagent + Pre-Tag-3-Achsen-Brille + Vier-Brillen-Session-Audit als drei sequentielle Sonnet-Slots.

### Hinzugefügt
- **Wave-J-Vorlauf-Pflicht (c) GESCHLOSSEN:** `.maintainer/docs/V0.17.11-WAVE-J-ARCHITECTURE-SPEC.md` (14 §-Sektionen, Spec-v1) — verbindliche Architektur-Klärung der drei ElevenLabs-relevanten Skills im Bundle-Kontext. Disk-Realität via Bestandsaufnahme-Subagent (Sonnet, 110K Token, 13 Tool-Uses) auf fünf `.claude/skills/agents_elevenlabs/references/*.md` + `.claude/skills/video-creator/SKILL.md` + vier Greps.
  - **§3.1 Drei Architektur-Verdikte:** (1) `agents_elevenlabs` (Vault-only, `/v1/convai/`) und `elevenlabs-api` (Bundle, Batch-TTS/Scribe/Music) sind **funktional disjunkt** — null Endpoint-Schnittmenge. (2) `elevenlabs-api` wird **eigener Bundle-Skill**, nicht Foundation-Library oder Sub-Modul. (3) `video-creator` greift **transitiv via `elevenlabs-api`** auf ElevenLabs zu, spiegelt das Nano-Banana-Indirektions-Pattern (`generate_image.py` → `find_api_key` → `_lib/api_keys.py`).
  - **§3.2 Bundle-Status nach Wave J:** Bundle-Skills 29 → 31 (Co-Migration `video-creator` + `elevenlabs-api`, identisch mit ROADMAP-Ziel).
  - **§4-§6 Sub-Skill-Routing und Konsumenten-Pfad:** drei kanonische Sub-Skill-Aufruf-Pfade (Scribe, TTS, Music), neue `CONSUMER_*`-Konstanten für `run_api_keys_consistency_eval.py` (eine direkt, drei transitiv), `video-creator/scripts/*` bleibt key-konsum-frei.
  - **§7.2 WJ-1 bis WJ-8 Pflichten:** WJ-8 NEU eingeführt — `BUENDEL_J_PRIVATE_PATTERNS_ELEVENLABS_API` als zweite Pattern-Liste neben WJ-7-`BUENDEL_J_PRIVATE_PATTERNS_VIDEO_CREATOR`. Ohne eigene Pattern-Liste keine elevenlabs-api-Isolation-Eval möglich (Brille-C-C.5a-Pflicht).
  - **§8 Zwei HARD-LOCKs für v0.18.0:** §8.1 Music-Endpoint-Existenz + Account-Tier (Brille-D-D.1 HIGH 90 — ElevenLabs Music war zeitweise Beta-only mit Allowlisting). §8.2 Voice-ID-Handling Premade vs Cloning (Brille-D-D.2 HIGH 88 — `video-creator/SKILL.md` sagt „Stefans Stimme", `LinkedIn Shorts.md` sagt Premade „George", beides verschiedene API-Pfade).
  - **§7.3 Token-Budget Wave J:** 1,9-2,8 M (Neubau-Aufwand + Multi-Sub-Skill-Orchestrator + zweischichtiger Stefan-Lock-Verifikations-Subagent). Plus v0.17.12 0,3-0,5 M (A.7.1 + B.7.3). Gesamt bis v0.18.0-Tag: 2,2-3,3 M.

### Aktualisiert
- 29 SKILL.md + `manifest.json` + `bundle.json`: `bundle_version: 0.17.10 → 0.17.11` via `bump_bundle_version.py --apply` (**dritter realer Skript-Einsatz** nach v0.17.9 Eigen-Verifikation und v0.17.10, 33 Touches in einem Schritt).
- `bundle.json::released` + `manifest.json::bundle.released`: `2026-05-22 → 2026-05-23`.
- `.maintainer/docs/FOLGE-WELLEN-ROADMAP.md` v0.18.0-Block **komplett umgeschrieben** von Single-Owner-Welle auf Co-Migration `video-creator` + `elevenlabs-api` (Bundle 29 → 31, Token-Realismus 1,9-2,8 M). Plus v0.17.11- und v0.17.12-Eintrag eingefügt (Brille-C-C.6b-Pflicht).
- `.maintainer/docs/BUNDLE-MODE-READINESS.md` Vorlauf-Pflichten-Tabelle Z. 211: Wave-J-Vorlauf-Pflicht (c) von `OFFEN — Wave-J-Spec-v1-Pflicht` auf **`GESCHLOSSEN v0.17.11`**. Plus neuer Stand-Block `## Stand 2026-05-23 nach v0.17.11` (Brille-C-C.6a-Drift-Falle).

### Werte-Bilanz
- pytest **365 passed** wiederhergestellt aus Stefan-Lock-14-Zustand 271/94 — drei konsekutive Bulk-Läufe je 365/0 (Brille-D-D.8-PASS-Schwelle erfüllt).
- Cross-Skill **25/25 PASS** unverändert (5 Suiten, unabhängig vom uv-Race über `.venv/Scripts/python.exe`-Direktaufruf).
- Skill-Eval nano-banana 16/16 + openai 16/16 unverändert.
- Bundle-Skills **29** unverändert (Wave J v0.18.0 macht 29 → 31).
- Stefan-Lock-Drift live: **0 Treffer** unverändert.

### Stefan-Lock 14 GESCHLOSSEN (uv-Bulk-Race + trigger_enforcer-Einzelcrash)
**Root-Cause:** Im uv-Python-Verzeichnis `C:\Users\stefa\AppData\Roaming\uv\python\` lag der defekte Minor-Version-Symlink `cpython-3.11-windows-x86_64-none` von der vorherigen ARM64-uv-Installation. Der zeigte auf einen nicht mehr existenten oder inkompatiblen Python-Binary. Bei jedem `uv run <pep723-script>`-Aufruf segfaultete uv beim Resolver-Schritt (`STATUS_ACCESS_VIOLATION` `0xC0000005`) ohne stderr. Tests, die direkt `.venv/Scripts/python.exe` nutzen, waren unbetroffen — daher Cross-Skill-Evals durchgängig 25/25 PASS, aber 94 pytest-Tests mit `subprocess.run(["uv", "run", ...])` crashten.

**Diagnose-Pfad (in dieser Session):** (a) `uv run python -c "print('hi')"` → OK (uv selbst läuft). (b) `uv run <pep723-script>` → SEGFAULT. (c) `.venv/Scripts/python.exe <script>` direkt → OK. **Verdikt:** Problem ist konsistente uv-Subprocess-Inkompatibilität mit PEP-723-Inline-Metadata-Scripts auf dieser Maschine, KEIN Bulk-Race wie ursprünglich vermutet (Brille-A-A.3-HIGH-Korrektur bestätigt).

**Auflösung:** `uv python install 3.11` (Fehlermeldung „Failed to create Python minor version link directory" am alten defekten Symlink, aber neue Verlinkung des Hauptpfads `cpython-3.11.15-windows-x86_64-none` erfolgreich). Danach `uv run <pep723-script>` → `{"action": "allow"}` Exit 0. PASS-Schwelle erfüllt mit drei konsekutiven 365/0-Bulk-Läufen.

### Vier-Brillen-Session-Audit (Welle-Abbruch-Bilanz 2026-05-22)
Vier disjunkte Sonnet-Brillen parallel auf die abgebrochene v0.17.11-Mini-Welle: **8 HIGH + 19 MED + 11 LOW**. Alle HIGHs und kritische MEDs vor Tag v0.17.11 in Spec und Handover eingearbeitet.

| Brille | Achse | Hauptbefunde HIGH |
|---|---|---|
| A — Widersprüche/Fehler | Spec-Konsistenz, Handover-Drift | A.1 Vorlauf-Pflicht-Tabelle (c)-Drift gefixt; A.3 trigger_enforcer crashed auch einzeln (heute bestätigt: KEIN Race, uv-Linkdir-Issue) |
| B — Effizienz | Process-Patterns | B.1 Komplett-Rewrite statt Replace-Pass; B.2 Welle-Abbruch ohne 15-Min-Diagnose; B.6 `git checkout -- .` statt `git stash` — alle drei als neue Memory-Lessons |
| C — Zahnrad-Fit | Spec vs. Gesamtkonstrukt | C.5a `elevenlabs_api_bundle_stefan_lock_isolation`-Eval + WJ-8-Pattern-Liste in Spec §3.2/§7.2 |
| D — Blinde Flecken | offene Fragen | D.1 Music-Endpoint-Existenz HARD-LOCK §8.1; D.2 Voice-ID-Handling HARD-LOCK §8.2 |

### Memory-Lessons verstärkt durch v0.17.11
- **`feedback_brief_ascii_substitute_drift` (12. Bestätigung):** Robustheits-Lesson aus 7 Folgewellen, Drift-Wand fängt weiter zuverlässig.
- **`feedback_subagent_token_budget_realistisch_30_50_prozent` (18. Bestätigung):** Bestandsaufnahme-Subagent 110K Token (Sonnet) bei Brief-Schätzung 30-50K — für Vault-Synthese-Subagents Brief-Schätzbereich auf 50-150K erweitert.
- **NEU `feedback_replace_pass_statt_komplett_rewrite` (B.1):** Bei ASCII-Substitut-Drift kleinen Replace-Pass statt großen Rewrite einsetzen; spart 70-80% Token, weniger Drift-Risiko.
- **NEU `feedback_mindest_15min_diagnose_vor_welle_abbruch` (B.2):** Bei Welle-Crash erst 15-Min-Diagnose mit drei Hypothesen, bevor abgebrochen wird; verhindert Doppel-Welle.
- **NEU `feedback_git_stash_statt_checkout_fuer_welle_rollback` (B.6):** `git stash push -m "wellen-doku-draft"` statt `git checkout -- .` für Welle-Abbruch; ergänzt `feedback_sabotage_probe_braucht_stash_vor_rollback` um den Welle-Rollback-Kontext.
- **NEU `feedback_uv_python_minor_link_segfault_pep723`:** uv-Python-Minor-Version-Symlinks von alten ARM64-Installationen können nach x86_64-Reinstall stehen bleiben und `uv run` mit PEP-723-Inline-Metadata segfaulten lassen. Diagnose: `uv python install 3.X` erzwingt Re-Link, `uv run python -c "print('hi')"` vs `uv run <pep723-script>` als isolierende Probe.

### Vorlauf-Pflichten-Stand (für Wave J v0.18.0)
- (a) Bump-Skript `bump_bundle_version.py` ✅ GESCHLOSSEN v0.17.9
- (b) Cross-Skill-Eval `run_api_keys_consistency_eval.py` ✅ GESCHLOSSEN v0.17.10
- (c) Wave-J-Architektur-Spec `agents_elevenlabs` vs `elevenlabs-api` ✅ **GESCHLOSSEN v0.17.11** (NEU)
- (d) `BUENDEL_J_PRIVATE_PATTERNS_VIDEO_CREATOR` ✅ GESCHLOSSEN v0.17.9
- **Zusatz Stefan-Lock 14 (uv-Race)** ✅ GESCHLOSSEN v0.17.11

**Alle vier Wave-J-Vorlauf-Pflichten geschlossen.** Nächste Mini-Welle v0.17.12 (A.7.1 AST-Tree-Scan + B.7.3 Cross-Skill-Pre-Bump-Gate, Stefan-Entscheidungen 11+12+13) ist Wave-J-Blocker vor v0.18.0 Co-Migration.

## [0.17.10] — 2026-05-22 — Mini-Welle: Cross-Skill-Eval Foundation-Härtung run_api_keys_consistency_eval.py

Mini-Welle schließt Wave-J-Vorlauf-Pflicht (b) aus v0.17.8 Mid-Audit (Backlog #8 GESCHLOSSEN). Hauptagent-deterministisch mit Pre-Tag-3-Achsen-Brille (~30K) und Sabotage-Probe (~30K) als parallele Sonnet-Subagents zur Wirkungs-Verifikation. Hebt die v0.16.3-Härtungen von Per-File-Pin-Tests auf eine Cross-Skill-Vertragsschicht.

### Hinzugefügt
- **Wave-J-Vorlauf-Pflicht (b) GESCHLOSSEN:** `.skills/_cross_skill_evals/run_api_keys_consistency_eval.py` (370 LOC) mit **8 Pin-Assertions**:
  - Pin 1: `__all__`-Vollständigkeit gegen Spec-Liste der 5 Public-Funktionen.
  - Pin 2: Wrapper-Signatur-Symmetrie `get_gemini_key/get_openai_key/get_elevenlabs_key` via `inspect.signature`.
  - Pin 3: Env-Var-Name-Korrektheit per Monkeypatch (GEMINI_API_KEY/OPENAI_API_KEY/ELEVENLABS_API_KEY).
  - Pin 4: Tuple-Return-Form `(key|None, source-string)` aller drei Wrapper.
  - Pin 5: Source-String enthält keinen absoluten Pfad (v0.17.5-Pfad-Leak-Schutz für CI-stderr).
  - Pin 6: Drei-Tier-Cascade-Reihenfolge (System-Env → Projekt-.env → Vault-.env) per Probe-`.env`-Fixture in drei Szenarien.
  - Pin 7: Konsumenten-Namespace-Import-Stil — Substring-Check auf drei explizit hinterlegte Konsumenten (Disk-Realität via Konstanten): zwei direkte (`find_api_key.py`, `generate.py`) prüfen Präsenz von `from _lib.api_keys import`, ein transitiver (`generate_image.py`) prüft Präsenz von `from find_api_key import`; alle drei prüfen Abwesenheit von `importlib.util.spec_from_file_location(` (mit Paren, damit Doku-/Kommentar-Erwähnungen nicht treffen — v0.17.6-Namespace-Refactor-Erhalt). Härtung auf AST-Tree-Scan steht als Backlog A.7.1 P1.
  - Pin 8: v0.16.3-Bug-Fix-Erhalt (UTF-8-BOM-Strip, Prefix-Match mit `=`-Suffix, symmetrischer Quote-Strip) via verschmutzten `.env`-Fixtures.

### Aktualisiert
- 29 SKILL.md + `manifest.json` + `bundle.json`: `bundle_version: 0.17.9 → 0.17.10` via `bump_bundle_version.py --apply` (**zweiter realer Skript-Einsatz** nach v0.17.9 Eigen-Verifikation, 33 Touches in einem Schritt — Vault-Lesson 14× bestätigt: ad-hoc-Counter bleibt bei 0).
- `bundle.json::released` + `manifest.json::bundle.released`: bleibt `2026-05-22` (Mini-Welle am selben Tag wie v0.17.9 Post-Tag-Audit-Reife).

### Werte-Bilanz
- pytest **365 passed** unverändert.
- Cross-Skill **17/17 → 25/25 PASS** (4 → 5 Suiten, +8 Assertions: Bundle-Schema 2/2 + Image-Wave-G 2/2 + Linkedin-Wave-H 5/5 + Audit-Bundle-Fingerprint 8/8 + **api_keys-Consistency 8/8 NEU**).
- Skill-Eval nano-banana 16/16 + openai 16/16 unverändert.
- Bundle-Skills **29** unverändert.
- Stefan-Lock-Drift live: **0 Treffer** (14 Wave-I-Patterns aktiv; 22 Wave-J-Patterns als inaktive Liste in `test_utils.py`, Eval-Assertion `video_creator_bundle_stefan_lock_isolation` folgt in Wave J v0.18.0) unverändert.

### Pre-Tag-Brille + Sabotage-Bilanz
- **Pre-Tag-3-Achsen-Sonnet-Brille** (~30K Token, disjunkt: A Pin-Mechanik/Effizienz + B Doku-Konsistenz/Drift + C Blinde Flecken/Drift-Wand-Vollständigkeit): **0 HIGH / 2 MED / 10 LOW**, **keine Pflicht-Fixes für Tag**. Zwei billige Optional-Fixes vor Tag eingebaut: **A.1** toter `API_KEYS_PATH`-Modul-Konstanten-Block entfernt (Code-Hygiene), **B.1** Pin-7-Lesson-Bezug von datierungs-spezifischer Formulierung auf neutrale "Disk-Grep 2026-05-22" geändert (Doku-Drift-Prophylaxe).
- **Sabotage-Probe** (~30K Token, Setup-Pflicht `git add -f` + Stash vor Rollback gemäß Memory-Lesson `feedback_sabotage_probe_braucht_stash_vor_rollback`): **8/8 Pins wirksam**. Jeder Pin per gezielter Patch-Sabotage entkräftet, Test-Failure verifiziert, dann sauber zurückgerollt. Working Tree am Ende clean (Eval-Datei untracked + 31 modified Bump-Files unberührt).

### Memory-Lessons verstärkt durch v0.17.10
- **`feedback_brief_ascii_substitute_drift` (11. Bestätigung):** ein `Laedt`-Drift im Eval-Header-Docstring beim Bau gefangen — Drift-Wand `tests/unit/test_no_umlaut_substitutes.py` greift weiter robust direkt nach Implementer-Lieferung.
- **`feedback_schiedsrichter_verifiziert_brille_befund` (10. Bestätigung):** Erstlauf Pin 7 FAIL durch Substring-Treffer in einem Kommentar (`# importlib.util.spec_from_file_location ...`) — Pattern auf `importlib.util.spec_from_file_location(` mit Paren verschärft statt Bug zu akzeptieren. Erstes Mal zweistelliger Zähler.
- **`feedback_reale_db_werte_gegen_brief_regex` (3. Bestätigung):** Spec-vs-Disk-Drift bei Pin 7 — Handover-Spec sagte "drei Konsumenten", Disk-Grep zeigte 2 direkte Konsumenten + 1 transitiver via Wrapper. Korrigiert vor Code-Einbau.
- **`feedback_sabotage_probe_braucht_stash_vor_rollback` (etabliert):** `git add -f` als Setup-Pflicht für untracked Eval-Datei, jedes Pin sauber revertet (Working Tree am Ende `??` nur für die Eval-Datei, sonst clean).
- **`feedback_subagent_token_budget_realistisch_30_50_prozent` (17. Bestätigung):** Brillen-Subagent ~30K + Sabotage-Subagent ~30K real bei Brief-Schätzung 25-40K / 25-35K — diesmal Brief-Schätzung gut getroffen (nach v0.17.9-Erweiterung um Stefan-Lock-Verifikations-Subagent-Realismus 50-100K wurden Audit-/Wirkungs-Subagent-Briefs realistischer kalibriert).

### Wave-II-Backlog erweitert um v0.17.10-Items
- **A.1.1 NEU v0.17.10 LOW** Hardcoded Erwartungs-Werte in FAIL-Messages Pin 4/5/8 ersetzen durch effektiv verglichene Werte (Sabotage-Befund: irreführende Debug-Meldungen, Pin selbst wirksam).
- **A.2.1 NEU v0.17.10 LOW** Pin 7 Substring-Match durch AST-basierten `ImportFrom`-Check ersetzen für echte Aktivierungs-Spur statt Substring-Sensitivität.
- **A.7.1 NEU v0.17.10 P1** Pin 7 Allgemeingültigkeits-Härtung: Tree-Scan über `.skills/**/*.py` (exkl. `_lib/`, `_cross_skill_evals/`, Tests) auf disjunkte Präsenz von `from _lib.api_keys import` UND Fehlen von `importlib.util.spec_from_file_location(`. Drei-Achsen-Konvergenz aus Brille A.2 + B.1 + Sabotage motiviert P1-Priorität.
- **B.2.1 NEU v0.17.10 MED** Bundle-Mode-Vorbereitung Eval-Header-Docstring: Versions-Identifier-Aliase als Vault-Wave-Identifier flaggen für künftige Bundle-Veröffentlichung.
- **C.1.1 NEU v0.17.10 LOW** Pin 6 Drei-Szenario-Helper (sparbar ~30 LOC, Trade-off: explizite Lesbarkeit).
- **C.3.1 NEU v0.17.10 P3 Wave-J** Falls `_lib/api_keys.py` ins Bundle-shared-foundation wandert: Stefan-Lock-Pin nachziehen analog `BUENDEL_I_PRIVATE_PATTERNS_NEUE_PRAESENTATION` im Audit-Bundle-Fingerprint-Eval.

### Vorlauf-Pflichten-Stand (für Wave J v0.18.0)
- (a) Bump-Skript `bump_bundle_version.py` ✅ GESCHLOSSEN v0.17.9
- (b) Cross-Skill-Eval `run_api_keys_consistency_eval.py` ✅ **GESCHLOSSEN v0.17.10** (NEU)
- (c) Wave-J-Spec-v1 Architektur-Abschnitt `agents_elevenlabs` vs `elevenlabs-api` — OFFEN für v0.18.0
- (d) `BUENDEL_J_PRIVATE_PATTERNS_VIDEO_CREATOR` ✅ GESCHLOSSEN v0.17.9

### Spec-Drift-Korrekturen
- Handover sagte "Cross-Skill 17/17 → 18/18" — real **17/17 → 25/25** (8 neue Pin-Assertions in einer neuen fünften Suite, nicht 1 zusätzliche Assertion). Korrigiert in dieser CHANGELOG-Bilanz. Mechanik: das Cross-Skill-Konsolidierungs-Total zählt Pin-Assertions, nicht Suite-Anzahl.

### Post-Tag-Vier-Brillen-Audit (2026-05-22, Doku-Commit ohne Bundle-Bump)

Vier disjunkte Sonnet-Brillen (Z/E/D/B, je ~30-50K Token) auf v0.17.10-Stand nach Commit `f33cada`: **3 HIGH + 9 MED + 20 LOW**. Zwei harte 2-Brillen-Konvergenzen, ein Schiedsrichter-Downgrade.

**Konvergenzen:**
- **K1 (Z.1 + E.3, MED-bestätigt):** `.skills/_cross_skill_evals/README.md` listete nur 2 von 5 Suiten (Run-Befehl-Block veraltet seit Wave H/Audit-Fingerprint/api-keys), Bilanz-Summe `4/4` statt `25/25`. → Doku-Commit-Fix: Block auf alle fünf Suiten + Total `25/25` aktualisiert.
- **K2 (E.2 HIGH + D.3 LOW → HIGH-Eskalation):** Backlog-Bilanz-Drift in `BUNDLE-MODE-READINESS.md` Z. 466 — Operationskette `11 − 1 + 6` ergibt rechnerisch **16**, nicht 17. Klärung: Backlog #8 war Wave-J-Vorlauf-Pflicht (separat geführt), gehörte nie zu den 11 Wave-II-Items. Korrekt ist `11 + 6 = 17`. → Doku-Commit-Fix mit expliziter Klarstellung. Memory-Lesson `feedback_reale_db_werte_gegen_brief_regex` **4. Bestätigung** (selbe Welle, die in der 3. Bestätigung den Pin-7-Spec-Drift bereinigt hatte, produzierte methodisch denselben Bilanz-im-Kopf-statt-Inventar-Drift erneut).

**Einzel-Brille-Befund mit Doku-Commit-Fix:**
- **D.1 MED** Eval-Header Pin-7-Beschreibung sagt nicht explizit, dass der transitive Konsument `from find_api_key import` enthält — Pin-Body prüft das aber. → Eval-Header ergänzt.

**Einzel-Brille-HIGH ohne Pflicht-Fix (Schiedsrichter-Triage):**
- **B.1 HIGH (Bundle-Mode-Leak in `_lib/api_keys.py`-Docstring):** Vault-interne Wave-Identifier (Brille R HIGH v0.17.5, E-1-01, MH-H4-05, Pre-Tag-M-K-04) — Wave-J-Blocker, **kein Tag-Blocker** für v0.17.10 (Foundation-Layer aktuell nicht im Bundle). Wave-II-Backlog **B.2.2 NEU** als Schwesterposten zu B.2.1.
- **B.2 HIGH (`os.environ.clear()`-Modul-Import-Risiko):** Schiedsrichter-Downgrade auf **MED** — Argument der Brille ("aggregierender Healthcheck-Runner via Modul-Import") ist spekulativ; README dokumentiert Subprocess-Standalone als kanonisches Pattern. Wave-II-Backlog MED.

**Wave-II-Backlog erweitert um sechs Post-Tag-Audit-Items (17 → 23):**
- **B.2.2 HIGH** Bundle-Mode-Sanitization `_lib/api_keys.py`-Docstring (Schwesterposten zu B.2.1, Wave-J-Blocker-Kandidat)
- **B.7.1 MED** `_isolated_runtime` Cleanup minimal-invasiv (nur explizit gesetzte/entfernte Vars touchen statt `clear()+update()`)
- **B.7.2 MED** Pin 5 Pfad-Leak-Negativliste um WSL-Mount-Pfade `/mnt/c/` + Container-Pfade `/root/`, `/app/`, `/workspace/` ergänzen
- **B.7.3 MED** Cross-Skill-Run als Pre-Bump-Gate in `bump_bundle_version.py` (Exit 6 bei Cross-Skill-FAIL) — koppelt Disziplin an Release-Mechanik
- **B.7.4 LOW** Pin im `test_bump_bundle_version.py` für Rückwärts-Bump-Pfad (0.17.x → 0.17.x−1)
- **B.7.5 LOW** Pin 9 für `read_key_from_dotenv`-OSError-Pfad (nicht-existente Datei → None)

**Hochstufungs-Empfehlung für Wave J:**
- **A.7.1** (Pin 7 AST-Tree-Scan-Allgemeingültigkeit) von P1 auf **Wave-J-Blocker** — Brille B.3 argumentiert: erster vierter Konsument (`elevenlabs-api` oder `video-creator` in Wave J) würde sonst still durchschlüpfen, falls nicht in `CONSUMER_*`-Konstanten eingetragen. Stefan-Entscheidung 13 offen.

**Memory-Lessons verstärkt:**
- `feedback_reale_db_werte_gegen_brief_regex` **4. Bestätigung** (Bilanz-Rechen-Drift in derselben Welle wie die 3. Bestätigung).
- `feedback_disjunkte_brillen_achsen_pattern` verstärkt (Z/E/D/B disjunkt 5. Mal).
- `feedback_schiedsrichter_verifiziert_brille_befund` **11. Bestätigung** (B.2-HIGH-Downgrade auf MED nach Schiedsrichter-Prüfung der Spekulations-Hypothese).
- `feedback_5brillen_konvergenz_schlaegt_final_konsistenz_check` verstärkt — K1+K2 wurden von Pre-Tag-3-Achsen-Brille + Sabotage nicht entdeckt, Post-Tag-Vier-Brillen-Audit fing sie.

**Werte-Bilanz unverändert:** pytest 365, Cross-Skill 25/25, Bundle-Skills 29, bundle_version 0.17.10. Doku-Commit ohne Bundle-Bump (HEAD wandert, Tag `v0.17.10` bleibt auf `f33cada`).

## [0.17.9] — 2026-05-22 — Mini-Welle: bump_bundle_version.py + BUENDEL_J-Befüllung

Mini-Welle gemäß v0.17.8-Mid-Audit-Vorlauf-Pflichten (a) + (d). Schließt Backlog #13 (`bump_bundle_version.py` — 12. ad-hoc-Bump war v0.17.8) und befüllt die in v0.17.8 als Stub angelegte Liste `BUENDEL_J_PRIVATE_PATTERNS_VIDEO_CREATOR`. Hauptagent-deterministisch mit zwei parallelen Sonnet-Subagent-Slots (A = Skript-Build, B = Stefan-Lock-Verifikation), Hauptagent-Schiedsrichter zwischen Subagent-Ausgabe und Code-Einbau.

### Hinzugefügt
- **Backlog #13 GESCHLOSSEN:** `.maintainer/scripts/bump_bundle_version.py` (395 LoC) mit acht Pin-Tests in `tests/unit/test_bump_bundle_version.py`. Bumpt 33 Felder in einem Schritt (29 SKILL.md-Frontmatter + bundle.json::version+released + manifest.json::bundle.version+bundle.released). Quote-Stil-Bewahrung via Regex-Line-Replace (`SKILL_BV_RE`) statt `python-frontmatter`-Dump-Roundtrip (Subagent-A-Designentscheidung — `frontmatter`-Lib dumpt unquoted, Regex-Pfad ist deterministisch). CLI: `--to <semver>` Pflicht, `--released YYYY-MM-DD` optional (Default heute), `--dry-run` Default, `--apply` explizit. Sechs Exit-Codes (0/1/2/3/4/5). **Eigen-Verifikation: v0.17.9-Bump selbst per `--apply` ausgeführt** (erstmaliger Skript-Einsatz im realen Repo), 33 Touches, pytest 357 → 365.
- **Wave-J-Vorlauf-Pflicht (d) GESCHLOSSEN:** `.skills/_lib/test_utils.py::BUENDEL_J_PRIVATE_PATTERNS_VIDEO_CREATOR` mit **22 Patterns** befüllt (war Stub seit v0.17.8). Stefan-Lock-Verifikations-Subagent (Sonnet, 83K Token) extrahierte 27 Pattern-Kandidaten aus Vault-`.claude/skills/video-creator/SKILL.md` (192 Zeilen). Hauptagent-Schiedsrichter-Verifikation per Python-Disk-Grep gegen aktuelles `.skills/`-Bundle-Tree strich **5 False-Positive-Kandidaten**:
  - `\bVideo-Studio\b` (subsumiert durch `\b02 Projekte/Video-Studio\b`)
  - `\b08 Systemsteuerung/Bildgenerierung/Authentische Personendarstellung\b` (Bundle-Konvention: authentic-portrait/references/dossier-konvention.md verlinkt diesen Pfad)
  - `\b03 Bereiche/Content & Positionierung/LinkedIn Posts\b` (Bundle-Konvention: linkedin-ideen/run_evals.py scannt diesen Pfad)
  - `\b00 Kontext/Glossar\b` (Bundle-weite Wiki-Link-Konvention, 7 Treffer in 6 Files exklusive test_utils.py: auditor/scan.json, authentic-portrait/eval, kreuzverhoer/run_evals.py 2×, kreuzverhoer/eval, project-session-end/run_evals.py, project-session-end/eval)
  - `\bPhasenplan\b` (zu generisch, subsumiert durch `\b02 Projekte/Video-Studio\b`)
- Streich-Begründungen im Stub-Docstring von `test_utils.py` dokumentiert.

### Aktualisiert
- 29 SKILL.md + `manifest.json` + `bundle.json`: `bundle_version: 0.17.8 → 0.17.9` (Bulk-Bump **erstmals per neuem Skript**, ad-hoc-Counter zurückgesetzt auf 0).
- `bundle.json::released` + `manifest.json::bundle.released`: `2026-05-20 → 2026-05-22`.

### Werte-Bilanz
- pytest **357 → 365 passed** (+8 Bump-Skript-Pin-Tests).
- Cross-Skill **17/17 PASS** unverändert (2/2 + 2/2 + 5/5 + 8/8).
- Skill-Eval nano-banana 16/16 + openai 16/16 unverändert.
- Bundle-Skills **29** unverändert.
- Stefan-Lock-Drift live: **0 Treffer** (14 Wave-I-Patterns aktiv; 22 Wave-J-Patterns als inaktive Liste in `test_utils.py` vorbereitet, Eval-Assertion `video_creator_bundle_stefan_lock_isolation` folgt in Wave J v0.18.0).

### Pre-Tag-Brillen-Pass
- **Eine kombinierte 3-Achsen-Sonnet-Brille** (Code-Korrektheit + Doku-Konsistenz + Stefan-Lock-Pattern-Wortgrenzen, ~38K Token) fand **2 HIGH + 6 MED + 4 LOW**. Pflicht-Fixes vor Tag: C1+C2 Hauptagent-Selbst-Drift bei "9 legitime Treffer" (Disk-Grep zeigte 7 Treffer in 6 Files exklusive test_utils.py — Docstring + CHANGELOG synchron korrigiert), C3 ROADMAP-Reihenfolge v0.17.8/v0.17.9 chronologisch getauscht, E6 Mandant-Pattern-Lücke per Stefan-Schiedsrichter-Entscheid bewusst ausgelassen mit Begründung im BUENDEL_J-Docstring. Restliche MEDs/LOWs gehen ins Wave-II-Backlog (unquoted-Pin-Test, Doppel-Verifikations-Doku, BUENDEL_SHARED_PRIVATE_PATTERNS-Layer-Erwägung, Stefan-Selbstbezug-Doku-Hinweis für Wave J).

### Memory-Lessons verstärkt
- **`feedback_brief_ascii_substitute_drift` (10. Mal):** ein `Tatsaechlich`-Drift im Subagent-A-Help-Text Z. 68 — Drift-Wand `tests/unit/test_no_umlaut_substitutes.py` fing das im Sanity-pytest direkt nach Subagent-Lieferung. Einminütiger Hauptagent-Edit. Pattern weiter robust.
- **`feedback_schiedsrichter_verifiziert_brille_befund` (9. Mal):** Disk-Grep gegen 27 Subagent-Pattern-Kandidaten fand 5 FP-Klassifikationen vor Code-Einbau. Schiedsrichter-Verdikt mit klarer Streich-Begründung dokumentiert.
- **`feedback_reale_db_werte_gegen_brief_regex` (2. Bestätigung):** Hauptagent-Selbst-Drift bei "9 legitime Treffer in 4 Skills" — Pre-Tag-Brille C1+C2 fand die Inkonsistenz, frischer Disk-Grep zeigte 7 Treffer in 6 Files exklusive test_utils.py-Self. Lesson erweitert: **reale Disk-Werte verbatim ins Docstring/CHANGELOG, nicht aus dem Subagent-Verifikations-Output-Kopf nachtragen** — die Selbst-Drift war beim Schreiben des Streich-Begründungs-Kommentars entstanden, weil ich den Subagent-Verifikations-Total-Count (9 inkl. Self) auf "legitime Treffer" gemappt habe ohne Self-Hits abzuziehen.
- **`feedback_subagent_token_budget_realistisch_30_50_prozent` (16. Bestätigung):** Subagent A 50K real (gegen 60K Stop-Schwelle, im Brief 30-60K geschätzt). Subagent B 83K real (gegen Brief-Schätzung 15-25K — Vault-SKILL-Read 192 Z. + 27 Kandidaten-Tabelle baute auf, war Aufgabe-bedingt notwendig). Pre-Tag-Brille 38K (gegen 40-60K geschätzt). Subagent B übersteigt Brief-Schätzung um Faktor 3-5, künftige Stefan-Lock-Verifikations-Subagent-Briefs realistisch mit 50-100K planen.

### Wave-II-Backlog (v0.17.9 reduziert)
- **GESCHLOSSEN:** #13 `bump_bundle_version.py` (war "höchstpriorisiert" seit v0.17.6, 12 ad-hoc-Bumps belegen).
- **GESCHLOSSEN:** Wave-J-Vorlauf-Pflicht (d) `BUENDEL_J_PRIVATE_PATTERNS_VIDEO_CREATOR` (war Stub seit v0.17.8).
- 11 Items bleiben offen (von 13 nach v0.17.8).

### Vorlauf-Pflichten-Stand (für Wave J v0.18.0)
- (a) Bump-Skript ✅ GESCHLOSSEN v0.17.9
- (d) BUENDEL_J befüllen ✅ GESCHLOSSEN v0.17.9
- (b) Cross-Skill-Eval `run_api_keys_consistency_eval.py` — OFFEN für v0.17.10
- (c) Wave-J-Spec-v1 Architektur-Abschnitt `agents_elevenlabs` vs `elevenlabs-api` — OFFEN für v0.18.0

### Post-Tag-Vier-Brillen-Audit (2026-05-22, Doku-Commit ohne Bundle-Bump)

Vier disjunkte Sonnet-Brillen (Z/E/D/B) auf v0.17.9-Stand: **5 HIGH + 13 MED + 6 LOW**. Zwei Konvergenzen auf HIGH-Stufe: **K1 (Z+D+D, 3-Brillen-Konvergenz):** BUNDLE-MODE-READINESS.md nicht v0.17.9-aktualisiert (Frontmatter, BUENDEL_J-Tabelleneintrag, Cross-Skill-Eval-Status, neuer Stand-Block, Bilanz 17→11). **K2 (D+B, 2-Brillen-Konvergenz):** v0.17.9-Lessons (Pre-Tag-3-Achsen-Brille-Pattern, Stefan-Lock-Verifikations-Subagent-Token-Realismus, Schiedsrichter-Disk-Grep-Self-Hits) nicht als Vault-Topic-Files persistiert.

**Doku-Commit-Patch eingearbeitet (kein Bundle-Bump, kein Tag, bundle_version bleibt 0.17.9):**
- K1: BUNDLE-MODE-READINESS.md aktualisiert — Frontmatter `updated: 2026-05-22`, BUENDEL_J-Eintrag auf `GESCHLOSSEN v0.17.9 (22 Patterns)`, Cross-Skill-Eval-Status auf `VORLAUF-PFLICHT-BAUPLAN-OK`, neuer Stand-Block "Stand 2026-05-22 nach v0.17.7+v0.17.8+v0.17.9" mit Bilanz 17→11.
- K2: Drei Topic-Files unter `02 Projekte/Second Brain Installationspaket/Lessons/` angelegt: `pre-tag-drei-achsen-brille-fuer-mini-wellen.md`, `stefan-lock-verifikations-subagent-token-realismus.md`, `schiedsrichter-disk-grep-self-hits-abziehen.md`. Index `00-Lessons.md` um v0.17.9-Sektion erweitert.
- Projektsteckbrief Frontmatter `updated: 2026-05-21 → 2026-05-22`.

**Wave-J-Spec-v1-Pflichten verankert (für v0.18.0, Brille B Befunde, nicht jetzt fixen):**
- B.2.1: BUENDEL_J um Stefan-Anrede-Pattern erweitern ODER Spec-v1 listet "Stefan-Anreden generisch umformulieren" als Migrations-Sub-Task.
- B.3.2: Wikilink-Sanitization-Tool oder -Sub-Task für 8 Vault-Wikilinks im migrierten Bundle-Skill.
- B.3.3: Owner-Skill-Runner-Eval `.skills/video-creator/run_evals.py` VOR Skill-Migration anlegen.
- B.4.2: `natur-sprech-check` als 10. Sub-Skill explizit klassifizieren.
- B.4.3: Test-Setup-Skizze für Cross-Skill-Eval-Pattern.
- B.6.1: authentic-portrait-Delegation generisch oder Stefan-spezifisch?

**Wave-II-Backlog erweitert um v0.17.9-Post-Tag-Audit-Items:**
- B.1.1 Path-Traversal-Hardening `bump_bundle_version.py` `--repo-root`
- B.1.2 Symlink-Containment-Check vor Write
- B.6.2 BUENDEL_SHARED_PRIVATE_PATTERNS-Trigger-Klärung (Stefan-Entscheidung #9 weiter)
- E.1.1 Toter Code Z. 227 `touches  # no touch` entfernen
- E.1.2 Doppel-Verifikation kombinieren (-15 LoC)
- E.2.1 BUENDEL_J-Begründungs-Docstring in `.maintainer/docs/`-Markdown auslagern (-30 LoC im Code)

**Memory-Lessons verstärkt:**
- `feedback_mid_implementer_audit_welle` **3. Bestätigung** (K1-3-Brillen-Konvergenz Z+D+D bestätigt Pattern erneut)
- `feedback_5brillen_konvergenz_schlaegt_final_konsistenz_check` verstärkt (K1 mit 3-Brillen-Konvergenz)
- `feedback_disjunkte_brillen_achsen_pattern` verstärkt (Z/E/D/B disjunkt 4. Mal)

**Werte-Bilanz unverändert:** pytest 365, Cross-Skill 17/17, Bundle-Skills 29, bundle_version 0.17.9.

## [0.17.8] — 2026-05-21 — Mid-Implementer-Audit-Reife nach v0.17.7

Mid-Implementer-Audit-Welle (Z/E/D/B disjunkt) auf v0.17.6+v0.17.7-Gesamtstand. **10 HIGH + 11 MED + 2 LOW** insgesamt, davon **2 Konvergenzen auf HIGH-Stufe**. Pattern `feedback_mid_implementer_audit_welle` zum **2. Mal** angewendet — fand strukturelle Schwächen, die Vier-Brillen-Final-Audit-Pässe nach Einzel-Wellen nicht abdecken (Cross-File-Doku-Konsistenz über mehrere Reife-Patches hinweg).

### Schiedsrichter-Konsolidierung der 4 Brillen

- **2-Brillen-Konvergenz Z-H-01 + D.4 (Conf 97+100):** BUNDLE-MODE-READINESS Z. 239 zeigte Bilanz `17→14`, Z-M-01-Fix in v0.17.7 hatte den CHANGELOG korrigiert, aber READINESS-Bilanzzeile unkorrigiert gelassen.
- **2-Brillen-Konvergenz B.2 + B.3 (Conf 88+95):** Vault hat `agents_elevenlabs` (Conversational AI/Twilio), kein `elevenlabs-api` (Scribe `/v1/speech-to-text` + TTS `/v1/text-to-speech`). Komplett andere Produkte. Wave-J-Spec-v1 muss dedizierten Architektur-Klärungs-Abschnitt liefern.
- **Brille-E Doppel-Befund E.2+E.5 (selbe Wurzel, Conf 95+92):** `bump_bundle_version.py` nach 11 ad-hoc-Bumps weiter fehlend — als Wave-J-Vorlauf-Pflicht (Backlog #13) priorisiert.

### Gefixt (Doku-Konsistenz, v0.17.8-Scope)
- **Z-H-01/D.4 KONVERGENZ:** `.maintainer/docs/BUNDLE-MODE-READINESS.md` Z. 239 Bilanz `17→14` → `17→13` korrigiert mit Verweis auf Z-M-01-Quelle.
- **D.1 HIGH (Conf 100):** `.maintainer/docs/FOLGE-WELLEN-ROADMAP.md` v0.17.7-Eintrag ergänzt (war komplett ausgelassen worden) + v0.17.8-Eintrag + v0.18.0-Eintrag mit Vorlauf-Pflichten-Liste aktualisiert.
- **Z-H-02 HIGH (Conf 92):** `.skills/_lib/test_utils.py` `BUENDEL_J_PRIVATE_PATTERNS_VIDEO_CREATOR` als leerer Stub angelegt (Code-Fundament für Wave-J-Pre-Implementer-Phase, war bisher nur Doku-Versprechen).
- **D.2 MED (Conf 85):** Handover-Frontmatter `updated: 2026-05-20 → 2026-05-21` (heutige inhaltliche Änderung durch v0.17.8-Sektion).
- **Z-M-01 MED (Conf 85):** BUNDLE-MODE-READINESS Wave-J-Tabelle-Überschrift `Stand nach v0.17.5 → Stand nach v0.17.7` + neue Tabellenzeilen für `Namespace-Package-Layer stabilisiert (v0.17.6)`, `BUENDEL_J_PRIVATE_PATTERNS_VIDEO_CREATOR im Code (v0.17.8)`, `Doku-Konsistenz als Post-Tag-Audit-Achse (v0.17.7/v0.17.8)`, sowie `Architektur-Klärung agents_elevenlabs vs elevenlabs-api` als OFFEN-Eintrag.
- **Z-M-02 MED (Conf 82):** Projektsteckbrief `Second Brain Installationspaket.md` Wikilink auf `Lessons/00-Lessons` ergänzt + `updated: 2026-05-19 → 2026-05-21`.
- **D.5 MED (Conf 83):** Memory-Topic-File `feedback_schiedsrichter_verifiziert_brille_befund.md` um aktuellen Zähler **8×** und Wellen-Anker (v0.17.3/5/6/7/8) erweitert.

### Wave-II-Backlog / Wave-J-Spec-Vorlauf (nicht v0.17.8-Scope, dokumentiert)
- **E.2/E.5 HIGH (Conf 95+92):** Backlog #13 `bump_bundle_version.py` als **Wave-J-Vorlauf-Pflicht** priorisiert. ~15-20K Token Investment, 5-10K Saving pro Welle danach. 11 ad-hoc-Bumps belegen Bedarf.
- **B.1 HIGH (Conf 90):** Cross-Skill-Eval `run_api_keys_consistency_eval.py` (Backlog #8) braucht Bauplan-Skizze vor Wave-J-Implementer (Wer baut? Welche vier Wrapper? Welche Tuple-Pins?). Stefan-Klärung #7 weiter OFFEN.
- **B.2/B.3 HIGH (Conf 88+95):** Wave-J-Spec-v1 muss dedizierten Architektur-Klärungs-Abschnitt zu `agents_elevenlabs` (Conversational AI, existiert im Vault) vs `elevenlabs-api` (TTS+Scribe, existiert NICHT) enthalten. `video-creator` Phase-1-DoD klären (kein Render in Phase 1 laut Vault-SKILL.md). `natur-sprech-check` als 10. Sub-Skill explizit klassifizieren.
- **B.5 HIGH (Conf 87):** Doku-Konsistenz als explizite Achse im Wave-J-Post-Tag-Final-Audit verankern (strukturelle Pre-Tag-Blindstelle, durch v0.17.6→v0.17.7 + v0.17.7→v0.17.8 zweimal bestätigt).
- **B.6 MED (Conf 83):** Implementer-/Audit-Brief-Template um Lessons-Pflicht-Reads-Sektion erweitern. Mechanismus muss Implementer zwingen, Lessons zu konsultieren.
- **E.1 MED (Conf 85):** Brillen-Brief-Template um Pflicht-Satz für Code-/Doku-Behauptungen: „Wenn die Brille eine Mechanik-/Semantik-Behauptung macht, muss sie die Vorbedingungen explizit formulieren; Empfehlungen ohne benannte Vorbedingung werden vom Schiedsrichter nicht als HIGH akzeptiert." Hätte v0.17.6 Option-A-FP und v0.17.7 Z-H-01-FP verhindert.
- **E.4 MED (Conf 83):** Reife-Patch-CHANGELOG-Einträge abspecken (Brillen-Pässe-Prosa ins Handover, nicht in Release-Notes).
- **B.4 MED (Conf 82):** Token-Budget Wave J Realismus: 1,5-2,2 M → 2,0-2,8 M wegen Vorlauf-Pflichten (Backlog #13 + #8 + Architektur-Klärung). In FOLGE-WELLEN-ROADMAP v0.18.0-Zeile aktualisiert.

### Aktualisiert
- 29 SKILL.md + `manifest.json` + `bundle.json`: `bundle_version: 0.17.7 → 0.17.8` (Bulk-Bump **12. ad-hoc-Mal** — letzter ad-hoc-Bump vor Backlog-#13-Schließung als Wave-J-Vorlauf).

### Werte-Bilanz
- pytest **357 passed** unverändert.
- Cross-Skill **17/17 PASS** unverändert.
- Skill-Eval nano-banana 16/16 + openai 16/16 unverändert.
- Bundle-Skills **29** unverändert.
- Stefan-Lock-Drift live: **0 Treffer** (14 Patterns) unverändert.

### Brillen-Pässe-Bilanz
- **Vier Mid-Implementer-Brillen** disjunkt parallel auf v0.17.6+v0.17.7-Gesamtstand: Z (Zahnrad-Fit, 6 Achsen, 2H/3M/1L), E (Effizienz, 6 Achsen, 2H/4M/0L), D (Drift, 7 Achsen, 2H/2M/0L), B (Blinde Flecken, 7 Achsen, 4H/2M/1L). 26 Achsen insgesamt, **10 HIGH** + 11 MED + 2 LOW.
- Vorab-Schwächen-Brainstorm (7 Punkte) durch Brille-Befunde validiert: 4 von 7 Punkten als HIGH bestätigt (D.1 Roadmap, D.2 Frontmatter, D.4 Bilanz, B.1 Eval-#8).
- Mid-Implementer-Audit als Pattern zum 2. Mal validiert (erstmals D4-Analyse-System Phase 10 gamma-1) — fand strukturelle Cross-File-Konsistenz-Befunde, die einzelne Vier-Brillen-Final-Audits nach Einzel-Wellen nicht abdeckten.

### Memory-Lessons (verstärkt / NEU)
- **`feedback_schiedsrichter_verifiziert_brille_befund` (8. Mal):** keine neue Schiedsrichter-Korrektur in v0.17.8 selbst — Brille-Befunde alle disk-verifiziert vor Edit.
- **`feedback_mid_implementer_audit_welle` (2. Bestätigung):** Vier Brillen Z/E/D/B disjunkt auf Multi-Wellen-Gesamtstand — fand strukturelle Konsistenz-Befunde, die Per-Welle-Final-Audits übersehen.
- **`feedback_disjunkte_brillen_achsen_pattern` (verstärkt):** Vier-Brillen-Achsen-Schema (Zahnräder/Effizienz/Drift/Blinde-Flecken) als Mid-Implementer-Variante des Z/E/B/R-Final-Audit-Schemas etabliert.

### Wave-II-Backlog-Stand nach v0.17.8 (13 Items + 5 neue v0.17.8-Items)
- 13 ursprüngliche bleiben offen.
- **NEU v0.17.8 HIGH-Prio:** Wave-J-Vorlauf-Pflicht-Pakete (Backlog #13 Bump-Skript, Backlog #8 Eval-Bauplan, Wave-J-Spec-v1 Architektur-Abschnitt, Wave-J-Post-Tag-Audit Doku-Konsistenz-Achse).
- **NEU v0.17.8 MED:** Brillen-Brief-Template-Härtung (E.1), Implementer-Brief-Lessons-Pflicht (B.6), Reife-Patch-CHANGELOG-Abspeck-Pattern (E.4).

## [0.17.7] — 2026-05-20 — Doku-Konsistenz-Reife nach Vier-Brillen-Final-Audit auf v0.17.6

Reife-Patch nach Vier-Brillen-Final-Audit (Z/E/B/R disjunkt) auf v0.17.6. Pattern zum **zweiten Mal** angewendet (erstmals v0.17.5) — fand vier HIGH-Befunde, die das Drei-Brillen-Pre-Tag-Pattern strukturell übersehen hätte. Alle vier HIGH plus drei MED in einer deterministischen Welle gebündelt. Schiedsrichter-Korrektur bei Z-H-01 dokumentiert (Brille Z empfahl Header-Umbenennen, korrekter Fix war Block-Überschrift einfügen — Memory-Lesson `feedback_schiedsrichter_verifiziert_brille_befund` **8. Bestätigung**).

### Gefixt
- **Z-H-01 HIGH (Brille Z, Conf 92, Schiedsrichter-korrigiert):** BUNDLE-MODE-READINESS Z. 249 — die `Wave-I-Status`-Tabelle hatte ihre eigene Block-Überschrift verloren, weil der v0.17.6-Stand-Block VOR der Tabelle eingefügt wurde. Brille Z empfahl Header `Wave-I-Status` → `Wave-J-Status` — Schiedsrichter widerlegt: die Tabelle beschreibt inhaltlich Wave I, nicht Wave J. Korrekter Fix: Block-Überschrift `## Stand 2026-05-20 nach Wave I v0.17.0 Komplett (Bündel-Modus-Bereitschaft)` davor einfügen.
- **Z-H-02 HIGH (Brille Z, Conf 88):** `_lib/api_keys.py` Modul-Docstring listete `generate_image.py` im Direkt-Konsumenten-Block, obwohl es indirekter Konsument via `find_api_key`-Wrapper ist. Konsumenten-Liste restrukturiert in drei Gruppen: **Direkt** (find_api_key.py, generate.py), **Indirekt** (generate_image.py via Wrapper), **Transitiv** (authentic-portrait via Skill-Routing).
- **R-H-01 HIGH (Brille R, Conf 100):** Handover.md auf v0.17.6+v0.17.7-Stand gezogen. Fünf Inkonsistenzen geschlossen: Überschrift, TL;DR, Endstand-Block (HEAD/Version/Tags), Wave-II-Backlog (17→13 Items, #1/#4/#16/#17 als GESCHLOSSEN), Klärung 1+2 als ERLEDIGT markiert.
- **B-H-01 HIGH (Brille B, Conf 85):** BUNDLE-MODE-READINESS Z. 247 Formulierung „ohne Bootstrap-Boilerplate zu replizieren" missverständlich. Klarstellung ergänzt: **3-Zeilen-`sys.path`-Header bleibt in jedem konsumierenden Skript Pflicht** — er ersetzt den alten `importlib.util`-Bootstrap, ist aber nicht weggefallen. Ohne Header schlägt `from _lib.api_keys import ...` mit `ModuleNotFoundError` fehl.
- **Z-M-01 MED (Conf 82):** v0.17.6-CHANGELOG-Eintrag #16-Status korrigiert. Geschlossen-Liste um #16 ergänzt (Memory-Lessons als Topic-Files persistiert), Bilanz 17→14 → korrekt 17→13.
- **Z-M-02 MED (Conf 80):** Lessons/00-Lessons.md Wikilink-Pfad-Qualifier für Projektsteckbrief + Handover ergänzt (Ambiguitäts-Schutz, Vault-Hygiene).
- **B-M-01 MED (Conf 82):** `.templates/default/AGENTS.md` `_lib/`-Bereich um Namespace-Package-Regel erweitert: PEP-420-Verhalten, 3-Zeilen-`sys.path`-Header Pflicht, Verbots-Regel für Tests („Nie naive `from _lib.designsystem ...` in pytest-Funktionen nach `.skills/`-sys.path-Insert"), Verweis auf `spec_from_file_location`-Schutz-Muster.

### Aktualisiert
- 29 SKILL.md + `manifest.json` + `bundle.json`: `bundle_version: 0.17.6 → 0.17.7` (Bulk-Bump **11. ad-hoc-Mal**).

### Werte-Bilanz
- pytest **357 passed** unverändert.
- Cross-Skill **17/17 PASS** unverändert.
- Skill-Eval nano-banana 16/16 + openai 16/16 unverändert.
- Bundle-Skills **29** unverändert, Stefan-Lock-Drift live **0 Treffer** (14 Patterns) unverändert.

### Brillen-Pässe-Bilanz
- **Vier Final-Audit-Brillen** disjunkt parallel auf v0.17.6: Z (Zahnrad-Fit, 5 Achsen), E (Effizienz/Vereinfachung, 5 Achsen), B (Blinde Flecken, 6 Achsen), R (Roadmap+Security, 6 Achsen). 22 Achsen, **4 HIGH** + 4 MED + 14 LOW/NIT.
- **Pattern-Validierung:** Vier-Brillen-Pattern zum **zweiten Mal** als robuster als Drei-Brillen-Pre-Tag-Pattern bestätigt (v0.17.5 erstmals, v0.17.6 wiederholt: 4 HIGH gefunden, alle Doku-Drifts).
- **Schiedsrichter-Aktion:** Brille Z' Empfehlung zu Z-H-01 disk-verifiziert und korrigiert vor Edit (Header-Umbenennen → Block-Überschrift-Fix).

### Memory-Lessons (verstärkt / NEU)
- **`feedback_schiedsrichter_verifiziert_brille_befund` (8. Mal):** Brille Z empfahl mit Conf 92 Header-Umbenennen (Wave-I → Wave-J). Disk-Verifikation zeigte: Tabelle beschreibt inhaltlich Wave I, Header-Umbenennen wäre semantisch falsch. Korrekter Fix war strukturell (Block-Überschrift). Erneut belegt: Brille mit Code-/Doku-Behauptung muss disk-verifiziert werden, auch bei mittelhoher Confidence.
- **`feedback_5brillen_konvergenz_schlaegt_final_konsistenz_check` (verstärkt):** Vier-Brillen-Final-Audit zum zweiten Mal fand mehrere HIGH-Befunde, die Drei-Brillen-Pre-Tag-Pattern strukturell nicht abdeckt. Pattern als Pflicht-Schicht für jeden Tag-Push etabliert.

### Wave-II-Backlog (v0.17.7 reduziert)
- **GESCHLOSSEN v0.17.6+v0.17.7:** #1 + #4 + #16 + #17 (vier Items aus 17 ursprünglichen).
- **NEU v0.17.6 (LOW):** `_lib/_sys_path.py`-Helper für 3-Zeilen-Header mit Zirkularitäts-Warnung (Helper kann nicht von Konsumenten importiert werden, die selbst sys.path-Setup brauchen).
- **NEU v0.17.6 (MED):** `auditor/scan.py:55` lazy `cross_skill`-Import nicht durch Eval-Suite abgedeckt.
- **WON'T FIX (Brille E v0.17.6 E.5):** #14 `getmyinvoices/scripts/gmi_client.py:55` — 1-stufige Lookup-Logik ist Design Intent (Production-Service-Token).
- **Priorität erhöht (Brille R v0.17.6 R.6):** #8 Cross-Skill-Eval `run_api_keys_consistency_eval.py` — von „empfohlen" auf **VORLAUF-PFLICHT** vor Wave-J-Implementer.
- **13 Items bleiben offen** (siehe Handover-Wave-II-Backlog).

### Stefan-Klärungen (v0.17.6+v0.17.7 ERLEDIGT)
- **Klärung 1 ERLEDIGT** (Stefan 2026-05-20): Wave J = Single-Owner-Welle für `video-creator`, `elevenlabs-api` als Anwender-Vault-Voraussetzung. Hinweis aus Brille R v0.17.6 R.2: Vault hat `agents_elevenlabs` (Conversational Agents), aber kein `elevenlabs-api` (TTS/Scribe) — sind nicht dasselbe, Wave-J-Spec-v1 muss das klarstellen.
- **Klärung 2 ERLEDIGT** (v0.17.6 Option D): Beide `_lib/`-Wurzeln Namespace Packages.

## [0.17.6] — 2026-05-20 — Namespace-Fix Bootstrap-Eliminierung + Memory-Lessons-Persistierung

Schließt Wave-II-Backlog-Items #1 (Namespace-Package-Konflikt strukturell lösen) und #4 (Bootstrap-Helper) durch Option D (disk-verifiziert vor Code-Änderung). Brille E's ursprünglich empfohlene Option A („leere `__init__.py` in Repo-Root-`_lib/`") wurde durch Probe-Skript widerlegt — hätte `_lib.api_keys`-Auflösung bei REPO_ROOT-vorne-Reihenfolge gebrochen. Memory-Lesson `feedback_schiedsrichter_verifiziert_brille_befund` **7. Bestätigung**.

### Gefixt
- **Namespace-Package-Konflikt strukturell aufgelöst:** `.skills/_lib/__init__.py` (0 Bytes) entfernt. Beide `_lib/`-Verzeichnisse sind jetzt Namespace Packages (PEP 420), Python mergt `__path__` automatisch. `_lib.api_keys` (aus `.skills/_lib/`) und `_lib.designsystem` (aus Repo-Root-`_lib/`) funktionieren in allen realistischen sys.path-Reihenfolgen, solange `.skills/` in sys.path liegt.
- **Drei Konsumenten zurückgebaut auf direkten Import** (ehemals `importlib.util.spec_from_file_location` mit ~17 LOC Bootstrap-Boilerplate je Datei):
  - `.skills/nano-banana-image/scripts/find_api_key.py`: 21 LOC importlib-Block durch 5 LOC sys.path-Setup + `from _lib.api_keys import get_api_key` ersetzt.
  - `.skills/openai-image-gen/scripts/generate.py`: identische Vereinfachung.
  - `.skills/nano-banana-image/scripts/generate_image.py`: unverändert (importiert über `find_api_key`-Wrapper, kein direkter `_lib.api_keys`-Bezug).
- **Netto-LoC-Bilanz:** ~32 LOC Bootstrap-Code dauerhaft eliminiert, Lesbarkeit der drei Konsumenten deutlich erhöht.

### Verifikations-Vorbau (disk-verifizierte Schiedsrichter-Korrektur)
- **Probe-Skript-Pass vor Code-Änderung:** Vier Probe-Szenarien (sys.path-Reihenfolge × `__init__.py`-Existenz × `_lib.api_keys` vs `_lib.designsystem`) gegen Python ausgeführt. Belegt:
  - Aktueller Stand: `_lib.api_keys` aus `.skills/_lib/` gewinnt als Regular Package — `_lib.designsystem` nur erreichbar wenn `_lib`-Regular-Package nicht aus `.skills/_lib/` geladen wird (sys.path-fragil).
  - Option A (leere `__init__.py` in Repo-Root-`_lib/`): `_lib.api_keys` wird bei REPO_ROOT-vorne unauffindbar — **Brille-E-Empfehlung war falsch**.
  - Option D (beide Namespace Packages): `_lib.api_keys` UND `_lib.designsystem` funktionieren in allen relevanten Reihenfolgen.
- Probe-Skript als Inline-Bash-Variante dokumentiert, künftige Wellen können den Stand re-validieren.

### Hinzugefügt
- **Memory-Lesson-Persistierung im Vault** unter `02 Projekte/Second Brain Installationspaket/Lessons/` (Wave-II-Backlog #16 + #17 — Konvention etabliert): drei neue Lessons aus v0.17.5:
  - `vier-brillen-final-audit-pattern` (Z/E/B/R disjunkt nach jedem Tag-Push)
  - `library-pfad-vs-cli-pfad-asymmetrie` (Skills mit beiden Pfaden brauchen beide gehärtet)
  - `source-string-path-leak-pattern` (Foundation-Funktionen mit Return-auf-stderr keine absoluten Pfade)
- **Neue Memory-Lesson aus v0.17.6 selbst:**
  - `disk-verifikation-vor-implementierung-bei-namespace-claims` (Brille-E-Korrektur per Python-Probe-Skript) — als 7. Bestätigung von `feedback_schiedsrichter_verifiziert_brille_befund` direkt im Vorgang validiert.

### Aktualisiert
- 29 SKILL.md + `manifest.json` + `bundle.json`: `bundle_version: 0.17.5 → 0.17.6` (Bulk-Bump **10. ad-hoc-Mal** — Wave-II-Backlog `bump_bundle_version.py` weiterhin offen, jetzt höchstpriorisiert).
- `tests/unit/test_no_local_api_key_lookup.py` Allowlist unverändert — beide Wrapper-Funktionen definieren weiter eigenes `def find_api_key(...)`-Symbol.
- `_lib/api_keys.py` Modul-Docstring um Hinweis ergänzt: „Konsumenten importieren via `from _lib.api_keys import ...` direkt (seit v0.17.6 Namespace-Package-Fix)."

### Werte-Bilanz
- pytest **357 passed** unverändert (Sanity vor Tag, real verifiziert nach Refactor).
- Cross-Skill **17/17 PASS** unverändert (2/2 + 2/2 + 5/5 + 8/8).
- Skill-Eval nano-banana 16/16 + openai 16/16 unverändert.
- CLI-Smoke `find_api_key.py` direkt: OK, Länge 39 (Stefan-`.env` korrekt aufgelöst).
- Bundle-Skills **29** unverändert.
- Stefan-Lock-Drift live: 0 Treffer (14 Patterns) unverändert.

### Memory-Lessons (verstärkt / NEU)
- **`feedback_schiedsrichter_verifiziert_brille_befund` (7. Mal):** Brille E empfahl mit hoher Confidence Option A („kleinster Eingriff, eine leere Datei"). Probe-Skript widerlegte das vor Code-Änderung. Erneut belegt: Brille mit Code-Behauptung muss disk-verifiziert werden, gerade wenn die Confidence hoch ist.
- **`feedback_brief_ascii_substitute_drift` (9. Mal):** Ein einziger `fuer`-Drift im neuen Bootstrap-Kommentar von `find_api_key.py` Z. 20. Drift-Wand fing das im pytest-Lauf direkt nach dem Edit. Lesson-Trigger-Liste um „Bootstrap-Kommentar-Vereinfachung" als typischen Drift-Punkt erweitern.

### Wave-II-Backlog (v0.17.6 reduziert)
- **GESCHLOSSEN:** #1 Namespace-Package-Konflikt strukturell lösen.
- **GESCHLOSSEN:** #4 Bootstrap-Helper `.skills/_lib/_bootstrap.py` (entfällt durch direkte Importierbarkeit).
- **GESCHLOSSEN:** #16 Memory-Lessons aus v0.17.4 + v0.17.5 als Topic-Files persistiert (4 Lessons + Index unter `02 Projekte/Second Brain Installationspaket/Lessons/`).
- **GESCHLOSSEN:** #17 Memory-Lesson-Persistierungs-Konvention (Vault-Pfad `02 Projekte/Second Brain Installationspaket/Lessons/` als kanonischer Ort etabliert).
- 13 Items bleiben offen (siehe Handover Wave-II-Backlog v0.17.6).

## [0.17.5] — 2026-05-20 — Vier-Brillen-Final-Audit-Reife (Library-Pfad-Härtung + Pfad-Leak + Doku-Konsolidierung)

Stefan-getriebener Vier-Brillen-Final-Audit-Pass (Z Zahnrad-Fit, E Effizienz, B Blinde Flecken, R Roadmap/Security) lieferte sechs HIGH-Befunde. Schiedsrichter-Konsolidierung: fünf vor Tag, eine Stefan-Klärung offen, mehrere Wave-II-Backlog. **357 passed unverändert**, Cross-Skill **17/17 PASS** unverändert, Bundle-Skills **29** unverändert.

### Gefixt
- **Brille B HIGH — Library-Pfad umging Wave-I-Härtungen:** `openai-image-gen/scripts/generate.py:156` rief direkt `os.environ.get(api_key_env_var)` ohne `.env`-Cascade, ohne `sk-...`-Filter, ohne BOM-Fix auf. Library-Konsumenten (Wave J video-creator via authentic-portrait potentiell) wären unbemerkt von den v0.17.3-Härtungen ausgenommen gewesen. Fix: `get_api_key(api_key_env_var, skill_dir)`-Aufruf inkl. Placeholder-Filter — identisch zum CLI-Pfad-Wrapper.
- **Brille R HIGH — Pfad-Leak in source-String:** `_lib/api_keys.py::get_api_key` Stufe 2 lieferte `source = f"Projekt-.env ({project_env})"` mit absolutem Pfad. `openai-image-gen/generate.py:67` gab source verbatim auf stderr — User-Home-Pfad (`C:\Users\stefa\...`) leakte in CI-Logs / Shared-Terminal. Fix: source auf relativen Marker `"Projekt-.env (CWD)"`. Pin-Test `test_three_tier_cascade_project_env` um Negativ-Assertion ergänzt (kein absoluter Pfad mehr im Source).

### Hinzugefügt
- **Brille Z HIGH — BUNDLE-MODE-READINESS.md Stand-Block für v0.17.3+v0.17.4+v0.17.5:** Drei-Wellen-Konsolidierung mit Refactor-Welle-Klausel, Pin-Test-Bilanz, Drei-Brillen-Konvergenz-Schließungs-Lesson, Vier-Brillen-Final-Audit-Pattern-Validierung. Zwei neue Bereitschaftskriterien: „Lessons-Persistierung als Pflicht-Pre-Tag-Check" und „Stub-Docstring-Diff-Scan vor Tag".
- **Brille Z+R HIGH — FOLGE-WELLEN-ROADMAP.md Einträge für v0.17.3 + v0.17.4 + v0.17.5** ergänzt. v0.18.0-Eintrag erweitert um Co-Migration `elevenlabs-api`, Sub-Skill-Verfügbarkeits-Matrix, realistische Token-Schätzung **2,5-3,5 M** (statt 1,2-1,8 M), expliziter Brillen-Plan, Stefan-Klärungs-Hinweis (`elevenlabs-api`-Vault-Skill existiert aktuell nicht).
- **Brille Z MED — `_lib/api_keys.py` Konsumenten-Liste erweitert:** authentic-portrait als transitiver Konsument (kein direkter Import, Skill-Routing), Wave-J-erwartete Konsumenten (`elevenlabs-api` direkt + `video-creator` transitiv), Wave-II-Backlog-Notiz für `gmi_client.py:55`, explizite Abgrenzung zu `_lib/env_loader.py` (Soft-Cascade vs Hard-Fail).

### Aktualisiert
- 29 SKILL.md + manifest.json + bundle.json: `bundle_version: 0.17.4 → 0.17.5` (Bulk-Bump **9. ad-hoc-Mal** — Wave-II `bump_bundle_version.py` weiterhin offen, jetzt sehr hoch priorisiert).
- `tests/unit/test_no_umlaut_substitutes.py::SCAN_EXCLUDE_FILES` um BUNDLE-MODE-READINESS.md + FOLGE-WELLEN-ROADMAP.md ergänzt (neue Stand-Blocks referenzieren Pattern-Stems `\banschliess` + `\bschuetz` als Beleg-Strings — sonst würden sich die Stand-Blocks selbst triggern).

### Werte-Bilanz
- pytest **357 passed** unverändert (Sanity vor Tag).
- Cross-Skill **17/17 PASS** unverändert.
- Skill-Eval unverändert.
- Bundle-Skills **29** unverändert.

### Brillen-Pässe-Bilanz
- **Vier Final-Audit-Brillen** disjunkt parallel dispatched: Z (Zahnrad-Fit, 5 Achsen), E (Effizienz/Vereinfachung, 5 Achsen), B (Blinde Flecken, 6 Achsen), R (Roadmap+Security, 6 Achsen). 22 Achsen insgesamt, **sechs HIGH** + mehrere MED/LOW.
- Schiedsrichter-Verifikation Brille B HIGH disk-bestätigt (Memory-Lesson `feedback_schiedsrichter_verifiziert_brille_befund` **6. Bestätigung**).
- Vier-Brillen-Pattern als neuer Standard für Refactor-Welle-Final-Audits validiert (analog Wave-I-Drei-Brillen für Bundle-Migration).

### Memory-Lessons (NEU geschmiedet in v0.17.5)
- **Vier-Brillen-Final-Audit-Pattern für Refactor-Wellen:** Zahnrad/Effizienz/Blind/Roadmap als disjunkte Achsen-Achsen-Quartett. Lieferte sechs HIGH bei v0.17.3+v0.17.4-Welle, die das Drei-Brillen-Pre-Tag-Pattern (M-A/M-C/M-E) übersehen hatte. Wave-J-Empfehlung: Vier-Brillen-Final-Audit nach jeder Tag-Push.
- **Library-Pfad-vs-CLI-Pfad-Asymmetrie:** Bei Skills mit beiden Pfaden (CLI plus Library-API) sind die Härtungen oft nur im CLI-Pfad. Brille B muss explizit beide Aufruf-Stellen scannen. v0.17.5 fand das in openai-image-gen — Wave-J `video-creator` orchestriert Sub-Skills via Library-Aufrufen, ist genau dieses Risiko.
- **source-String-Path-Leak-Pattern:** Foundation-Funktionen, deren return-Wert auf stderr/Logs gelangt, dürfen keine absoluten Pfade enthalten. CI-Logs, Shared-Terminals, Bug-Reports leaken User-Home-Pfade sonst.

### Stefan-Klärungen offen (Wave-J-Vorlauf)
- **Vault-`elevenlabs-api`-Skill existiert aktuell NICHT** unter `C:\Users\stefa\OneDrive\03 Resources\00_MySecondBrain_Obsidian\.claude\skills\elevenlabs-api\` (Brille R disk-verifiziert, Glob 0 Treffer). **Entweder Skill vor Wave J anlegen oder Co-Migration verschieben** und Wave J nur als Single-Owner-Welle für `video-creator` planen mit `elevenlabs-api` als Anwender-Vault-Voraussetzung.
- **Struktureller Namespace-Fix:** Repo-Root-`_lib/` hat kein `__init__.py` (Namespace-Package) vs. `.skills/_lib/__init__.py` (Regular). v0.17.3 löste das via `importlib.util.spec_from_file_location` in zwei Konsumenten (~28 LOC Boilerplate). Brille E HIGH: strukturell besser via `__init__.py` in Repo-Root-`_lib/` oder `_lib/designsystem/` nach `.skills/_lib/` migrieren — eliminiert Bootstrap-Code komplett. Stefan-Klärung: ist `_lib/designsystem/` bewusst Namespace?

### Wave-II-Backlog (v0.17.5 erweitert um 4 Items)
- **NEU:** Cross-Skill-Eval `run_api_keys_consistency_eval.py` für Tuple-Vertrag-Symmetrie über alle vier Wrapper (Brille Z HIGH, empfohlen vor Wave-J-Implementer).
- **NEU:** Bootstrap-Helper `.skills/_lib/_bootstrap.py` ODER struktureller Namespace-Fix (Brille E HIGH).
- **NEU:** stderr-ERROR-Helper in `_lib.api_keys.format_lookup_error()` bei drittem Konsumenten (Wave J `elevenlabs-api`).
- **NEU:** `_resolve_env_var_name`-Override-Pfad-Pin-Test (Brille B MED).
- Alle 13 v0.17.3-Wave-II-Backlog-Items bleiben offen.

## [0.17.4] — 2026-05-20 — v0.17.3 Post-Tag-Reife-Patch (Stub-Docstring-ASCII-Drift + Pattern-Wand-Lücke)

Post-Tag-Final-Audit fand zwei ASCII-Substitut-Drifts im neuen `get_elevenlabs_key()`-Stub-Docstring (`_lib/api_keys.py:132-133`): `anschliessen` → `anschließen`, `schuetzt` → `schützt`. Plus: `UMLAUT_SUBSTITUTES_PATTERNS` in `_lib/test_utils.py` enthielt weder `\banschliess` noch `\bschuetz` als Stem — Pre-Tag-Wand-Lauf war grün, aber blind für diese Drifts. Wave J würde den Stub-Wortlaut direkt erben. Reife-Patch vor Wave-J-Start zwingend.

### Gefixt
- `.skills/_lib/api_keys.py:132-133` Stub-Docstring: zwei ASCII-Substitut-Drifts (`anschliessen`/`schuetzt`) auf echte Umlaute (`anschließen`/`schützt`) korrigiert. Memory-Lesson `feedback_brief_ascii_substitute_drift` **8. Mal** in Folge.

### Hinzugefügt
- `.skills/_lib/test_utils.py::UMLAUT_SUBSTITUTES_PATTERNS`: zwei neue Stem-Patterns `\banschliess` (deckt anschließen/Anschluss) und `\bschuetz` (deckt schützt/Schutz/schützen). Sichert künftige Wave-J-Stubs gegen denselben Drift.

### Aktualisiert
- 29 SKILL.md + manifest.json + bundle.json: `bundle_version: 0.17.3 → 0.17.4` (Bulk-Bump 8. ad-hoc-Mal).

### Werte-Bilanz
- pytest **357 passed** (unverändert, neue Patterns sind grün gegen die korrigierten Strings).
- Cross-Skill **17/17 PASS** unverändert.
- Bundle-Skills **29** unverändert.

### Memory-Lessons (NEU geschmiedet aus Post-Tag-Audit v0.17.3)
- **Stub-Docstring-Drift-Falle:** Wave-Vorbereitungs-Stubs sind „kalt" (kein Konsument), Funktions-Pin-Tests prüfen sie nicht inhaltlich. Pre-Tag-Brille muss explizit Diff-Bereich nach neuen ASCII-Substitut-Stems durchsuchen, nicht nur Wand-Lauf-PASS akzeptieren.
- **Drift-Wand-Stem-Vollständigkeit:** Jeder neue Substitut-Stem aus aktiver Welle braucht Positiv-Pin in `_lib/test_utils.py`. v0.17.4 verankert das als Pflicht-Pre-Tag-Check für künftige Wellen.
- **Vault-Handover-Sub-Skill-Vollständigkeits-Check:** Wenn Vault-SKILL N Sub-Skills nennt, Handover-Sub-Dep-Klassifikation muss alle N benennen, nicht nur die Wave-relevanten N-1. Post-Tag-Brille bemerkte: `natur-sprech-check` (10. Sub-Skill in `video-creator`-Vault-Werkzeugkasten) fehlt im Handover-Punkt-4 — bereits Bundle-Skill, deshalb kein Wave-J-Migrations-Risiko, aber Wave-J-Spec-v1 sollte Cross-Skill-Eval-Kandidat `video_creator_consumes_natur_sprech_check_for_tts` erwägen.

### Wave-II-Backlog (unverändert + 1 neu)
- Alle 12 Wave-II-Backlog-Items aus v0.17.3 bleiben offen.
- **NEU:** Negativer Pin-Test in `tests/unit/test_no_umlaut_substitutes.py`, der explizit `anschliessen` und `schuetzt` als Pflicht-Fehlschlag-Strings testet (zusätzliche Schicht über Pattern-Wand).

## [0.17.3] — 2026-05-20 — Refactor-Welle `_lib/api_keys.py` (Drei-Brillen-Konvergenz-Schließung)

Refactor-Welle vor Wave J. Schließt die Drei-Brillen-Konvergenz aus v0.16.3 (E-1-01 + MH-H4-05 + Pre-Tag-M-K-04) durch zentrale `_lib/api_keys.py` als Single Source für API-Key-Lookup. Drei konkrete Bugs in `openai-image-gen/scripts/generate.py::_read_key_from_env` gefixt. Lokale 1-stufige Kopie in `nano-banana-image/scripts/generate_image.py:81-90` plus dortige `_resolve_env_var_name`-Duplikation entfernt. Wave-J-Vorbereitung: `get_elevenlabs_key()`-Stub bereit für `elevenlabs-api`-Bundle-Migration in v0.18.0. Charakter: Hauptagent-deterministisch (S7), keine Owner-Welle. Drei Brillen Pre-Tag (M-A Architektur, M-C Konsistenz, M-E Effizienz/Doku) plus Critic-Pass auf Spec v1 (7 Brillen-Achsen, 4 HIGH-Edits in Spec v2 abgeräumt).

### Hinzugefügt
- **`.skills/_lib/api_keys.py`** mit fünf Public-Funktionen (`read_key_from_dotenv`, `get_api_key`, `get_gemini_key`, `get_openai_key`, `get_elevenlabs_key`) und `__all__`-Export. Sicherheits-Regel im Modul-Docstring: Key-Wert verlässt nie das Modul.
- **`tests/unit/test_api_keys_lib.py`** mit **zwölf** Pin-Tests in vier Gruppen: Drei-Bug-Pins (BOM, Prefix-`=`, symmetrischer Quote), Drei-Stufen-Cascade (4 Pins), Edge-Cases (Comment-Skip, `=`-im-Wert, Empty-Value-Skip, Empty-Quoted-Value), Spezialisierungs-Wrapper-Env-Var-Mapping.
- **`tests/unit/test_no_local_api_key_lookup.py`** Drift-Wand-Test mit Per-File-Allowlist (`ALLOWED_PATTERNS_PER_FILE` für `_lib/api_keys.py`, `nano-banana-image/scripts/find_api_key.py`, `openai-image-gen/scripts/generate.py`). Schützt vor lokaler Re-Implementierung von `_read_key_from_env` oder `find_api_key`.
- **Spec v2** unter `.maintainer/docs/V0.17.3-API-KEYS-REFACTOR-SPEC.md` (Format-Vorbild Wave-I-Spec v3).
- **`__all__`-Liste** in `_lib/api_keys.py` schützt Wave-J-Stub `get_elevenlabs_key` vor Dead-Code-Cleanup.

### Gefixt
- **E-1-01 / MH-H4-05 / Pre-Tag-M-K-04 (Drei-Brillen-Konvergenz):** Drei Bugs in `openai-image-gen/scripts/generate.py::_read_key_from_env` inhärent durch zentrale Lib gefixt:
  - **UTF-8-BOM-Strip-Fehlen:** Zeile 74 hatte `encoding="utf-8"` statt `"utf-8-sig"` → BOM `EF BB BF` machte erste Zeile unparsbar. Zentrale Lib nutzt `utf-8-sig`.
  - **Prefix-Match ohne `=`-Suffix:** Zeile 77 hatte `startswith(env_var_name)` ohne `"="`-Suffix → `OPENAI_API_KEY_BACKUP=wrong` matchte bei Suche nach `OPENAI_API_KEY`. Zentrale Lib prüft `startswith(var_name + "=")`.
  - **Asymmetrischer Quote-Strip:** Zeile 80 hatte `.strip('"').strip("'")` → `KEY="value'` wurde fälschlich auf `value` getrimmt. Zentrale Lib prüft `value[0] == value[-1] and value[0] in ('"', "'")`.
- **Lokale 1-stufige Kopie entfernt:** `nano-banana-image/scripts/generate_image.py` Zeilen 61-90 (lokales `_resolve_env_var_name` + 1-stufiges `find_api_key`) durch Re-Import aus `find_api_key.py` ersetzt. Damit konsumieren beide Aufrufstellen (`:571` und `:686`) die volle Drei-Stufen-Cascade.
- **Vier eigene ASCII-Substitut-Drifts** im Refactor selbst (Memory-Lesson `feedback_brief_ascii_substitute_drift` **7. Mal**): `Schliesst` → `Schließt` in api_keys.py:4; `weiss` → `weiß` in find_api_key.py:61; `Schluessel` → `Schlüssel` in Spec Z. 266; `fuer` → `für` in generate.py:28. Vor Tag-Push abgeräumt.

### Aktualisiert
- 29 SKILL.md + `manifest.json` + `bundle.json`: `bundle_version: 0.17.2 → 0.17.3` (Bulk-Bump zum **7. Mal ad-hoc** — Wave-II-Backlog `bump_bundle_version.py` weiterhin offen).
- `tests/unit/test_no_umlaut_substitutes.py::SCAN_EXCLUDE_FILES`: Eintrag für `V0.17.3-API-KEYS-REFACTOR-SPEC.md` ergänzt (Symmetrie zur Wave-I-Konvention plus Schutz gegen künftige Pattern-Stem-Erweiterungen wie `Paesse`).
- Drei Konsumenten migriert:
  - `nano-banana-image/scripts/find_api_key.py` Wrapper mit Self-Resolve + skill.config.yaml-Override-Erhalt, delegiert via `_lib.api_keys.get_api_key`. Über `importlib.util.spec_from_file_location` robust gegen Cross-Skill-Eval-sys.path-Setup.
  - `openai-image-gen/scripts/generate.py` Wrapper mit OpenAI-spezifischem `sk-...`-Placeholder-Filter und striktem `sys.exit(1)`-Vertrag (Backwards-Compat zum CLI).
  - `nano-banana-image/scripts/generate_image.py` Re-Import aus Wrapper-Datei.

### Werte-Bilanz
- pytest tests/: **344 → 357 passed** (+13: 12 Pin-Tests + 1 Drift-Wand-Test). Real verifiziert.
- Cross-Skill **17/17 PASS** unverändert (4 Suiten: 2+2+5+8).
- Skill-Eval: nano-banana-image 16/16 + openai-image-gen 16/16 PASS unverändert.
- Bundle-Skills **29** unverändert.
- Stefan-Lock-Drift live unverändert.

### Memory-Lessons (neue Erkenntnisse aus v0.17.3)
- **`feedback_brief_ascii_substitute_drift` (7. Bestätigung):** Vier eigene Drifts in einer Refactor-Welle (`Schliesst`, `weiss`, `Schluessel`, `fuer`). Memory-Lesson zum 7. Mal angewendet — Pre-Tag-Audit Pflicht-Filter.
- **Namespace-Package-Konflikt zwischen Repo-Root-`_lib/` (kein `__init__.py`, Namespace) und `.skills/_lib/` (Regular mit `__init__.py`)** als neue Lesson: Cross-Skill-Evals manipulieren sys.path so, dass `from _lib.api_keys import` je nach Reihenfolge fehlschlägt. Robuste Lösung: `importlib.util.spec_from_file_location` mit absolutem Pfad. Strukturelle Auflösung als Wave-II-Backlog.
- **Critic-Pass auf Spec v1 vor Implementer (Memory-Lesson `feedback_spec_first_vor_code` + `feedback_spec_first_multi_reviewer_validiert`):** 4 HIGH-Befunde in Spec v1 abgeräumt vor Code-Schreiben — geschätzte Ersparnis 20+ K Token gegenüber HIGH-Fund im Code.
- **Schiedsrichter verifiziert Brillen-HIGH disk (Memory-Lesson `feedback_schiedsrichter_verifiziert_brille_befund` 4×):** M-E HIGH 1 (CHANGELOG fehlt) und HIGH 2 (SCAN_EXCLUDE_FILES-Eintrag) beide disk-bestätigt vor Edit.

### Wave-J-Vorbereitung
- **`get_elevenlabs_key()`-Stub** in `_lib/api_keys.py` Zeile 129-136 mit `TODO(wave-j v0.18.0)`-Marker. Pin-Test `test_specialization_wrappers_use_correct_env_var_names` schützt Env-Var-Name (`ELEVENLABS_API_KEY`) und Signatur. Sub-Dep-Triage-Entscheidung aus Handover-Punkt 4 (Stefan 2026-05-20): `elevenlabs-api` als Co-Skill-Migration in Wave J (Phase-1-Scribe-Pfad-Pflicht).
- **Bundle-Skills-Roadmap:** v0.18.0 (Wave J video-creator + elevenlabs-api) → 29 → 31 Bundle-Skills.

### Wave-II-Backlog (konsolidiert aus drei Pre-Tag-Brillen + Critic-Pass)
- **Namespace-Package-Konflikt strukturell lösen:** Repo-Root-`_lib/` (kein `__init__.py`) mit `.skills/_lib/` (Regular) mergen — entweder `__init__.py` in Repo-Root oder `_lib/designsystem/` migrieren (M-A).
- **`generate_image.py:69-72` sys.path-Audit** auf tatsächliche Notwendigkeit nach Refactor (M-A).
- **Wrapper-Rename:** `find_gemini_api_key()` / `find_openai_api_key()` für Cross-Skill-Klarheit (M-A).
- **`test_no_local_api_key_lookup.py` Allowlist-Aufräumung:** Pattern für `_lib/api_keys.py` enthalten beide Patterns obwohl Datei aktuell weder `_read_key_from_env` noch `find_api_key` definiert (defensiv vs. inkonsistent) (M-C).
- **Pin-Test `_resolve_env_var_name`-Override-Pfad:** vier Fälle (skill.config.yaml fehlt, yaml-ImportError, valide Override, leerer Value) (M-C).
- **Ast-basierter Drift-Wand-Scan:** Pattern-Schutz aktuell symptom-basiert (Funktionsname), semantische Drift via Umbenennung (z.B. `def load_api_key`) fällt durch (M-E).
- **source-String absolute-Pfad-Klarstellung** in Modul-Docstring oder Pfad-Strip in `_lib/api_keys.py::get_api_key` Stufe 2 (M-E).
- **`read_key_from_dotenv` → private (`_read_key_from_dotenv`)** und aus `__all__` entfernen (kein externer Konsument) (M-E).
- **Drift-Wand-Pattern um `read_key_from_dotenv`** erweitern (aktuell nur alter Name `_read_key_from_env`) (M-E).
- **`bump_bundle_version.py` Maintainer-Skript:** 7× ad-hoc nach v0.17.3 — Wave-II hochpriorisiert.
- **`run_api_keys_consistency_eval.py`** Cross-Skill-Suite (optional, Tuple-Vertrag-Symmetrie).
- **`getmyinvoices/scripts/gmi_client.py:55`** auf `_lib.api_keys` migrieren falls Drei-Stufen-Fallback erwünscht.

## [0.17.2] — 2026-05-20 — Wave I Final-Audit-Reife-Patch (SCAN-Logik-Bug)

Pflicht-Fix-Welle nach Drei-Brillen-Final-Audit (α Repo-Konsistenz + β Vault-Layer-Pflege + γ Wave-J-Vorbereitungs-Lücken). Brille α fand: pytest tatsächlich 343 passed + 1 failed (nicht 344/0 wie in v0.17.1-Tag-Message + CHANGELOG + BUNDLE-MODE-READINESS dokumentiert). Ursache: SCAN_TARGETS-Iterator in `tests/unit/test_no_umlaut_substitutes.py::_iter_files()` umging die `SCAN_EXCLUDE_FILES`-Prüfung bei direkten File-Targets (CHANGELOG.md). Damit triggerten die in v0.17.1 hinzugefügten Pattern-Stems sich selbst über die Pattern-Erweiterungs-Beschreibung im CHANGELOG.

### Gefixt
- **Iterator-Bug in `tests/unit/test_no_umlaut_substitutes.py::_iter_files()`**: `SCAN_EXCLUDE_FILES`-Check für direkte File-Targets ergänzt (analog zur Dir-Scan-Branche). Sonst sind via SCAN_EXCLUDE freigegebene Doku-Files wie CHANGELOG.md blind.
- **CHANGELOG.md zu `SCAN_EXCLUDE_FILES`** ergänzt (Reife-Patch-Beschreibungen thematisieren Pattern-Stems als Beleg-Strings).
- **Drei Final-Audit-Brillen-Files α/β/γ zu `SCAN_EXCLUDE_FILES`** ergänzt (analog zu den anderen Wave-I-Audit-Trail-Files, die schon dort waren).

### Aktualisiert
- 29 SKILL.md + manifest.json + bundle.json: `bundle_version: 0.17.1` → `0.17.2` (Bulk-Bump zum 6. Mal ad-hoc — Wave-II-Backlog `bump_bundle_version.py` weiterhin offen).

### Werte-Bilanz
- pytest **344 passed**, 0 failed (jetzt real bestätigt, nicht nur behauptet).
- Cross-Skill **17/17 PASS** unverändert.
- Skill-Eval **44/44 PASS** unverändert.
- Stefan-Lock-Drift live: **0 Treffer** (14 Patterns) unverändert.
- Bundle-Skills **29** unverändert.

### Memory-Lessons (neue Erkenntnisse aus Final-Audit)
- **„Drift zwischen pytest-Lauf-Werten und Doku-Werten"** als Risiko-Pattern verankern: Wenn nach Edits an Test-Pattern-Konstanten plus Edits an Doku-Files (CHANGELOG) nicht **danach** pytest läuft, kann die Doku Patterns triggern, die im selben Commit erst aktiviert wurden. Wave-J-Lesson: Final-Pytest-Lauf **nach** allen CHANGELOG/READINESS/ROADMAP-Edits Pflicht-Gate vor Commit.
- **„Test-Iterator-Pfad-Asymmetrie"** als Health-Brille-Achse für Wave J: Direkte File-Targets vs. Dir-Scan-Targets in pytest-Lints. Symmetrie-Check als Wave-II-Backlog.
- **Final-Audit nach Tag-Push als Pflicht-Schicht**: Wave I hatte 11 Brillen-Pässe vor Tag, aber der Iterator-Bug + Tag-Message-ASCII-Drift wurden erst im Post-Tag-Final-Audit gefangen. Wave-J-Empfehlung: Final-Audit-Welle nach `git push origin` als verbindlicher Schritt.

### Wave-J-Vorbereitungs-Befunde aus Brille γ
- **`_lib/api_keys.py`-Refactor als harte Wave-J-Sperre** (Drei-Brillen-Konvergenz aus v0.16.3): Vault-`video-creator` konsumiert `nano-banana-image` direkt und `authentic-portrait` (transitiv ebenfalls Image-API). Refactor vor Wave-J-Spec-v1 nötig — es sei denn Wave-J-Spec klauselt Phase-1-Bild-API-Ausschluss explizit.
- **Sub-Dep-Triage Bundle-vs-extern**: Vault-`video-creator` listet 10 Sub-Skills, manifest.json bestätigt nur 3 als Bundle-Skills. Sieben weitere (`elevenlabs-api`, `text-to-speech`, `fal-ai-video`, `kling-video-skill`, `veo-video-generator`, `remotion`, `brand`, `claude-design`) sind Vault-only — Wave-J-Spec muss Bundle-vs-extern verbindlich klassifizieren.

### Wave-II-Backlog (Final-Audit erweitert)
- Test-Iterator-Symmetrie-Audit für alle Drift-Wand-Tests (über `test_no_umlaut_substitutes` hinaus).
- Doku-Werte-Disk-Sync-Test als neue Cross-Skill-Eval (CHANGELOG + READINESS-Stand + Tag-Message gegen reale pytest/Cross-Skill-Outputs).
- Memory-Lesson-Persistierungs-Konvention (Lessons-Ordner unter `02 Projekte/Second Brain Installationspaket/Lessons/`?).
- Welle-1-Readiness-Vault-Roll-up auf 25/25 (Brille β LOW).
- Token-Realismus-Zähler-Bridge-Doku zwischen Session-Logs (Drift 12× vs. 14×).

## [0.17.1] — 2026-05-20 — Wave I Reife-Patch (Post-Tag-Audit-Konvergenz)

Pflicht-Fix-Welle nach Vier-Brillen-Post-Tag-Audit (WG-L7-Pattern zum 6. Mal: M-H Health/Security + M-E Effizienz + M-K-vertieft Konsistenz + M-G Gesamt-Konstrukt). Drei HIGH-Befunde:

### Gefixt
- **M-K-HIGH-1 Bundle-Vault-Identity-Leak (Stefan-Lehnisch-Hardcoding):** Acht Stellen Stefan-Lehnisch-Hardcoding im Bundle-Skill und der Foundation. `scripts/neue_praesentation.py:127` (HTML-Title-Suffix) entfernt — generierte Bundles haben keinen Anwender-Namen mehr im HTML-Title. Foundation `_lib/designsystem/templates/praesentation/src/slides-a.jsx` und `slides-b.jsx`: sieben `alt="Stefan Lehnisch"`-Logo-Tags auf `alt="Logo"` umgestellt, Demo-Personen-Namen auf fiktiven Default `Max Mustermann` umgestellt. Pattern-Erweiterung in `BUENDEL_I_PRIVATE_PATTERNS_NEUE_PRAESENTATION`: neuer Eintrag `r"\bLehnisch\b"` — verhindert künftige Drift.
- **M-K-HIGH-2 ASCII-Substitute in `update_lint.py`:** Drei Stellen mit `Verstoesse`/`laeuft`/`Verstoss` als ae/oe/ue-Substitute, die per `--install-hook` in jedes Anwender-`build.cmd`/`build.sh` wandern. Auf echte Umlaute `Verstöße`/`läuft` umgestellt. Pattern-Erweiterung in `UMLAUT_SUBSTITUTES_PATTERNS`: neue Stems `\bverstoess` und `\blaeuft` — Test-Pattern-Set-Lücke geschlossen.
- **M-G-HIGH-1 Profil `beratung` Drift:** `bundle.json::profiles` listete `beratung`, `manifest.json::theme_profiles` nicht — Funktionsbruch bei Anwender-Aktivierung des Profils. `theme_profiles.beratung`-Eintrag ergänzt mit konsistenter Description.
- **Cross-Skill-Eval-Robustheit:** `run_audit_bundle_fingerprint_eval.py::neue_praesentation_referenced_in_manifest_json` hardcodete `bundle.version == "0.17.0"` — generalisiert auf `startswith("0.17.")` für Reife-Patches.
- **SCAN_EXCLUDE_FILES erweitert:** 11 Wave-I-Audit-Trail-Dateien (Phase-3-Brillen P1/P2/P3, Owner-Brief, Pre-Tag M-A/M-C/M-E, Post-Tag M-H/M-E/M-K/M-G) — diese thematisieren Pattern-Strings als Beleg und müssen vom globalen Umlaut-Test ausgenommen werden.

### Aktualisiert
- 29 SKILL.md + manifest.json + bundle.json: `bundle_version: 0.17.0` → `0.17.1` (Bulk-Bump zum 5. Mal ad-hoc — Wave-II `bump_bundle_version.py`).

### Werte-Bilanz
- pytest **344 passed**, 0 failed (unverändert).
- Cross-Skill **17/17 PASS** (8/8 in Audit-Bundle-Fingerprint nach Generalisierung).
- Skill-Eval **44/44 PASS** unverändert.
- Stefan-Lock-Drift live: **0 Treffer** (jetzt 14 Patterns nach `\bLehnisch\b`-Erweiterung).
- Bundle-Skills 29 unverändert.

### Memory-Lessons
- `feedback_reviewer_brille_disk_false_positive` (Disk-Verifikation vor Fix-Pflicht): Vier Brillen-HIGH-Behauptungen alle disk-verifiziert vor Fix.
- `feedback_schiedsrichter_korrigiert_sub_fp`: M-G sagte 6 Skills mit `beratung: true`, real nur 1 — Schiedsrichter korrigiert vor Fix-Bemessung.
- `feedback_drei_bruellen_konvergenz_refactor_welle`: M-E entdeckte **vier-fache** Playwright-Duplikation (`print_to_pdf.py` + `print_to_a4_pdf.py` + `_lib/designsystem/compose.py` + `compose_v.py`) — eigenständige Wave-II-Refactor-Welle (`_lib/designsystem/_pdf_render.py`).
- `feedback_brief_ascii_substitute_drift` (6. Mal): Bundle-Code-Drift in `update_lint.py` blieb von Pattern-Set-Lücke geschützt — Pattern-Erweiterung ist die Schließung.
- `feedback_wgl8_fp_zwischen_bruellen`: M-H meldete drei Pfad-Hypothesen, alle drei disk-widerlegt vor Befund-Aufnahme.

### Wave-II-Backlog (aus Post-Tag-Audit erweitert)
- 4-fache Playwright-Duplikation → `_lib/designsystem/_pdf_render.py` zentral (Drei-Brillen-Konvergenz, eigenständige Refactor-Welle).
- `update_lint.py` CHECKS-Liste hat keine Umlaut/Natur-Sprech/Glossar-Lints obwohl Skill-Body als Pflicht-Gates dokumentiert (drei Sub-Items).
- `karpathy` Profil-Drift bundle.json vs theme_profiles (andere Richtung als beratung).
- `bump_bundle_version.py` Maintainer-Skript (6× ad-hoc nach v0.17.1).
- Cross-Skill `run_manifest_path_consistency_eval.py` für Naming-Drift-Schutz.
- `SCAN_EXTENSIONS` in test_no_umlaut_substitutes auf `.jsx`/`.js` erweitern.
- Tag-Message-Drift „Paesse"/„Pässe" (irreversibel nach v0.17.0-Push, Pre-Tag-Brille-Lesson für Wave J).

## [0.17.0] — 2026-05-20 — Wave I komplett (neue-praesentation Bundle-Migration)

Wave-I-Marathon-Welle über zwei Sessions 2026-05-19/-20 mit Spec-Härtung, Phase A (Hauptagent-Deterministisch), Phase A Reife-Fix nach Drei-Brillen-Audit, Phase B (Owner-Implementer + Reife-Fix nach Owner-Return), Vor-Tag-Audit (3 disjunkte Brillen M-A/M-C/M-E) und Pflicht-Fix-Welle vor Tag-Push. Insgesamt **elf Brillen-Pässe** (3 Pre-Dispatch + 3 Phase-3 + 3 Vor-Tag + Critic + Self-Review), 0 CRIT in jeder Welle nach Schiedsrichter-Pass.

### Hinzugefügt
- `.skills/neue-praesentation/SKILL.md` mit Wave-H-konformem Frontmatter (`bundle_skill: true`, `scope: vault`, `depends_on: [natur-sprech-check]`, 6 default_active-Profile, 12 trigger_words, `allowed-tools` mit Edit+Write), H1-Header `# Neue Präsentation` und Body mit Pflicht-Reads `{context}`-Pattern, BUNDLE_ROOT-Resolver, vier Modi-Übersicht, Modus-Audit-Bundle-Fingerprint-Vertrag, Hinweis auf separaten Anwender-Vault-Skill `webseiten-audit` als Voraussetzung für Modus Audit.
- `_lib/designsystem/templates/praesentation/` als Foundation-Erweiterung: 13+ Dateien (Layout-Regeln.md, Praesentation Template.html, theme.css + theme-a4.css, deck-stage.js, 4 kompilierte JS, 4 JSX-Quellen in src/, vendor/ mit React + 8 woff2, build.cmd + build.sh, WarmNavigator.potx, 6 Default-Logos in assets/, README.md).
- 6 Helper-Skripte unter `.skills/neue-praesentation/scripts/` (snake_case): neue_praesentation.py, update_lint.py, echo_helper.py, print_to_pdf.py, print_to_a4_pdf.py, check_audit_bundle_filled.py.
- 5 Eval-Blöcke unter `.skills/neue-praesentation/eval/` mit insgesamt **44 Assertions** (Modus Neu 10, Update 8, Echo 9, Audit 11 inkl. Exit-12-Mock + Hash-Determinismus, Pflicht-Reads 6 inkl. Stefan-Lock-Drift-Brille).
- 6 Drift-Wand-Tests unter `tests/unit/` (Tokens-Isolation, Glossar-Compliance, Demo-Natur-Sprech, Templates-Präsenz, Helpers-Präsenz mit 6-Helper-Verifikation, JSX-JS-Parity).
- Neue Cross-Skill-Eval-Suite `.skills/_cross_skill_evals/run_audit_bundle_fingerprint_eval.py` mit 8 Assertions (Hash-Code-Block, Manifest-Schema, Exit-12, Helper-Existenz, Manifest-Eintrag, Modus-Karte, Hash-Determinismus, Stefan-Lock-Isolation).
- `BUENDEL_I_PRIVATE_PATTERNS_NEUE_PRAESENTATION` (13 Patterns nach Reife-Fix-Reklassifikation, WarmNavigator.potx als Foundation-Asset entfernt) und `GLOSSAR_DEMO_NAMES` (9 Falsch/Korrekt-Tupel) in `.skills/_lib/test_utils.py`.
- AGENTS.md-Zeile für neue-praesentation in `.templates/default/AGENTS.md`.
- `.skills/neue-praesentation/requirements.txt` mit `playwright>=1.40,<2.0`.
- Owner-Brief unter `.maintainer/docs/V0.17.0-WAVE-I-PHASE-B-OWNER-BRIEF.md` als Audit-Trail-Artefakt persistiert.

### Aktualisiert
- `manifest.json`: neue-praesentation alphabetisch eingefügt, `manifest.bundle.version: 0.17.0`.
- `bundle.json`: `version: 0.17.0`, `released: 2026-05-20`.
- 29 SKILL.md (28 existierende + 1 neu): `bundle_version: 0.17.0` via Python-Inline-Bulk-Bump (Pattern zum 5. Mal ad-hoc — Wave-II-Backlog `bump_bundle_version.py` Maintainer-Skript).
- `tests/unit/test_no_umlaut_substitutes.py::SCAN_EXCLUDE_FILES`: 7 Wave-I-Doku-Einträge (Defense-in-Depth).
- Spec §1 Healthcheck-Befehl um vierten Cross-Skill-Aufruf `run_audit_bundle_fingerprint_eval.py` erweitert (P3.3-03 MED-Fix nach Phase-3-Audit).
- `.maintainer/docs/V0.17.0-WAVE-I-STEFAN-LOCK-CONTRACT.md`: Reife-Fix-Reklassifikations-Vermerk für Pattern 12 `WarmNavigator.potx` (Foundation-Asset, kein Stefan-Privates).
- FOLGE-WELLEN-ROADMAP.md: v0.19.0-Drift zu v0.18.0 (Wave J video-creator) konsolidiert, Konsens mit Spec §11 und BUNDLE-MODE-READINESS.

### Gefixt
- Phase-A-Reife-Fix nach Drei-Brillen-Audit P1/P2/P3 (HEAD `c1da63a`):
  - P2.1-H-01: `neue_praesentation.py` Pfad-Resolver auf BUNDLE_ROOT/FOUNDATION umgestellt (vorher VAULT_ROOT-Bug).
  - P1.2-01: 10 hardkodierte Vault-Pfade in 4 Modus-Karten auf Bundle-Konventionen umgestellt.
- Phase-B-Reife-Fix nach Owner-Return (HEAD `65e9f0f`):
  - Stefan-Lock-Drift in vier Modus-Karten saniert (32 Roh-Treffer in 15 distinct File-Pattern-Paaren): motogadget → Mustermann GmbH, D4 → MUST-1, Vault-Pfade auf Platzhalter (`<projekt-beratung>`, `<webseiten-audit-root>`, `{context}/Glossar`, `<webseiten-audit-skill>/`).
  - WarmNavigator.potx aus Stefan-Lock-Pattern-Konstante entfernt (Klasse-3-FP, Foundation-Asset).
  - Helper-Docstring `scripts/neue_praesentation.py:11` generalisiert.
  - Owner-Brief ASCII-Substitute in 5 Stellen gefixt.
- Pflicht-Fix-Welle nach Vor-Tag-Audit:
  - SKILL.md fehlender H1-Header ergänzt (M-E HIGH, machte `test_skill_description_redundancy.py` vacuous-PASS).
  - Stefan-Lock-Contract-Doku-Drift-Vermerk angebracht (M-C MED).
  - Roadmap v0.18.0/v0.19.0-Konsolidierung (M-E MED).
  - SKILL.md „Was nicht macht"-Sektion um webseiten-audit-Dep-Hinweis ergänzt (M-A LOW).

### Bilanz
- **pytest tests/: 330 → 344 passed**, 0 failed (+14 über zwei Phasen).
- **Cross-Skill: 9/9 → 17/17 PASS** (vierte Suite `run_audit_bundle_fingerprint_eval.py` mit 8/8 PASS aus Phase B).
- **Skill-Eval-Suiten: 0 → 44/44 PASS** (5 Eval-Blöcke aus Phase B).
- **Stefan-Lock-Drift live: 0 Treffer** (13 Patterns geprüft nach Reklassifikation).
- **Bundle-Skills: 28 → 29**, `bundle_version: 0.17.0`.
- Elf Brillen-Pässe insgesamt (Critic + Self-Review + 3 Pre-Dispatch A/C/E + 3 Phase-3 P1/P2/P3 + 3 Vor-Tag M-A/M-C/M-E).
- Token-gesamt-Welle: ~1,8-2,1 M real (Phase A ~1,1-1,3 M + Phase B Owner ~0,3 M + Phase-B-Reife-Fix ~0,1 M + Vor-Tag-Audit ~0,4 M + Pflicht-Fix-Welle + Phase 6 ~0,1 M).

### Wave-II-Backlog (NICHT in Wave I gezogen)
- Drei-Brillen-Konvergenz `_lib/api_keys.py`-Refactor (aus v0.16.3 weiter offen).
- `print_to_pdf.py` + `print_to_a4_pdf.py` Playwright-Logik-Extraktion in `_scripts_common.py` (~25-35 Zeilen Duplikation).
- `update_lint.py` Umlaut-Lint-Erweiterung (UMLAUT_SUBSTITUTES_PATTERNS in CHECKS einbinden).
- linkedin-finalize + linkedin-carousel ohne `allowed-tools`-Frontmatter-Vollständigkeit (Wave-H-Defizit P3.1-01).
- `bundle.json::external_global_recommendations.content` listet nano-banana-image/openai-image-gen als „external" obwohl Bundle-Skills (Wave-G-Altlast P3.4-01).
- `feedback_brief_ascii_substitute_drift`-Pre-Dispatch-Auto-Grep als formaler Phase-0-Schritt verankern.
- `bump_bundle_version.py` Maintainer-Skript (E-4-01, 5× ad-hoc benutzt).
- `_case_variants`-Helper für `SS_STATT_BETA_PATTERNS` + `GLOSSAR_DEMO_NAMES` (E-1-03/E-2-02).
- AGENTS.md-Sortier-Konvention konsolidieren (Hauptblock alphabetisch bis `session-log`, danach Anhängsel-Konvention — MC-2).
- Spec-interner Text-vs-Bullet-Drift (Z. 457 sagt „Drei Einträge", listet sechs — MC-3).

## [0.16.3] — 2026-05-19 — Wave I Post-Tag-Multi-Brillen-Audit-Folge-Patch (Foundation-Pillow-Pin)

### Anlass
Vier-Brillen-Post-Tag-Audit nach v0.16.2 (Wave-H-WG-L7-Pattern zum 5. Mal: M-H Health/Security + M-E Effizienz/Vereinfachung + M-K-vertieft Konsistenz/Drift + M-G Gesamt-Konstrukt/Zahnrad). Brille M-G fand einen MED-Befund, der bei der v0.16.2-Pillow-CVE-Bump-Welle (H.4-01) übersehen worden war: `_lib/designsystem/requirements.txt` pinnte `Pillow>=10.0.0,<12.0.0` statt `>=10.4.0,<12.0.0`. Foundation-Library, die linkedin-finalize, linkedin-carousel, authentic-portrait und der nächste Wave-I-Skill `neue-praesentation` konsumieren — also Foundation-Layer-CVE-Anfälligkeit auf Systemen mit Pillow 10.0–10.3. Wave-G-C-07-Heuristik (singularer MED + Konvergenz zu H.4-01) löst Reife-Patch trotz singularem Befund aus.

### Gefixt
- **G2-02 Foundation-Pillow-Pin-Drift:** `_lib/designsystem/requirements.txt` von `Pillow>=10.0.0,<12.0.0` auf `Pillow>=10.4.0,<12.0.0` angehoben. Konsistenz zum Wave-H-Skill-Stack-Pin-Wert hergestellt.

### Hinzugefügt
- **Pin-Test `tests/unit/test_pillow_pin_consistency.py`:** Greppt alle Bundle-`requirements.txt` (.skills/*/, _lib/*/) nach Pillow-Pins und stellt sicher, dass die Lower-Bound mindestens 10.4.0 fordert. Schützt gegen künftige Drift, falls ein Maintainer pillow auf eine ältere Lower-Bound senkt.

### Schiedsrichter-Korrektur an Brille M-K Pre-Tag (FP-Verifikation)
Brille M-K Pre-Tag v0.16.2 hatte für Achse 4 (Pillow-Konsumenten-Vollständigkeit) verbatim festgestellt: „`_lib/designsystem/requirements.txt` existiert nicht im Repo". Brille M-G Post-Tag fand: die Datei existiert unter `_lib/designsystem/requirements.txt` (Repo-Root-Layout), nicht unter `.skills/_lib/designsystem/`. Pfad-Hypothese der Pre-Tag-Brille war falsch. Memory-Lesson `feedback_sandbox_halluzination_check_wg_l4` zum 5. Mal: auch Audit-Brillen-Pfad-Annahmen brauchen Disk-Verifikation.

### Bilanz
- pytest tests/: 329 → **330 passed** (+1 Pillow-Pin-Konsistenz-Test).
- Cross-Skill **9/9 PASS** (unverändert): Bundle-Schema 2/2 + Image-Wave-G 2/2 mit M-A-02 4 Sub-Checks + Linkedin-Wave-H 5/5.
- Bundle-Skills **28** (unverändert), `bundle_version: 0.16.3`.

### Wave-II-Backlog (konsolidiert aus dem Post-Tag-Audit)
Vier Brillen-Befunde, die als Wave-II-Refactor-Welle gebündelt werden (Drei-Brillen-Konvergenz auf API-Key-Lookup-Refactor):
- **E-1-01 (HIGH) + MH-H4-05 (MED) + WI-04/05 (Pre-Tag M-K-MED):** `_read_key_from_env` in nano-banana-image vs. openai-image-gen dupliziert, openai-Version schwächer (kein UTF-8-BOM, Prefix-Match-Bug bei `VAR_NAME_SUFFIX=`, asymmetrischer Quote-Strip). Plus generate_image.py hat lokale Drei-Stufen-Kopie. **Konvergenter Vorschlag:** `_lib/api_keys.py`-Extraktion als Single Source.
- **E-4-01 (HIGH):** Bulk-Bump-Maintainer-Skript `.maintainer/scripts/bump_bundle_version.py` fehlt — Pattern 2× ad-hoc benutzt (Wave H + Wave I).
- **E-1-03+E-2-02 (MED):** `_case_variants`-Helper für `SS_STATT_BETA_PATTERNS` (30 Pattern-Strings → 15 + Helper).
- **E-2-01+E-4-02 (MED):** Description-Redundanz-Score-Debug-Skript `.maintainer/scripts/score_description_redundancy.py` fehlt für Threshold-Kalibrierung.
- **E-4-03 (MED):** `validate_skill_md.py` als Kombi-Skript (Frontmatter + Redundanz-Score + Body-Struktur).
- **K-3-01 (MED):** 193 ae/oe/ue-Treffer in `tests/`-Kommentaren/Docstrings durch `SCAN_EXCLUDE_DIRS` aktuell nicht geprüft — CLAUDE.md-Absolut-Regel-Pflege-Defizit.
- **G1-03 (MED):** v0.17.0-Roadmap-Eintrag informationsarm — Foundation-Sub-Deps (`_lib/designsystem`, `natur-sprech-check`, optionale Image-Wrapper) für Brainstorming präzisieren.
- Plus ~10 LOWs aus allen vier Brillen.

### Methodisch
- **WG-L7 (Meta-Audit-Welle) zum 5. Mal angewendet:** Vier disjunkte Brillen lieferten 1 Pflicht-Fix-MED und 9+ Wave-II-Backlog-Befunde. Token-Bilanz ~411 K Subagent-Token gesamt.
- **WG-L8 (FP-Verifikation revidiert Audit-Brille):** Erstmals wurde eine Pre-Tag-Brillen-Hypothese durch eine Post-Tag-Brille widerlegt. Lesson: WG-L4 Sandbox-Halluzinations-Check gilt auch zwischen Brillen, nicht nur zwischen Sub und Hauptagent.
- **C-07-Heuristik bei singularem MED zum 3. Mal:** Konvergenz zum vorherigen Pflicht-Fix-Bereich (gleicher Pillow-Bump-Pattern, vergessene Datei) rechtfertigt Reife-Patch trotz singularem Befund.
- **Drei-Brillen-Konvergenz auf API-Key-Refactor (E-1-01 + MH-H4-05 + Pre-Tag-M-K-04):** Hartes Pflicht-Fix-Gate für Wave-II-Welle.

### Audit-Trail
`V0.16.2-POST-TAG-MULTI-BRUELLE-AUDIT.md` mit Vier-Brillen-Befunden + Schiedsrichter-Verdikt + Brille-M-K-Pre-Tag-FP-Korrektur.

## [0.16.2] — 2026-05-19 — Wave I Reife-Patch (Backlog-Aufarbeitung vor neue-praesentation)

### Anlass
Vor dem Welle-1-Skill `neue-praesentation` als nächster Bundle-Welle wurde ein Reife-Patch eingeschoben, der vier Pflicht-Fix-Items aus dem Wave-H-Backlog abräumt: ein Security-Bump (pillow CVE), eine .env-Fallback-Konsistenz-Asymmetrie zwischen den beiden Image-API-Sub-Skills, die Vollständigung der Umlaut-Hartregel um ss-als-ß-Patterns, und die Pytest-Verankerung der Vault-Hartregel „Description nicht im Body wiederholen" inklusive Body-Sweep der 16 betroffenen SKILL.md. Stand-Audit-Welle → Wave-A-Implementer (3 Owner-Subs + Hauptagent) → Schiedsrichter-Korrektur einer Sub-C-False-Positive → Pre-Tag-Brille M-K → TAG-REIF.

### Gefixt
- **H.4-01 pillow CVE-2023-44271:** `nano-banana-image/requirements.txt` (`pillow>=9.0.0`) und `linkedin-carousel/requirements.txt` (`pillow>=9.0.0`) erlaubten Versionen unter 10.0.1 (CVE-2023-44271 ReDoS in ImageFont). Beide auf `pillow>=10.4.0` angehoben. `openai-image-gen/requirements.txt` ebenfalls auf `>=10.4.0` (vorher `>=10.0.0`) für Konsumenten-Symmetrie.
- **H.1-02 .env-Fallback-Asymmetrie:** `nano-banana-image/scripts/find_api_key.py` hatte nur Env-Var-Lookup, `openai-image-gen/scripts/generate.py` hatte Drei-Stufen-Kette (Env-Var → Projekt-`.env` → `assets/.env`). Fix: neuer `_read_key_from_env`-Helper plus Drei-Stufen-Fallback in `find_api_key`. Rückgabe-Signatur `(str | None, str | None)` belassen (Aufrufer-Check ergab Backwards-Compat-Pflicht: `nano-banana-image/run_evals.py` testet `(None, None)`-Rückgabe). `__main__`-Block mit erweiterter Fehlermeldung (alle drei Pfade plus 1Password-Hinweis).
- **ss-als-ß-Lint-Vollständigkeit:** ein verbleibender ss-statt-ß-Drift im Docstring von `getmyinvoices/scripts/workflows/get_document.py:20` korrigiert (Details im Audit-Trail-Doc). Neue Pattern-Liste `SS_STATT_BETA_PATTERNS` in `_lib/test_utils.py` mit 30 Wortgrenzen-Patterns (Titlecase + lowercase explizit, case-sensitive — ALL-CAPS-Form bleibt nach Duden-Regel zulässig). Neue Test-Funktion `test_no_ss_substitutes_in_user_facing_code` in `tests/unit/test_no_umlaut_substitutes.py`. Whitelist dokumentiert: legitime ss-Wörter mit korrektem doppel-s am Wortende sind ausgeschlossen; das Englisch-kollidierende Adjektiv-Stem (gross margin) weggelassen.
- **Description-Redundanz-Lint + 16-SKILL.md-Body-Sweep:** Stand-Audit fand 16 von 28 SKILL.md mit wörtlicher Description-Wiederholung im ersten Body-Absatz unter H1. Body-Eingangsabsätze neu formuliert (Description in Frontmatter unverändert): authentic-portrait, cross-check, curator, gmi-accountant, index-rebuild, linkedin-finalize, linkedin-ideen, linkedin-kommentar, linkedin-research, master-prompt, migration, notebook-research, notebooklm-kurator, openai-image-gen, reflector, vault-gap-analysis. Neuer Pytest-Lint `tests/unit/test_skill_description_redundancy.py` mit Wortset-Overlap-Threshold 0.60 und SKIP_SKILLS={nano-banana-image} (Body beginnt mit Sicherheits-Sektion). Vault-CLAUDE.md-Hartregel zur Audit-Schicht erhoben.

### Schiedsrichter-Korrektur an Sub C
Sub C akzeptierte einen False-Positive (`AUSSER` in Großbuchstaben in `authentic-portrait/run_evals.py:106`) und kassierte ihn via temporären SCAN_EXCLUDE-Eintrag ein. Duden-Regel: in ALL-CAPS darf SS für ß stehen (Capital-ẞ U+1E9E selten implementiert). Hauptagent-Korrektur: Pattern-Liste um Titlecase-Varianten erweitert, `re.IGNORECASE`-Flag aus SS-Test entfernt, SCAN_EXCLUDE-Eintrag wieder gelöscht. Beide Tests grün nach Korrektur. Memory-Lesson `feedback_reviewer_hypothesen_verifizieren` zum n-ten Mal angewendet.

### Bilanz
- pytest tests/: **329 passed** (327 → 329, +2: ss-Substitute-Test + Description-Redundanz-Test).
- Cross-Skill **9/9 PASS** (unverändert): Bundle-Schema 2/2 + Image-Wave-G 2/2 mit M-A-02 4 Sub-Checks + Linkedin-Wave-H 5/5.
- Bundle-Skills **28** (unverändert), `bundle_version: 0.16.2`.
- Drift-Wand-Tests **2** (vorher 1, +`test_no_ss_substitutes_in_user_facing_code` + `test_skill_description_not_redundant_in_body`).

### Wave-G/H-Lessons angewendet
- **WG-L2 (Verifikations-Subagent) zum sechsten Mal:** Stand-Audit-Subagent vor Implementer-Dispatch lieferte konsolidiertes Patch-Inventar mit verbatim-Code-Zitaten — Hauptagent konnte Implementer-Briefs ohne weitere Disk-Reads schreiben.
- **WG-L8 (FP-Verifikation):** Sub-C-AUSSER-Befund als False-Positive identifiziert durch Schiedsrichter-Disk-Verifikation und Duden-Regel-Anwendung.
- **WG-L9 (CHANGELOG-Redaktions-Disziplin):** Final-Lese-Pass vor Tag, vollständige Sätze.
- **S7 Stochastik-Disziplin durchgängig:** Item 1 (Bulk-Bump 3 requirements.txt) und Item 4b (Pytest-Datei) durch Hauptagent deterministisch. Items 2/3/4a durch Subagents — Code-Refactor mit Pattern-Übernahme + Sprachgefühl-Sweep. Audit-Trail-Doku durch Subagent (Sprachgefühl + Token-Entlastung).
- **Bulk-Bump-Pattern via Python-Inline (Wave-H-Lesson zum 2. Mal):** 28 SKILL.md `bundle_version` 0.16.1 → 0.16.2 in einem Bash-Call statt 28 Edit-Tool-Roundtrips.
- **Vorgezogene Pre-Tag-Brille (Wave-H-Phase-6.5-Pattern):** Brille M-K als einziger Vor-Tag-Audit-Pass für diesen Reife-Patch reichte aus (vs. Wave-H drei Brillen A/C/E + F + H) — Reife-Patch-Scope rechtfertigt kleinere Brille-Front.
- **Memory-Lesson `feedback_subagent_token_budget_realistisch_30_50_prozent` zum 8. Mal:** alle drei Wave-A-Subagents im unteren Drittel der Schätzung (Sub B 55K real / 50K geschätzt, Sub C 61K real / 70K geschätzt, Sub D 149K real / 120K geschätzt — D leicht drüber wegen 16-Skill-Sweep-Volumen).

### Wave-I-Backlog (aus dieser Welle)
Brille-M-K-MEDs als Wave-II-Backlog dokumentiert: M-K-01 SS-Patterns-Helper-Funktion (Asymmetrie zu UMLAUT-Achse), M-K-02 fünf fehlende ß-Patterns für gehäufte Drift-Kandidaten (Details im Audit-Trail-Doc), M-K-03 memory-router ~50% Overlap (knapp unter Threshold), M-K-04 `generate_image.py` hat lokale `find_api_key`-Kopie ohne Drei-Stufen-Fallback (Item-2-Halb-Fix, Wave-G-Altlast), M-K-05 Verhaltens-Asymmetrie nano-banana vs. openai find_api_key (Non-Breaking-Return vs. Fail-Fast-Exit, Foundation-Konvention noch nicht etabliert). Plus 3 LOWs aus Brille-M-K und 18 Befunde aus dem ursprünglichen Wave-H-Pre-Session-Close-Audit (siehe `V0.16.0-WAVE-H-AUDIT-WELLE-PRE-SESSION-CLOSE.md`).

### Audit-Trail
`V0.16.2-WAVE-I-REIFE-PATCH-AUDIT.md` mit Stand-Audit + Wave-A-Implementer-Berichten + Schiedsrichter-Korrektur + Brille-M-K-Verdikt.

## [0.16.1] — 2026-05-19 — Wave H Reife-Patch (Post-Tag-Audit-Befund H.1-01)

### Anlass
Post-Tag-Audit Wave H v0.16.0 (Brille H mit schmal fokussiertem Security-Scope) lieferte einen Befund mit Code-Bereich-Konvergenz zu Wave-G-v0.15.1-Pattern F-02. Spec-v2-Korrektur C-07 (Wave-F-Doktrin) greift für Security-Defense-Lücken — Reife-Patch trotz singularem MED gerechtfertigt, um das Risiko nicht monatelang offen zu halten.

### Gefixt
- **H.1-01 (MED, konvergent mit Wave-G F-02-Pattern):** `nano-banana-image/scripts/generate_image.py` loggte API-Fehler in beiden Code-Pfaden (Streaming Z. 452, Standard Z. 514) als nackten `print(f"API-Fehler: {e}")` auf stdout. `str(e)` für `google.genai`-Authentication-Errors kann den präsentierten Credential-Anfang enthalten (analog dem Wave-G-v0.15.1-Befund im `openai`-Wrapper). Fix: beide print-Statements auf `print(f"API-Fehler: {type(e).__name__}: {str(e)[:200]}", file=sys.stderr)` umgestellt — Typ-Marker, 200-Zeichen-Limit, stderr statt stdout. Konsistent zum openai-Wrapper-Pattern aus v0.15.1 (Kommentar dort verbatim als Begründungs-Vorbild verwendet). Plus Pin-Test `nano_banana_image_api_error_uses_stderr_and_truncates` in run_evals.py (Wave-G-Lesson „Pin-Test-Pflicht für jeden Reife-Patch-Fix").

### Bilanz
- pytest tests/: **327 passed** (unverändert, Source-Code-Pin via grep in run_evals.py).
- Eval-Total 360 → **361 Assertions** (+1 nano-banana-image Pin-Test, 15 → 16).
- nano-banana-image: 15 → 16 Assertions.
- Cross-Skill 9/9 PASS (unverändert).

### Wave-G-Lessons angewendet
- **WG-L6 Konvergenz-Marker:** Code-Bereich-Konvergenz zum Wave-G F-02-Pattern explizit dokumentiert (gleicher Skript-Typ, anderes Skript — nano-banana wurde 2026-05-19 nicht mit openai mitgefixt).
- **WG-L8 FP-Verifikation:** Schiedsrichter-Direkt-Check per Lesen beider API-Fehler-print-Statements in generate_image.py vor Fix-Entscheidung.
- **C-07-Heuristik (Spec-v2-Korrektur):** Reife-Patch trotz singularem MED, weil Security-Defense-Lücke statt reine Doku-MED.
- **S7 Stochastik-Disziplin:** Hauptagent-Entscheidung deterministisch (grep + Lesen), kein Subagent für den Patch nötig (~30K Token statt 100K+).

### Audit-Trail
Phase-7-Brille-H-Bericht und Schiedsrichter-Verdikt in Session-Log. Weitere Brille-H-Befunde als Wave-I-Backlog: H.1-02 (.env-Fallback-Asymmetrie in openai-image-gen find_api_key — Doku-Drift, kein Exploit), H.4-01 (pillow>=9.0.0 in nano-banana erlaubt CVE-2023-44271-vulnerable Versionen — Exploit-Surface minimal, da nur Output-Save), H.6-01 (export-carousel-pdf.py kein Graceful-Fail bei schreibgeschütztem Output-Pfad). H.2-01 FP verifiziert (Konsumenten-XSS-Sicht — Defense in compose.py intakt, kein Bypass-Pfad).

## [0.16.0] — 2026-05-19 — Wave H Skill-Stack (linkedin-finalize + authentic-portrait + linkedin-carousel auf Foundation v0.15.0)

### Anlass
Skill-Stack-Welle auf der Wave-G-Foundation v0.15.0/v0.15.1. Drei Bundle-Skills parallel über drei Owner-Subagents A/B/C plus sequenziellen Schluss-Owner D migriert. Roadmap-Kontinuität gegenüber Wave G (Foundation-First-Schichtung): authentic-portrait und linkedin-carousel konsumieren beide Image-API-Wrapper (`nano-banana-image`, `openai-image-gen`) und `_lib/designsystem/`, linkedin-finalize orchestriert die beiden Sub-Skills plus `natur-sprech-check` als Pflicht-Gate. Drei-Owner-Pattern zum dritten Mal operativ verifiziert (Wave F = 2 Owner, Wave G = 3 Owner, Wave H = 3 Owner mit Foundation-Konsum).

### Hinzugefügt
- **`.skills/linkedin-finalize/`** (Owner A, Orchestrator): finalisiert LinkedIn-Post-Entwürfe — Stilcheck, Natur-Sprech-Gate als Pflicht-Gate, Thumbnail-Generierung in zwei Stufen (Basisbild via Nano Banana 2 oder OpenAI gpt-image-2, optional Headline-Overlay via Playwright-Renderer auf Warm-Navigator-Templates), optionaler Carousel-Build, Hashtag-Vorschläge, Status-Übergang nach „bereit". Sieben Pin-Assertions inkl. Demo-Template-Filter (Wave-G F-03-Konsum), Sub-Skill-Namen verbatim, Carousel-Branch, Natur-Sprech-Gate, Foundation-Subprocess-Konsum, BUENDEL-H-Patterns, ID-Konsistenz-Check.
- **`.skills/authentic-portrait/`** (Owner B, Sub-Skill): Dossier-basierte Personen-Bilder mit Engine-Wahl Nano-Banana ↔ OpenAI, sechs-Layer-Prompt-Reihenfolge (Identität → Outfit → Szene → Lighting Integration → ABSOLUTE PRIORITY), Authentizitäts-Review-Fallback-Loop. Sieben Pin-Assertions inkl. Engine-Konsum, MA-08 VERBOTS-Pattern, Prompt-Layer-Reihenfolge, Glossar-Namen, BUENDEL-H, ID-Konsistenz (Pin-Assertion post-Phase-5b ergänzt).
- **`.skills/linkedin-carousel/`** (Owner C, Sub-Skill): 10-Slide-Document-Posts via Designsystem-Template, Cover-Heuristik A/B/C/D (Photo+Overlay / Bold Type Dark / Frage Cream / Zahl-Hook), Playwright-PDF-Export im Format 1080×1350. Zwanzig Assertions: sechs Pin-Tests plus vierzehn Aggregations-Manifest-Einträge.
- **Cross-Skill-Eval erweitert** (Owner D): neue `run_linkedin_wave_h_evals.py` mit fünf Konsumenten-Vertragsschecks für den Skill-Stack. Cross-Skill-Eval-Run von 4/4 auf **9/9 PASS** (run_linkedin_bundle_schema_eval.py 2/2 + run_image_wave_g_evals.py 2/2 mit M-A-02 4 Sub-Checks aus Wave-G-Backlog + run_linkedin_wave_h_evals.py 5/5).

### Geändert (Foundation-Härtung Owner D, Anker 2+3)
- **Anker 2 XSS-Escape:** `_lib/designsystem/compose.py` und `_lib/designsystem/compose_v.py` escapen jetzt `headline` und `eyebrow` via `html.escape(..., quote=True)`. Vier Pin-Tests verifizieren Defense gegen `<script>alert(1)</script>`, `&`, `"`.
- **Anker 3 Path-Traversal-Schutz:** `_lib/designsystem/render.py` validiert `--output` (PNG-Suffix-Whitelist + CWD-Korridor-Pfad-Traversal-Schutz) und `--photo` (Magic-Bytes-Whitelist PNG/JPEG statt nur Extension-Check). Drei Pin-Tests.
- **Designsystem-Assertions:** 13 → 20 (+4 XSS-Escape compose/compose_v headline/eyebrow, +3 render Whitelist-Reject).
- **Manifest-Insertion alphabetisch** (Owner D + MG-1/MG-2): drei neue Bundle-Skill-Einträge alphabetisch (authentic-portrait, linkedin-carousel, linkedin-finalize). Profil-Default-Update für `nano-banana-image` und `openai-image-gen`: `default_active.content` von `false` → `true` (MG-1 Profil-Zahnrad-Synchronisation aus Pre-Session-Close-Audit-Welle — Wave-H-Skills im content-Profil rufen die Image-Wrapper als depends_on auf, also muss der Profil-Default synchron sein). `depends_on` im Manifest gesetzt (MG-2): linkedin-finalize → fünf Deps (natur-sprech-check, authentic-portrait, linkedin-carousel, nano-banana-image, openai-image-gen); authentic-portrait → zwei Deps (nano-banana-image, openai-image-gen); linkedin-carousel → eine Dep (natur-sprech-check).
- **nano-banana-image / openai-image-gen Pin-Tests erweitert** (MG-1): Pin-Test um `content=true` ergänzt, damit Profil-Drift künftig sofort failt. Beide Skills 14 → 15 bzw. 15 → 16 Assertions.

### Wave-G-Lessons angewendet
- **5-fach-Konvergenz-Pattern erstmals beobachtet** in Pre-Session-Close-Audit-Welle (MA-01 + MA-02 + MK-1 + MK-7 + MG-5 auf Sub-Skill-Aufruf-Form): Doppelpunkt-Form `Skill: <name>` → Backtick-Form ``Skill `<name>``` in allen drei Stefan-Lock-Contracts vor Owner-Dispatch normalisiert.
- **WG-L2 (Verifikations-Subagent für Stefan-Lock-Contract) zum fünften Mal** angewendet, jeweils mit substanziellen Befunden (Vault-Pfade verbatim, Frontmatter-Defaults, Glossar-Namen).
- **WG-L7 (Meta-Audit-Welle) zum vierten Mal** — vier disjunkte Brillen M-A/M-K/M-E/M-G lieferten sechs HIGH-Fixes vor Phase 4 Owner-Dispatch und achtzehn Wave-I-Backlog-Befunde.
- **WG-L8 (FP-Verifikation):** MA-04 (`nano-banana _build_result size=(0,0)`) per Code-Read als False Positive bestätigt; alle vier Phase-5-HIGH-Befunde per Schiedsrichter-Direkt-Check als valide bestätigt.
- **WG-L9 (CHANGELOG-Redaktions-Disziplin):** Final-Lese-Pass vor Tag, keine abgebrochenen Sätze, keine halben Aufzählungen.
- **S7 Stochastik-Disziplin** durchgängig: jeder LLM-Subagent-Output durch Hauptagent-Schiedsrichter mit Direkt-Verifikation (Python-Inline-Check, grep, file-read, eval-runs) belegt.
- **Memory-Lesson `feedback_subagent_token_budget_realistisch_30_50_prozent` zum siebten Mal** bestätigt: alle Wave-H-Subagents im unteren Drittel des Schätz-Budgets gelandet.

### Bundle-Modus-Bilanz Wave H
- Drei parallele Owner-Subagents A/B/C disjunkt plus sequenzieller Schluss-Owner D — Drei-Owner-Pattern zum dritten Mal operativ verifiziert (Wave F = 2 Owner, Wave G = 3 Owner, Wave H = 3 Owner mit Foundation-Konsum).
- Vor-Tag-Audit drei Brillen A/C/E disjunkt plus Schiedsrichter-Pass mit zwei Trivial-Fix-Wellen (Phase 5 HIGHs plus Phase 5b MEDs vor Tag-Push).
- Pre-Tag-Cross-Skill-Eval-Healthcheck-Gate (drei Eval-Runs: bundle_schema 2/2, image_wave_g 2/2, linkedin_wave_h 5/5) erfüllt — BUNDLE-MODE-READINESS-Hartregel ab v0.13.4.
- Bündel-Modus-Bereitschaftskriterien zum vierten Mal erfüllt.

### Werte
- pytest tests/: **327 passed** (Wave-G-Endwert unverändert — Wave H bringt keine zusätzlichen `tests/unit/`-Tests, alle Pin-Tests laufen in skill-lokalen `run_evals.py`).
- Eval-Total: 312 → **360 Assertions** (+7 linkedin-finalize, +7 authentic-portrait, +20 linkedin-carousel, +1 nano-banana-image, +1 openai-image-gen, +7 designsystem, +5 Cross-Skill).
- Bundle-Skill-Zähler: 25 → **28 Bundle-Skills**.
- Cross-Skill-Vertrag: 4/4 → **9/9 PASS**.

### Offen (Backlog Wave I)
Achtzehn Befunde aus Pre-Session-Close-Audit-Welle plus Phase-5-Audit-Backlog: BUENDEL_H-Semantik-Split, Description-Länge-Lint, Description-Redundanz-Lint, ss-als-ß-Pattern-Lint mit Lemma-Whitelist, BUNDLE-MODE-READINESS Wave-H-Stand-Block, FOLGE-WELLEN-ROADMAP-Update. Detail-Trail in `.maintainer/docs/V0.16.0-WAVE-H-AUDIT-WELLE-PRE-SESSION-CLOSE.md`.

## [0.15.1] — 2026-05-19 — Wave G Reife-Patch (Post-Tag-Audit-Befund-Konvergenz-Fixes)

### Anlass
Post-Tag-Audit Wave G v0.15.0 (zwei Brillen F+H) lieferte zwei Befund-Konvergenzen, die nach Wave-F-Doktrin (Memory-Lesson `feedback_konvergenz_code_bereich_vs_befund`) Pflicht-Fix-Gate für einen Reife-Patch v0.15.1 darstellen.

### Gefixt
- **F-02 / A-04 (HIGH, 2-Brillen-Befund-Konvergenz):** `openai-image-gen/scripts/generate.py::generate_image()` hatte kein try/except um den `client.images.generate(**params)`-API-Call. Bei API-Exception (RateLimit, Timeout, BadRequest) propagierte die Exception ungefangen statt das vier-Schlüssel-Output-Dict zu liefern — Wrapper-Vertrag-Bruch für Wave-H-Konsumenten. Fix: try/except um API-Call, im Except-Pfad konsistentes Output-Dict mit `path=None`, `format=output_format`, `size=(0,0)`, `prompt_hash=<sha256(prompt)>`. Konsistent zu `nano-banana-image/scripts/generate_image.py`. Plus Pin-Test `openai_image_gen_generate_image_returns_schema_dict_on_api_error` in run_evals.py (Wave-F-Lesson M-A MED-4: Pin-Test-Pflicht für jeden Trivial-Fix).
- **F-03 / Q-04 / E-03 (MED, 3-fach-Befund-Konvergenz):** Templates T22/T22v/T24/T24v/T28/T30/T30v in `_lib/designsystem/compose.py` und `compose_v.py` enthalten hartcodierte Demo-Strings (`"Ausgabe · 2026"`, `"TEIL 01 / 03"`, drei T28-Karten-Texte, T30-Statement), die nicht über die render.py-CLI überschreibbar sind. T28v hat als Ausnahme ein Pipe-Split-Schema und ist voll konfigurierbar. Fix: neue Datei `_lib/designsystem/templates/README.md` mit Demo-Template-Tabelle und Wave-H-Konsumenten-Pflicht (linkedin-finalize-Empfehlungs-Heuristik muss diese Templates ausschließen, bis sie konfigurierbar gemacht werden — Wave-H-Spec-Anker). Plus Pin-Test `demo_templates_readme_documents_hardcoded_strings` in `_lib/designsystem/run_evals.py`.

### Bilanz
- pytest **327 passed** (Wave-G-Endwert nach v0.15.0 + v0.15.1; +13 gegenüber Pre-Wave-G-Stand 314 — davon +5 Designsystem-Behavior-Tests in v0.15.0 plus +3 Manifest-/Profil-/Designsystem-Lint-Tests + Pin-Tests integriert in skill-lokalen run_evals.py, nicht in tests/unit/)
- Eval-Total 310 → **312** (+1 openai-image-gen-Pin-Test `_returns_schema_dict_on_api_error`, +1 designsystem-Pin-Test `demo_templates_readme_documents_hardcoded_strings`)
- openai-image-gen: 15 → 16 Assertions
- designsystem: 12 → 13 Assertions
- Cross-Skill 4/4 PASS (unverändert)

### Audit-Trail
Phase-7-Brillen-Berichte und Schiedsrichter-Verdikt in Session-Log dokumentiert. Plus Meta-Audit-Welle (4 Brillen M-A/M-K/M-E/M-G) post-v0.15.1 — Audit-Trail in `.maintainer/docs/V0.15.1-META-AUDIT.md`. Backlog für Wave H + künftige Reife-Patches: M-A-01 (`_LOGO_PATH` Thread-Safety, 3-fach mit Owner-A-Q-05/Brille-E-E-02), M-A-02 (Cross-Skill-Eval Fehlerpfad-Lücke), M-A-03 (Trigger-Kollision `image-generation`), M-A-06 (`--list-templates`-Capability-Matrix), M-A-07 (compose.py/compose_v.py Doppel-main()), MK-05 (Welle-1-Readiness-Drift-Befund-Sektion Vault), ME-01..ME-07 (Code-Cleanup-Empfehlungen), MG-02/03/04 (Schiedsrichter-Doku-Klarstellungen). Plus Vor-Tag-Audit-Backlog: H-01 (HTML-Escape), H-02 (--output Whitelist), H-06 (MIME-Whitelist), F-01/F-04/F-05/F-06, A-01/A-03/A-05..A-08, C-01/C-03, E-01/E-04/E-06, Owner-A-Q-01..Q-09. Pre-Wave-H-Fix-Empfehlung (Hauptagent-Schiedsrichter): M-A-02 Cross-Skill-Eval-Fehlerpfad-Test ergänzen.

## [0.15.0] — 2026-05-19 — Wave G Foundation (_lib/designsystem/ + nano-banana-image + openai-image-gen)

### Anlass
Foundation-Welle vor dem Designsystem-Skill-Stack in Wave H v0.16.0. Drei Komponenten parallel über drei Owner-Subagents A/B/C plus Schluss-Owner D migriert. Roadmap-Änderung gegenüber Handover 2026-05-19: Wave G war ursprünglich `linkedin-finalize`, wurde nach Brainstorming-Skill-Lauf auf Foundation-First-Schichtung umgestellt — `linkedin-finalize` braucht fünf Sub-Skills und zwei externe Python-Skripte, ein Single-Tag-Marathon wäre über 8 M Token gewesen. Lösung: v0.15.0 = Foundation, v0.16.0 = Skill-Stack (authentic-portrait + linkedin-carousel + linkedin-finalize konsumieren die Foundation aus v0.15.0).

### Hinzugefügt
- **`_lib/designsystem/`** als Bundle-Asset-Layer (Owner A): Playwright-basierter Warm-Navigator-Renderer (compose.py / compose_v.py / preview_all.py), 460 Z. Tokens (JSON/CSS/Build-Skript), 27 HTML-Templates für 16:9 und 27 für 4:5 (T05/T23/T29 ausgespart). Subprocess-Entry-Points `python -m _lib.designsystem.render` und `python -m _lib.designsystem.preview_all`. resolve.py-Funktion `resolve_designsystem(bundle_root)` analog `config_loader.py`-Bundle-Root-Aufwärtssuche.
- **`.skills/nano-banana-image/`** als Wrapper für die Google Gemini Image Generation API (Owner B): 15/15 Eval-Assertions inkl. Mock-Behavior-Test, Output-Schema-Pflicht `{path, format, size, prompt_hash}`, ENV-Var `GEMINI_API_KEY` als Default (per Skill-Config überschreibbar).
- **`.skills/openai-image-gen/`** als Wrapper für die OpenAI gpt-image-2 API (Owner C): 15/15 Eval-Assertions analog, ENV-Var `OPENAI_API_KEY` als Default.
- **Neues Profil `image`** in `bundle.json.profiles` für Bild-API-Wrapper und künftige visuelle Skills (linkedin-finalize, authentic-portrait, linkedin-carousel).
- **Cross-Skill-Vertrag erweitert** (Owner D): zwei zusätzliche Assertions — `designsystem_resolvable_from_skill_context` (resolve_designsystem() liefert valid Pfad mit render.py) und `image_wrapper_output_schema_consistent` (beide API-Wrapper liefern dict mit `path`/`format`/`size`/`prompt_hash`). Cross-Skill-Eval-Run von 2/2 auf **4/4 PASS**.
- **`tests/unit/test_manifest_alphabetical.py`** als Pytest-Lint-Test (verankert Wave-F-Lesson M-K HIGH-2, v0.14.2-Meta-Audit): manifest.json muss strikt alphabetisch sortiert sein.
- **`tests/unit/test_profile_image_exists.py`**: bundle.json.profiles enthält `image`, beide API-Wrapper-SKILL.md haben `default_active.image: true`.
- **`tests/unit/test_designsystem_lib_resolves.py`**: `resolve_designsystem()` ist importierbar, liefert existierenden Pfad mit render.py, raised FileNotFoundError bei ungültigem Bundle-Root.
- **INSTALL.md-Abschnitt „API-Schlüssel für Bild-Skills"** mit 1Password-CLI-Empfehlung als Sicherheits-Pattern (kein Hardcoding, kein LLM-Leak, validierung nur per `wc -c`).
- **`bundle.json.profiles`** als explizite Liste aller Theme-Profile (`["allgemein", "automation", "beratung", "business", "content", "image"]`).
- **AGENTS.md (Template)** mit drei neuen Komponenten: Bundle-Asset-Layer-Sektion für `_lib/`, Skill-Index-Einträge für nano-banana-image und openai-image-gen, Profil-Sektion mit `image`-Erläuterung.

### Wave-F-Lessons angewendet
- **Manifest strikt alphabetisch** (M-K HIGH-2): nano-banana-image zwischen migration und natur-sprech-check; openai-image-gen zwischen notebooklm-kurator und project-session-end. Pytest-Lint-Test `test_manifest_alphabetical.py` verhindert künftige Insertion-Drift.
- **Brillen-Briefs mit Frontmatter-Konsistenz-Pflicht** (M-S HIGH-1): Pflicht-Check 1 in Brille-A-Brief = manifest.json ↔ SKILL.md-Frontmatter-Konsistenz für **alle Schlüssel-Felder** (type, agent_ready, schema_version, bundle_skill, bundle_version, scope, default_active.<alle_profile>, depends_on, conflicts_with, trigger_words).
- **Konvergenz-Marker in Audit-Berichten** (M-S MED-1): Befund-Konvergenz vs. Code-Bereich-Konvergenz wird in Vor-Tag-Audit-Sentenzen explizit unterschieden.
- **Verifikations-Subagent für Stefan-Lock-Contract** (`feedback_stefan_lock_vertrag_subagent_pre_implementer`): vor Owner-Dispatch durchgeführt, 27 fehlende Patterns gefunden + 1 Hauptagent-Halluzination aufgedeckt (`.maintainer/docs/V0.15.0-STEFAN-LOCK-CONTRACT-VERIFICATION.md`).
- **Spec-First mit Critic-Pass** (`feedback_spec_first_multi_reviewer_validiert`): Spec v1 → Spec-Critic-Pass → Spec v2 (13 Befunde verankert: Umlaut-Korrektur-Pflicht, STOPP-Klausel-Generalisierung, render.py-CLI-Erweiterung, Output-Schema-Pflicht, BUNDLE-MODE-READINESS-Stand-Block, Eval-Muster-Begründung, SCAN_EXCLUDE-Eintrag, feature-dev-Hartregel, Brille-K-Klausel-Differenzierung pro Owner-Typ, preview_all.py-CLI-Klarstellung, Owner-A-Token-Budget-Korrektur, Cross-Skill-Eval-Run-Healthcheck).
- **`feature-dev`-Hartregel respektiert** (Handover 2026-05-19): Owner A/B/C/D als `general-purpose`-Subagents dispatched, nicht als `feature-dev` — sichert Scope-Disziplin.

### Bundle-Modus-Bilanz Wave G
- Drei parallele Owner-Subagents mit disjunktem File-Scope: 0 File-Konflikte zwischen A/B/C.
- Brille-K-Klausel differenziert pro Owner-Typ (Owner A `_lib/`-Code-Refactor: n/a; Owner B/C API-Wrapper mit externer API: Brille K verbindlich).
- Cross-Skill-Vertrag erweitert ohne Schema-Refactor (additive Assertion-Insertion).
- Bündel-Modus-Bereitschaftskriterien aus BUNDLE-MODE-READINESS.md zum dritten Mal erfüllt.

### Werte
- pytest tests/: 319 → **322 passed** (+3 neue Unit-Tests: `test_manifest_alphabetical`, `test_profile_image_exists` (3 Cases), `test_designsystem_lib_resolves` (4 Cases))
- Eval-Total: 266 → **310 Assertions** (+15 nano-banana-image, +15 openai-image-gen, +12 designsystem, +2 Cross-Skill)
- Bundle-Skill-Zähler: 23 → **25 Bundle-Skills + 7 Hooks**
- Cross-Skill-Vertrag: 2/2 → **4/4 PASS**

### Offen (Backlog Wave H)
- linkedin-finalize, authentic-portrait, linkedin-carousel als Skill-Stack auf Foundation v0.15.0.
- _cross_skill_evals/-Erweiterung um Skill-Stack-Verträge.
- video-creator (Wave I+).

## [0.14.2] — 2026-05-18 — Meta-Audit-Konsolidierung (vier qualifizierte Brillen M-A/M-K/M-S/M-G)

### Anlass
Stefan beauftragte ein kritisches Nachprüfungs-Audit der Wave-F-Welle (v0.14.0 + v0.14.1) mit vier disjunkten Sonnet-Brillen über unterschiedliche Achsen: M-A Architektur+Effizienz, M-K Konsistenz+Doku-Drift, M-S Schiedsrichter-Logik, M-G Gesamtkonstrukt-Integration. Hauptagent agierte als Schiedsrichter, nicht als Annehmer — Brillen-Bias geprüft, Severities kalibriert. Vier echte HIGH-Befunde aus Konvergenz und Einzelbrille identifiziert.

### Vier HIGH-Fixes
- **HIGH-A** (M-K HIGH-2, Konf 100): `.skills/manifest.json` strikt alphabetisch sortiert. `master-prompt` stand nach `migration` (Wave-F-Insertion-Bug), `notebooklm-kurator` vor `notebook-research` (Legacy-Drift). Beide korrigiert. 23 Skills jetzt 0 alphabetische Mismatches.
- **HIGH-B** (M-S HIGH-1, Konf 88): CHANGELOG v0.14.1 F-MED-3-Beschreibung verschob Schuld auf Brille A („Brille A erstmals zur Aufdeckung führte"). Sachlich falsch: der `default_active.allgemein`-Drift wurde vom Pytest-Drift-Test im Release-Bump aufgedeckt, nicht von Brille A. Ursache war Brief-Design-Lücke des Hauptagenten (Brille-A-Brief enthielt keinen expliziten `default_active.<profile>`-Check). CHANGELOG + `test_manifest_skill_md_drift.py` Z. 9-Docstring sachlich neu formuliert.
- **HIGH-C** (M-S HIGH-2, Konf 87): F-MED-3 war als „Helper-Layer-Multiplikator" klassifiziert, obwohl die Implementierung in `tests/unit/` liegt (kein `_lib/`-Helper). Klassifikation auf „Test-Generalisierung" korrigiert in CHANGELOG und BUNDLE-MODE-READINESS. Gleichzeitig wurde F-LOW-1 (echter Helper-Layer-Befund in `_lib/test_utils.py`, case-sensitive BUENDEL_B-Patterns) selektiv ins Backlog geschoben — diese Asymmetrie ist jetzt transparent dokumentiert.
- **HIGH-D** (M-K HIGH-1 + M-G MED-4, 2-Brillen-Konvergenz, Konf 90/85): Welle-1-Zähl-Drift Steckbrief vs. Readiness-Audit. Steckbrief sagte „16 von 25 + 4 weitere"-Phantom-Skills, Audit sagt „21 von 25 Bundle-tatsächlich". Steckbrief-D-Zeile auf Bundle-tatsächlich-Sicht konsolidiert mit Verweis auf die drei Zählweisen im Audit. Phantom-Aussage entfernt.

### BUNDLE-MODE-READINESS Lessons-Block ehrlicher umformuliert
- **„Brief-Design-Lücken-Pattern"** statt „Brille-A-Audit-Lücken-Pattern" — Schuld liegt beim Hauptagent-Brief, nicht bei der Brille.
- **F-MED-3-Klassifikation:** Test-Generalisierung (in `tests/unit/`), nicht Helper-Layer-Multiplikator.
- **Code-Bereich-Konvergenz vs. Befund-Konvergenz:** F-MED-2 (FileNotFoundError, UX) + H-MED-1 (Path-Traversal, Security) waren Code-Bereich-Konvergenz, nicht Befund-Konvergenz nach strikter v0.13.2-Definition. Doktrin-Klarstellung für Wave G.
- **Brillen-Empfehlungs-Asymmetrie:** bei divergierenden Brillen-Empfehlungen Schiedsrichter-Eintrag mit klarer Trigger-Bedingung für Backlog-Eskalation.
- Frontmatter `updated: 2026-05-17 → 2026-05-18` (Body-Edits am 18.).

### Optional-Add-Ons (Pin-Tests + Memory)
- **Zwei Pin-Tests** in `linkedin-research/run_evals.py` als Schutz für die v0.14.1 F-MED-1/2-Fixes (M-A MED-4):
  - `linkedin_research_run_loop_empty_evals_schema_error` reproduziert leeres `{}` als evals.json → exit 1 + Schema-Note ohne KeyError-Traceback.
  - `linkedin_research_run_loop_missing_file_error` reproduziert nicht-existenten `--file`-Pfad → exit 1 + „nicht gefunden"-Note ohne FileNotFoundError-Traceback.
  - `eval/linkedin-research.eval.json` um zwei IDs erweitert. linkedin-research jetzt **19/19** (von 17/17).
- **Zwei Memory-Topic-Files** im user-Memory-Dir (M-K MED-2):
  - `feedback_brief_design_luecke_pattern.md`
  - `feedback_konvergenz_code_bereich_vs_befund.md`
  - MEMORY.md-Index nicht erweitert (Limit 24,4 KB überschritten).

### Verworfen als Brillen-Bias (Schiedsrichter-Entscheidung)
- M-A HIGH-1 „Over-Auditing 1,9 M Token ohne CRIT-Ertrag": Token-Korridor war im Soll (1,5–2,5 M). Doktrin-Härtung hat realen Wert (γ-C-1 Stefan-Lehnisch-Leak vor Implementer gefunden).
- M-A MED-3 „argparse.FileType wäre eleganter": Stilpräferenz, kein Bug. Refactor jetzt = Scope-Drift.
- M-G HIGH-2 „Karpathy-Templates Frischvault-Crash": `please_customize: true` ist explizites Anwender-Signal, dokumentiertes Onboarding, kein Bug.
- M-G HIGH-1 „Setup-Smoke-Test broken": Pre-existing v0.12.2-Issue, gehört in eigene Wartungs-Welle, nicht v0.14.2-Scope.

### Werte
- pytest tests/: **314 passed unverändert**
- Eval-Total: 264 → **266 Assertions** (+2 Pin-Tests in linkedin-research)
- Bundle-Skill-Zähler: **23 + 7 Hooks unverändert**
- Cross-Skill-Vertrag: **2/2 PASS unverändert**

### Offen (Backlog Wave G)
- F-LOW-1 (BUENDEL_B-Patterns case-sensitiv) — echter Helper-Layer-Befund.
- F-LOW-3, F-LOW-4 (skill-isolierte LOW-Befunde).
- H-MED-1 (Path-Traversal-Containment) — Trigger: `run_loop.py` Detail-Output-Erweiterung.
- M-G MED-1, M-G MED-3 (linkedin-research Status-Marker, BUENDEL_*-Skalierung) — Architektur-Diskussionen für Wave G.
- M-A LOW-1 (Drift-Test-Docstring-Profile-Liste).

## [0.14.1] — 2026-05-18 — Reife-Patch nach v0.14.0-Post-Tag-Audit (Brille F + H)

### Vier Trivial-Fixes ohne Feature-Scope
- **F-MED-1** (Konf 95, reproduziert): `linkedin-research/run_loop.py` `load_evals` hat jetzt Schema-Validierung. Malformed `evals.json` ohne `assertions.hard`-Liste führt zu sauberer Fehlermeldung statt `KeyError`-Traceback. Reproduktion: `echo "{}" > empty.json && run_loop.py --evals empty.json` → exit=1 mit klarer stderr-Note.
- **F-MED-2** (Konf 95, reproduziert): `linkedin-research/run_loop.py` `--file`-Arg hat jetzt File-Existence-Check vor `open()`. Nicht-existente Datei führt zu sauberer Fehlermeldung statt `FileNotFoundError`-Traceback.
- **F-MED-3** (Konf 90, Test-Generalisierung): `tests/unit/test_manifest_skill_md_drift.py` prüft jetzt **alle Profile** aus `manifest.theme_profiles` (allgemein, karpathy, business, automation, content), nicht nur `allgemein`. Hintergrund (korrigiert in v0.14.2-Meta-Audit, Brille M-S HIGH-1): in v0.14.0 hatten linkedin-research + master-prompt-SKILL.md keinen `default_active.allgemein`-Key, obwohl das manifest.json ihn setzte. Der Drift wurde vom Drift-Test während des Release-Bump-Schritts §9.8 aufgedeckt, **nicht** vom Vor-Tag-Audit Brille A — deren Brief enthielt keinen expliziten `default_active.<profile>`-Konsistenz-Auftrag (Brief-Design-Lücke des Hauptagenten, nicht Brille-A-Audit-Versagen). Die Test-Generalisierung schließt diese Klasse für alle künftigen Wellen. Pre-Implementation-Check: 0 Drifts in allen 23 Skills × 5 Profilen.
- **F-LOW-2** (Konf 80): `_lib/test_utils.py` `BUENDEL_B_PRIVATE_PATTERNS` Docstring um Wortgrenz-Klarstellung für `\bfino\b`-Pattern ergänzt — `fino-data-services` wird durch Wortgrenz-Splitting am Bindestrich gewollt mitgefangen.

### Audit-Bilanz Post-Tag v0.14.0
- Brille F (Adversarial): 0 CRIT, 0 HIGH, 3 MED + 4 LOW, Konfidenz 75-95, Verdikt „Reife-Patch v0.14.1 leichtgewichtig empfohlen".
- Brille H (Security): 0 CRIT, 0 HIGH, 1 MED + 1 LOW, Konfidenz 65-80, Verdikt „Kein Reife-Patch v0.14.x nötig" für H-MED-1 (kein Remote-Vektor).
- **Eine 2-Brillen-MED-Konvergenz** auf `run_loop.py` `--file`-Argument-Handling (F-MED-2 + H-MED-1). Hauptagent-Schiedsrichter-Verdikt: F-MED-2-Code-Fix (File-Existence-Check) + H-MED-1 als dokumentierter Backlog-Eintrag mit klarem Trigger (Wave G oder erstes öffentliches Bundle-Release, analog config_loader._resolve_paths H-LOW-1 deferred-Doku).
- Keine CRIT/HIGH-Konvergenz. Tag v0.14.0 selbst war stabil.

### Werte
- pytest tests/: **314 passed unverändert** (Drift-Test 2/2 nach Generalisierung)
- Eval-Total: **264 Assertions unverändert** (17+21+17+17+21+28+26+20+20+11+23+25+16+2)
- Bundle-Skill-Zähler: **23 + 7 Hooks unverändert**
- Cross-Skill-Vertrag: **2/2 PASS unverändert**

### Offen (Backlog, nicht in dieser Welle)
- **F-LOW-1**: `BUENDEL_B_PRIVATE_PATTERNS` case-sensitiv (Backlog Wave G, Entscheidung: `IGNORECASE` nur für Eigennamen, nicht für Schema-Form-Patterns).
- **F-LOW-3**: unbekannter `check`-Typ silent FAIL in `evaluate_hard` (skill-isoliert, kein realer Trigger).
- **F-LOW-4**: Cross-Skill-Schema-Producer-Lint fehlt für `linkedin-entwurf` / `linkedin-ideen` (Wave-G-Scope, paralleles Eval-Pattern zu `linkedin-research`).
- **H-MED-1**: `--file` Containment-Check via Env-Var-Allowlist (analog `SETUP_SMOKE_ALLOWED_ROOTS` aus v0.12.2). Trigger: Wave G oder erstes öffentliches Bundle-Release.
- **H-LOW-1**: `config_loader._resolve_paths` Skill-Pfade-Containment (dokumentiert deferred, Trigger: erstes öffentliches Bundle-Release).

## [0.14.0] — 2026-05-18 — Wave F Bündel B (linkedin-research + master-prompt)

### Anlass
Zweite Bündel-Spurprobe nach Wave E Bündel A. Zwei Content-Skills parallel migriert: `linkedin-research` (Karpathy-Auto-Research-Loop für LinkedIn-Posts, 17 Eval-Assertions) und `master-prompt` (Methodik-Skill für externe KI-Systeme mit drei Pfaden A/B/C, 21 Eval-Assertions, opt-in via `content`-Profil). Cross-Skill-Vertrag unverändert (KONV-7). Bündel-Modus-Bereitschaftskriterien aus v0.12.1 ein zweites Mal erfüllt (LLM-Prompt-Klausel deckt Wave F ab, Brille-K systemisch n/a, Ersatz: skill-interne Stefan-Lock-Drift-Brillen als Alias-Wrapper).

### Spec-Härtung (3 Audit-Pässe + T-Audit vor Implementer, 11 Sonnet-Brillen, 68+ Befunde)

**Welle 1 — 5 Brillen α/β/γ/δ/ε auf Spec v2, Eingriffe in v3:**
- 5-Brillen-Konvergenz §14-Drift (`α-H-1 + β-M-3 + γ-M-3 + δ-H-1 + ε-C-1`): Cross-Skill-Vertrag-Konsumenten-Lint-Beschreibung gehärtet.
- `γ-C-1` (Konf 100): judge-prompt.md Stefan-Lehnisch-Leak — Pflicht-Generalisierung auf `[Anwender]` in §11/§5.1 verankert.
- `γ-C-2`: benannte Eval-Funktion `bundle_stefan_lock_isolation` (Wave-E-Alias-Wrapper-Pattern weitergeführt).
- `α-H-2`: `paths.vault_writeback_targets`-Key gestrichen (nur `paths.master_prompts_root` für master-prompt).
- `β-H-1`: Eval-Total-Soll-Range **262–268** als Akzeptanzkriterium verankert.
- `β-H-2`: drei explizite Behavior-Tests für linkedin-research `run_loop.py` (`--text`/`--file`/Fehlerpfad, kein stdin-Pfad).
- `γ-H-1`: `BUENDEL_B_PRIVATE_PATTERNS`-Liste mit `Björn`, `Björn Kahle`, `Cawa`, `Cawa Younosi`, `Simon Miles`, `DATEV`, `fino` in `_lib/test_utils.py`.
- `γ-H-2`: §11 fünf Subsektionen pro Skill (Pfade/Frontmatter/Stefan-Strings/Layout/Mutations-Test) — Wave-E-Vorbild übernommen.
- `γ-H-3`: `tests/unit/test_no_umlaut_substitutes.py::SCAN_EXCLUDE_FILES` um Karpathy-Templates erweitert (Pattern-String-Files mit ASCII-Substituten).
- `γ-H-4`: Glossar-Verdikt-Kandidaten Simon Miles + Cawa Younosi (Glossar-Einträge + Generalisierung als Referenzpost-Autor 1/2) plus Sarah-Frage (Neutralisierung als Laien-Test).
- `γ-H-5`: master-prompt zweite Literal-Pfad-Quelle (Lücken-Zuordnungstabelle Z. 282–285 zusätzlich zu Subagent-Tabelle Z. 62–73) als Pin-Test abgesichert.
- `δ-M-3`: Zwei-Skill-Mix-Begründung (linkedin-research API-konsumierend, master-prompt reiner Methodik-Skill) in §0 dokumentiert.
- `ε-H-1`: 0b Existenz-Gate für `WAVE-F-STEFAN-LOCK-CONTRACT.md` vor Owner-Dispatch als nummerierter Schritt verankert.
- `ε-H-2`: Post-Owner `presets`-Re-Grep als Deliverable 8 in Owner-D-Brief.
- `ε-H-3 + δ-M-1 + δ-M-2`: Race-Condition-Fix C-post / D-post (Konsolidierung kommt nach Owner-Lieferung, nicht parallel).
- `ε-M-1`: Sub-Block-Coverage-Gate für Multi-Brillen-Audit.
- `ε-M-2`: 4+-Brillen-Konvergenz-Abbruch-Pfad in Spec dokumentiert.
- `ε-M-4 + ι-I-2`: Cross-Skill-Eval-Run als Pflicht-Healthcheck-Gate verankert (Konvergenz mit v0.13.4 L-H-2).

**Welle 2 — 5 Brillen ζ/η/θ/ι/κ auf Spec v3.1, Eingriffe in v4:**
- 5-Brillen-Konvergenz §9.5-Schritt-5-Dublette (`ζ-M-2 + η-H-1 + θ-H-1 + ι-CRIT-1 + ι-H-1`): Pre-Dispatch-Schritt-Nummerierung bereinigt.
- 4-Brillen-Konvergenz §5.1-Zeile-204-AGENTS.md-Phantomreferenz (`ζ-H-1 + η-C-1 + θ-H-5-Teil + ι-H-2`): falsche Zeilennummer im Owner-D-Brief korrigiert.
- `θ-C-1`: WAVE-F-STEFAN-LOCK-CONTRACT als Schritt 1 0-pre vor Owner-Dispatch (eigenständiges Maintainer-Doc analog Wave E).
- `κ-2-1`: `presets`-Sequenz-Pflicht (0a presets-Entfernung vor 0c BUENDEL_B-Pattern-Liste).
- 2-Brillen-Konvergenz §6.2-Header (`ζ-M-1 + θ-Cold-Start`): Akzeptanzkriterien-Tabelle vor Owner-Dispatch klargestellt.
- 2-Brillen-Konvergenz §0-Pipeline (`ζ-L-1 + θ-M-1`): Welle-Charakter-Block aktualisiert.

**T-Audit — Brillen T1/T2/T3/T4 auf Spec v4, Eingriffe in v4.1:**
- 2-Brillen-Konvergenz §3.4 0-pre (`KONV-T-4`: T2-4 + T3-H-1, Konf 88): Schritt 0-pre Sub-Bullet ergänzt.
- `T3-C-1` (Konf 100): Pre-Step-Arithmetik „sechs"→„fünf" in §9.5-Hinweis korrigiert.
- 2-Brillen-Konvergenz §9.5 Schritt 4 0b Inhalts-Grep (`T1-A-1 + T2-6`): 0b prüft jetzt zusätzlich Subsektions-Marker-Vollständigkeit (schließt κ-2-2 aus Pre-Dispatch-Backlog).
- `T4-HIGH-1` (Konf 92): Vault-Quell-`run_evals.py`-Pfad-Bug (Zeilen 33+140 `03 Bereiche/Karpathy Methoden/` falsch) als Warnung für Owner D verankert, Bundle muss `{system}/Karpathy Methoden/` via `cfg.layout` auflösen.
- `T4-HIGH-2` (Konf 88): SKILL.md-Body-Stefan-Strings (linkedin-research Description Z.3, Body Z.19/42/50/88) als Generalisierungs-Pflicht.
- `T4-HIGH-3` (Konf 82): stdin-Encoding-Hinweis für Owner D (Bundle-`run_loop.py` ohne stdin-Branch gelöst).
- `T4-MED-3` (Konf 81): `--text` und `--file` als `mutually_exclusive_group` (verhindert stillen Gewinner).

### Owner-Lieferung (parallel-Dispatch via general-purpose-Subagent)
- **Owner D (linkedin-research):** 17/17 Assertions PASS, vier Karpathy-Templates unter `templates/08 Systemsteuerung/Karpathy Methoden/Auto-Research/LinkedIn-Post/`, `run_loop.py` portabel mit `--evals`-Argument und `mutually_exclusive` `--text`/`--file`, Stefan-Lock-Isolation via `linkedin_research_bundle_stefan_lock_isolation` Alias-Wrapper, Cross-Skill-Konsumenten-Lint `linkedin_research_documents_post_schema_consumer` mit Anker-Pattern `\bstatus:\s*entwurf\b` und `##\s+Entwurf\b`. Token-Verbrauch 163 K.
- **Owner E (master-prompt):** 21/21 Assertions PASS, sechs PARA-Wurzeln als `{placeholder}` in Subagent-Brief (Z. 62–73) plus Lücken-Zuordnungstabelle (Z. 282–285), `MASTER_PROMPT_PRIVATE_PATTERNS` skill-lokal in `.skills/master-prompt/run_evals.py` (kein `_lib`-Eingriff), `paths.vault_writeback_targets`-Key nicht eingeführt, Codex-Fallback-Modus dokumentiert. Token-Verbrauch 158 K.

### Vor-Tag-Audit (3 Sonnet-Brillen A/C/E, disjunkte Achsen)
- Brille A (Architektur + Loader-API): 0 CRIT, 0 HIGH, 1 MED + 1 LOW.
- Brille C (Cross-Skill + Helper-Library-Drift): 0 CRIT, 0 HIGH, 0 MED, 1 LOW.
- Brille E (Doku + CHANGELOG + BUNDLE-MODE-READINESS): 0 CRIT, 0 HIGH, 2 MED + 3 LOW.
- **Konvergenz über 2+ Brillen: keine.** Pflicht-Fix-Gate nicht ausgelöst. Spec-Erwartung „0 CRIT, 0–2 HIGH" deutlich unterschritten.

### Trivial-Fixes vor Tag (chore-Commit `bba07d1`)
- **A-MED-1** (Konf 82): master-prompt SKILL.md `default_active.content: false`-Begründungs-Block im Body ergänzt (Symmetrie zu linkedin-research Z. 27, KONV-A-M-5-Konsistenz).
- **E-LOW-1** (Konf 78): `V0.14.0-PRE-DISPATCH-BACKLOG.md` Frontmatter-Description „15 offen"→„16 offen" (Body Z. 18 sagte schon „16 offen"; Hauptagent-Edit-Drift-Pattern fünftes Mal).

### Werte
- pytest tests/: **314 passed** (unverändert, keine neuen Unit-Tests; Pin-Tests laufen in Skill-Runnern)
- Eval-Total: 226 → **264 Assertions** (+17 linkedin-research, +21 master-prompt, Cross-Skill 2/2 unverändert)
- Bundle-Skill-Zähler: 21 → **23 Bundle-Skills + 7 Hooks**

### Offen (Backlog, nicht in dieser Welle)
- `V0.14.0-PRE-DISPATCH-BACKLOG.md` mit 16 offenen Items aus Multi-Brillen-Welle 2 (8 HIGH + 8 MED + 2 LOW, davon 2 geschlossen) — alle nicht-blockierend, Pflicht-Read für Wave G.
- C-LOW-1: linkedin-research kein expliziter Pin-Test (Spec §6.2 nicht gefordert; Backlog-tauglich, Mutations-Test analog Wave-E in späterer Welle).
- A-LOW-1: master-prompt `## Verknüpfungen` minimal (kosmetisch, Wave G).
- E-LOW-2/3: CHANGELOG `[Unreleased]`-Block leer (durch §9.8 gefüllt — erledigt), Welle-1-Readiness-Audit Vault-Header (durch §9.8 gefüllt — erledigt).

## [0.13.4] — 2026-05-17 — Korrektur-Welle nach Meta-Audit (vier qualifizierte Brillen)

### Anlass
Meta-Audit der v0.13.2 + v0.13.3-Welle mit vier qualifizierten Sonnet-Brillen (Architektur/Effizienz/Korrektheit/Übersehene Flanken) hat vier 2-Brillen-Konvergenzen und mehrere Tool-belegte FAILs aufgedeckt: K-2 Overengineering (A+B-Konvergenz, dokumentiert als Backlog für künftige Architektur-Welle), L-H-2 Healthcheck nicht verankert (A+D-Konvergenz), CHANGELOG-Brillen-IDs für K-1/K-2 teilweise halluziniert (C, Tool-belegt), Handover HEAD-Bezug 2 Commits veraltet (C, Funktions-Defekt in nächster Session), M-F-1 nicht in v0.13.3 gefixt (D, Tool-belegt — Wave-F-Falle).

### Code-Fix (ein Helper-Patch)
- **M-F-1** Wave-F-Falle entschärft: `assert_no_literal_vault_paths` greedy-Strip-Regex in `_lib/test_utils.py` mit zwei-Schicht-Schutz — Vor-Scan auf `\{[a-z_.]+\}/<exakter-PARA-Wurzelordner>` plus Strip-Regex mit dotted placeholders erlaubt. Tool-verifiziert: `{areas}/03 Bereiche/foo` und `{areas}/03 Bereiche` → False (vorher beide False-PASS), `{paths.posts_root}/00-Ideenspeicher.md` → True (unverändert PASS). Plus zwei dedizierte Pin-Tests in `tests/unit/test_lib_pattern_consolidation.py` (greedy-strip-Regression + CRLF-Frontmatter-Regression).

### Doku-Drift-Fixes (acht Einzelfixes)
- **CHANGELOG Brillen-IDs korrigiert (Brille C H-1):** K-1-Konvergenz auf `α H-α-3 + β H-β-1 + δ H-δ-1` aus Spec v4 §0.2 Zeile 40, K-2 auf `α M-α-4 + γ M-γ-1 + δ H-δ-2` aus Spec v4 §0.2 Zeile 41. N-5 + N-6 Brillen-IDs (G G.1a/b + G.3 + G.4 sowie I H-2) blieben — Implementer-Verifikation: stammen aus v0.13.1-Vertiefungs-Audit (Brillen I/G/J/L), keine Halluzination. Herkunft im CHANGELOG präzisiert. **N-5 „-90 netto" auf Spec-konforme Formulierung korrigiert:** „~55-75 Drift-Reduktion in den drei Runnern gemäß Spec v4 §4, Netto-Codebase ~+79 nach git show b6728bf --stat".
- **Handover HEAD-Bezüge entfernt (Brille C H-2):** alle 6 Vorkommen `eb0804e` durch „nach v0.13.3-Tag (Hash bewusst nicht zitiert — N-4-Lesson aus v0.13.1)" ersetzt. Verhindert Hash-Drift in nächster Session.
- **V0.13.0-BACKLOG Schließen-Marker (Brille C M-3 + Brille D D.7):** A-M-4 (geschlossen in v0.13.1 K-4), C-M-2 (geschlossen in v0.13.1 K-3), KONV-C-H1+H-3 (geschlossen in v0.13.2 K-1). Tabelle synchron mit Schließen-Regel-Absatz.
- **V0.13.2-PRE-DISPATCH-BACKLOG Marker (Brille C M-2):** η L-η-1 (geschlossen in v0.13.3 via Handover-Update), M-δ-3 (geschlossen in v0.13.2 via Release-Bump-Step F). Plus neuer „## v0.13.4-Update"-Block.
- **Welle-1-Readiness-Audit Stand-Header (Brille C L-1):** auf „Stand 2026-05-17 nach v0.13.3-Tag, Code-Refactor-Welle + Reife-Patch" aktualisiert. Zähl-Drift „7 offen, nach Wave F bleiben 5" mit Quelle-der-Wahrheit verankert (Brille D D.8). HEAD aus Tabelle entfernt.
- **README Hook-Sprache vereinheitlicht (Brille C M-1):** Zeile 10 + Zeile 32 auf „21 Bundle-Skills + 7 Hooks (davon 1 Python-Hook-Skill `guard_notebooklm_delete`, sechs weitere als reine YAML-Konfigurationen)". Tool-verifiziert: `find .skills -name hook.yaml | wc -l` = 7, nicht 6 wie ursprüngliche Spec sagte.
- **BUNDLE-MODE-READINESS Healthcheck-Pflicht verankert (Konvergenz Brille A H-2 + Brille D D.5):** neuer Pflicht-Healthcheck-Block mit Cross-Skill-Eval-Run-Befehl `PYTHONUTF8=1 .venv/Scripts/python.exe .skills/_cross_skill_evals/run_linkedin_bundle_schema_eval.py` (2/2 PASS erwartet). Verhindert stillen Drift bei vergessener Ausführung.

### Werte
- pytest tests/: 312 → **314 passed** (+2 Regressionstests)
- Eval-Total: **226 unverändert** (224 Skill + 2 Cross-Skill)
- Bundle-Skill-Zähler: **21 SKILL.md + 7 Hooks** (unverändert, nur Sprache korrigiert)

### Offen (Backlog, nicht in dieser Welle)
- K-2 Overengineering (Brille A H-1 + Brille B H-B-1, 2-Brillen-Konvergenz): Cross-Skill-Vertrag-Architektur könnte schlanker sein (3 Zeilen statt 297). Gehört in eigene Architektur-Welle.
- `presets`-YAGNI (Brille A M-1 + Brille B): durch v0.13.3-NotImplementedError-Guard de facto abgesichert, formale Klärung in Wave F oder Bündel-B.
- Vorab-Audit-Tiefe-Lessons (Brille B): für Wave-F-Spec-Strategie dokumentiert (zwei statt drei Multi-Brillen-Pässe als Default).
- L-F-3 ABSOLUT-Status-Revision (Brille B M-B-3): Hauptagent-Selbstkorrektur — v0.13.3-Reife-Patch-Begründung war überdehnt; vier von sechs Fixes (M-F-3/4/5/6) waren ausreichende Begründung.

## [0.13.3] — 2026-05-17 — Reife-Patch nach v0.13.2-Post-Tag-Audit (Brille F + H)

### Sechs Trivial-Fixes im Helper-Layer (kein Feature-Scope, kein Eval-ID-Drift)
- **M-F-3**: `assert_frontmatter_required_fields` in `_lib/test_utils.py` akzeptiert jetzt CRLF-Frontmatter (`^---\r?\n(.*?)\r?\n---`). Verhindert irreführendes „Kein gültiges Frontmatter gefunden" auf Windows-Default-Save.
- **M-F-4**: `_cross_skill_evals/run_linkedin_bundle_schema_eval.py` hat neue `_validate_schema_shape`-Funktion; leeres oder unbrauchbares Schema (fehlende `required_fields`/`required_values`) führt jetzt zu rc=1 mit klarer stderr-Note statt silent-PASS.
- **M-F-5**: `_validate_frontmatter_against_schema` mit `isinstance(required_values, dict)`-Guard vor `.items()`-Loop. Memory-Bezug: `feedback_provenance_json_null_eskalation`.
- **M-F-6**: linkedin-ideen Anti-Halluzination-Anker `"ehrlich"` → `r"\behrlich\b"` via `re.search`. „unehrlich" und „ehrlichsten" triggern nicht mehr als Anker. Eval-ID unverändert.
- **L-F-3**: Umlaut-Substitute in Docstrings/Kommentaren von `_lib/test_utils.py` (Block ~265-333) auf echte Umlaute korrigiert (`Präfixe`, `für`, `Prüft`, `gültige`, `Blöcke`, `über`, `ausschließlich`, `enthält`, `vollständiger`, `fängt`). Pattern-Strings bleiben ASCII (Regex-Funktionalität). Schließt globale Umlaut-Regel-ABSOLUT-Lücke (Datei in SCAN_EXCLUDE).
- **L-H-1**: `assert_no_literal_vault_paths(body, presets=None)` wirft jetzt `NotImplementedError`, wenn `presets is not None`. Defense-in-Depth für Bündel B — Konsument bemerkt Drift sofort.

### Audit-Bilanz Post-Tag v0.13.2
- Brille F (Adversarial): 6 MED + 3 LOW, Konfidenz 72, Verdikt „Reife-Patch v0.13.3 empfohlen".
- Brille H (Security): 0 CRIT/HIGH/MED + 2 LOW, Konfidenz 92, Verdikt „v0.13.2-Sicherheit stabil".
- Keine 2+-Brillen-Konvergenz auf CRIT/HIGH. Hauptagent-Schiedsrichter-Verdikt: Reife-Patch wegen Helper-Layer-Charakter und L-F-3 Umlaut-Regel-ABSOLUT-Verstoss.

### Werte unverändert
pytest 312 passed, Eval-Total 226 (224 Skill + 2 Cross-Skill), 21 Bundle-Skills.

## [0.13.2] — 2026-05-17 — Code-Refactor-Welle (Pre-Bündel-B-Konsolidierung)

### Geschlossene Backlog-Items (Hauptscope)
Vier V0.13.0-BACKLOG-Items aus 4-Brillen-Vertiefungs-Audit, Konvergenz-IDs aus Spec v4 §0.2 (zweiter Multi-Brillen-Audit-Pass mit Sonnet-Brillen α/β/γ/δ/ε):
- **K-1**: Pattern-Listen-Konsolidierung — `BUENDEL_A_PRIVATE_PATTERNS` zentral in `_lib/test_utils.py` (3-Brillen-Konvergenz α H-α-3 + β H-β-1 + δ H-δ-1, eliminiert Drift-Risiko über drei Skill-Eval-Suites). Vorgänger-Befund: V0.13.0-BACKLOG A-M-3 + Vertiefungs-Audit L H-L-1 + G G.2.
- **K-2**: Cross-Skill-Schema-Vertrag `linkedin-ideen` → `linkedin-entwurf` als eigene Eval-Suite (`_cross_skill_evals/run_linkedin_bundle_schema_eval.py`, 2 Assertions, 3-Brillen-MED→HIGH-Konvergenz α M-α-4 + γ M-γ-1 + δ H-δ-2). Vorgänger-Befund: Vertiefungs-Audit I H-3 + Post-Tag F-M1.
- **N-5**: Helper-Auslagerung YAML-Validierung + Frontmatter-Pflicht-Check + `no_literal_paths` in `_lib/` (V0.13.0-BACKLOG-Vertiefungs-Audit Brille G G.1a/b + G.3 + G.4, ~80-120 Zeilen Drift-anfällige Duplikat-Code-Motivation in den drei Runnern). Implementer-Ist: -55 bis -75 Zeilen Drift-Reduktion in den drei Runnern gemäß Spec v4 §4 (Helper-Mechanik wächst entsprechend, Netto-Codebase laut `git show b6728bf --stat` +222/-143 = +79 nach diesem Schritt).
- **N-6**: `linkedin-ideen` Perplexity-Fehlerpfad-Härtung für Exit ≠ 0 (V0.13.0-BACKLOG-Vertiefungs-Audit Brille I H-2, Regression-Guard via deterministischem Fallback).

### Trivial-Mitnahmen (sieben Mit-Schließungen aus V0.13.0-BACKLOG)
- **A-M-2**: Pattern-Listen-Eindeutigkeit (mit-erledigt durch K-1).
- **A-M-3**: Pattern-Listen-Stefan-Eigennamen-Konsistenz (mit-erledigt durch K-1).
- **C-H-1**: Cross-Skill-Vertrag-Eval-Fehlen (mit-erledigt durch K-2).
- **C-L-1**: Stefan-privater Name `Fotis Stamatelopoulos` in Pattern-Liste (Trivial-Fix M-C-1 vor Tag).
- **C-M-1**: Schema-Vertrag-Doku-Drift (mit-erledigt durch K-2-Eval-Suite als Single Source of Truth).
- **E-M-2**: Helper-Library-Drift-Risiko (mit-erledigt durch N-5).
- **F-M5**: Perplexity-Fehlerpfad-Eval-Lücke (Trivial-Fix L-A-1 vor Tag, mit-erledigt durch N-6).

### Audit-Pipeline-Bilanz
Drei Audit-Pässe vor Implementer (Spec-Critic + zwei Multi-Brillen-Pässe = **11 Sonnet-Brillen, 68 Befunde**, in Spec v4 eingearbeitet). Vor-Tag-Audit drei Brillen A/C/E parallel: **0 CRIT, 0 HIGH, 1 MED + 6 LOW**, alle drei ready-to-tag. Trivial-Fixes M-C-1 (C-L-1-Verdikt) + L-A-1 (F-M5-Verdikt) vor Tag eingespielt.

### Pytest + Eval-Stand nach v0.13.2
- **309 → 312 pytest passed** (+3 durch K-2-Cross-Skill-Suite und N-6-Härtungs-Tests, 0 failed)
- **224 → 226 Eval-Total** (224 Skill-Eval-Assertions unverändert + 2 neue Cross-Skill-Assertions aus K-2 = 226)
- **Bundle-Skill-Zähler 21 unverändert** (Code-Refactor-Welle ohne neue Skills)

### Bundle-Mode-Status
Wave F **Bündel B** (`linkedin-research` + `master-prompt`) weiter erlaubt für **v0.14.0** — Code-Refactor-Welle hat Pre-Bündel-B-Bereitschaft hergestellt, kein neuer Bündel-Anker.

## [0.13.1] — 2026-05-17 — Reife-Patch nach 4-Brillen-Vertiefungs-Audit

### Geändert (Trivial-Fixes, kein Feature-Scope)
- **README-Skill-Zähler**: Drei Stellen falsch („20 Skills" statt 21) — Tool-verifiziert per `.skills/*/SKILL.md`-Glob = 21. Brille J Befund J.3-H.
- **Eval-Total-Drift**: CHANGELOG-v0.13.0-Block, Status-Tabelle, README-Eintrag, Vault-Handover und Session-Log nannten konsistent „220" — Addition 16+21+17+28+26+20+20+11+23+25+16 = **223** vor v0.13.1-Patch. Nach `linkedin-entwurf`-Umlaut-Assertion-Nachrüstung (17 statt 16) sind es jetzt 17+21+17+169 = **224 Bundle-Eval-Assertions**. Brille J Befund J.9-H.
- **V0.13.0-BACKLOG-Schließen-Satz** präzisiert (vorher „alle 11 Einträge", inkonsistent mit Post-Tag-Block). Brille J Befund J.4-M.
- **BUNDLE-MODE-READINESS-Stand-Block** HEAD-Bezug entfernt (war 2 Commits veraltet). Brille J Befund J.6-M.

### Code-Fixes (Trivial)
- **`linkedin-entwurf`**: `assert_no_umlaut_substitutes` war importiert, aber nie aufgerufen. Wave-E-Reife-Patch rüstet die Assertion mit eigener Eval-ID `linkedin_entwurf_skill_md_no_umlaut_substitutes` nach. Eval-Suite wächst 16 → 17. Schließt 3-Brillen-Konvergenz V0.13.0-BACKLOG A-M-4 + Brille G G.9 + Brille I L-1.
- **`linkedin-kommentar`**: `bundle_stefan_lock_isolation` war vollständige Code-Duplikation von `skill_md_no_literal_paths`. Nach Wave-E-Reife-Patch als Alias-Wrapper mit Kommentar — analog `linkedin-entwurf`-Pattern. Schließt 2-Brillen-Konvergenz V0.13.0-BACKLOG C-M-2 + Brille G G.6.

### Audit-Bilanz Vertiefungs-Welle (4 Brillen parallel, Sonnet)
- **Brille I** (Karpathy + Zahnrad): 0 CRIT, 3 HIGH, 3 MED, 2 LOW. Karpathy-Score 9/10 pro Skill.
- **Brille G** (Effizienz): 0 CRIT, 2 HIGH, 5 MED, 3 LOW. Verdikt OPTIMIERBAR. Code-Refactor-Bedarf in v0.13.2.
- **Brille J** (Doku-Integrität): 0 CRIT, 2 HIGH, 3 MED. Verdikt FIX-NÖTIG. Alle vier durch Reife-Patch geschlossen.
- **Brille L** (Cross-Welle-Konsistenz): 0 CRIT, 2 HIGH, 5 MED, 3 LOW. Verdikt DRIFT-VORHANDEN.

### Backlog für v0.13.2 (Code-Refactor-Welle vor Bündel B)
- **K-1**: Pattern-Listen-Auslagerung `BUENDEL_A_PRIVATE_PATTERNS` nach `_lib/test_utils.py` (3-Brillen-Konvergenz L H-L-1 + G G.2 + V0.13.0-BACKLOG A-M-3).
- **K-2**: Cross-Skill-Schema-Vertrag linkedin-ideen → linkedin-entwurf als Eval-Assertion (2-Brillen-Konvergenz I H-3 + Post-Tag F-M1).
- **N-5**: Helper-Auslagerung YAML-Validierung + Frontmatter-Pflicht-Check + `no_literal_paths` (Brille G G.1a/b + G.3 + G.4, ~180 Zeilen Drift-anfälliger Duplikat-Code).
- **N-6**: linkedin-ideen Perplexity-Fehlerpfad-Härtung für Exit ≠ 0 (Brille I H-2).

### Pytest + Eval-Stand nach v0.13.1
- 309 pytest passed, 0 failed (unverändert)
- 11 Skill-Eval-Suites alle PASS: **17/21/17 (Wave E nach Patch) + 28/26/20/20/11/23/25/16 (Regression)** = **224 Assertions Total**.

## [0.13.0] — 2026-05-17 — Wave E Bündel A (drei LinkedIn-Skills)

### Neu
- **Wave E Bündel A:** Drei LinkedIn-Workflow-Skills aus dem Anwender-Vault als gemeinsames Bündel migriert (erste Bündel-Spurprobe nach Konsolidierungs-Welle v0.12.1):
  - `linkedin-entwurf` — substanzielle LinkedIn-Post-Entwürfe mit Format-Wahl, 14 Qualitäts-Gates, PVL-Skelett, Lese-Persona-Test
  - `linkedin-ideen` — drei Post-Vorschläge aus Vault-Wissen, Performance-/Trend-Brief-Match, optionales Perplexity-Zahlen-Feature (externe Abhängigkeit, Default-OFF)
  - `linkedin-kommentar` (MVP-Scope) — substanzielle Kommentar-Entwürfe via Modus A (WebFetch + Schreibstil-Filter). Phase-2 (DB-Ingest, Inbox-Modus, Inbound-KI-Check) folgt in v0.20.x.
- **Neues `content`-Profil** in `manifest.json` mit drei aktivierten Skills, Default-aktiv im `allgemein`-Profil.
- **13 neue Bundle-Templates** unter `templates/00 Kontext/`, `templates/02 Projekte/`, `templates/03 Bereiche/Content & Positionierung/` (alle mit `bundle_template: true` und `please_customize: true`).
- **Stefan-Lock-Drift-Brille** als Brille-K-Ersatz für LLM-Prompt-Skill-Wellen etabliert (siehe `.maintainer/docs/WAVE-E-STEFAN-LOCK-CONTRACT.md`). Mutations-Test als reine Lint-Assertion auf SKILL.md-Body.
- **Eval-Suite-Ausbau:** 54 neue Assertions (16 linkedin-entwurf + 21 linkedin-ideen + 17 linkedin-kommentar). Nach v0.13.1-Reife-Patch: 55 neue + 169 Regression = **224 Bundle-Eval-Assertions** (siehe v0.13.1-Eintrag).

### Geändert
- `manifest.json.theme_profiles.content` neu hinzugefügt — viertes Profil neben allgemein/karpathy/business/automation.
- `.templates/default/AGENTS.md` Skill-Index um drei linkedin-Skills erweitert.
- `FOLGE-WELLEN-ROADMAP.md` umnummeriert: v0.13.0 = Bündel A (statt Quintessenz). Notebooklm-Phase-2-Wellen rutschen: Claude-CLI auf v0.23.0, scoring.py auf v0.24.0, Quintessenz auf v0.25.0. Welle-1-Skills haben Vorrang.

### Backlog geschlossen aus V0.12.1-BACKLOG.md
- **A-L-2** — Welle-1-Readiness-Audit Bündel-Kandidat-Spalte auf `migriert` für die drei linkedin-Skills.
- **E-MED-1** — BUNDLE-MODE-READINESS Kriterium-2-Qualifier in Stand-Tabelle gespiegelt (Hauptagent-Pflicht post-tag).
- **E-MED-3** — Klausel „Brille K systemisch n/a für LLM-Prompt-Skill-Wellen" in BUNDLE-MODE-READINESS verankert (Hauptagent-Pflicht post-tag, erste Anwendung in Wave E).

### Audit-Bilanz Wave E
- Spec-Critic-Pass: 0 CRIT, 4 HIGH, 5 MED, 3 LOW = 12 Befunde, alle in Spec v2 eingearbeitet.
- Vor-Tag-Audit: 4 Sonnet-Brillen parallel (A/B/C/E). 0 CRIT, 4 HIGH, 13 MED, 7 LOW = 24 Befunde gesamt. Zwei 2-Brillen-Konvergenzen (`scope: vault` im Frontmatter-Check, `expected_ids_match_runner_results`-Prefix) plus drei Trivial-Spec-Fixes vor Tag eingespielt. 11 verbleibende Befunde in `V0.13.0-BACKLOG.md` dokumentiert.
- Bündel-Modus operativ verifiziert: drei Implementer-Subagents parallel, null File-Konflikte, ~330K Token-Verbrauch gesamt für Implementer-Phase.

### Pytest + Eval-Stand
- 309 pytest passed, 0 failed
- 16/16 linkedin-entwurf, 21/21 linkedin-ideen, 17/17 linkedin-kommentar (alle Eval-Suites grün)
- 7 existierende Skill-Eval-Suites regressionsfrei: 28/26/20/20/11/23/25/16

### Bekannte Backlog-Items
Siehe `.maintainer/docs/V0.13.0-BACKLOG.md` für die 11 nicht-blockierenden Befunde (Sarah-Lookahead-Defekt, Umlaut-Substitute-Assertion-Lücke, default_active-Begründungs-Block, weitere Cross-Skill-Konsistenz-Drifts).

## [0.12.2] — 2026-05-17

PATCH-Release: Reife-Patch nach v0.12.1-Post-Tag-Audit (Brillen F Adversarial + H Security). **Fünf Härtungen** in den zwei neuen Maintainer-Skripten (`setup_smoke_test.py` + `check_vault_sync.py`), kein Feature-Scope. Wave-D-Pattern wie v0.11.0 → v0.11.1.

### Härtungen

- **H-1a (HIGH, OWASP A01):** `setup_smoke_test.py --vault-temp` jetzt mit Containment-Check via `SETUP_SMOKE_ALLOWED_ROOTS`-Env-Var (Default `tempfile.gettempdir()`). Verhindert versehentlichen `rmtree` auf z.B. `C:/Windows/System32` im `finally`-Block.
- **F-H1 (HIGH):** `check_vault_sync.py._check_file` mit Null-Byte-Heuristik in den ersten 512 Bytes — Binärdateien (z.B. PDF mit `.md`-Endung) werden jetzt erkannt und mit Exit 1 abgelehnt. Verhindert False-Negative bei eingebettetem Tag-String.
- **F-M1 + H-4 (MED-Konvergenz):** ZIP-Bomb-Schutz mit `MAX_UNZIP_BYTES = 500 MB` Vorab-Check via `infolist()`-Summe, plus expliziter `filter='data'` in `extractall` (ab Python 3.12, Fallback für 3.11).
- **H-3 (MED, OWASP A05):** `check_vault_sync.py` Default-Allowed-Root von `Path.home()` (gesamter Userprofile-Tree) auf `Path(tempfile.gettempdir()).resolve()` eingeengt. Echte Vault-Prüfung erfordert explizites `CHECK_VAULT_SYNC_ALLOWED_ROOTS`.
- **H-6 (MED, Defense-in-Depth):** `_check_file` mit `full_path.resolve().is_relative_to(base_root.resolve())`-Check vor Datei-Read.

### Test-Coverage

- `tests/integration/test_setup_smoke.py`: 2 neue Cases (Vault-Temp-Containment, ZIP-Bombe)
- `tests/unit/test_check_vault_sync.py`: 3 neue Cases (H-3 Path.home-Ablehnung, F-H1 Binärdatei, H-6 Pfad-Traversal)
- **309 pytest passed** (+5 gegenüber v0.12.1), 7-Skill-Eval-Regression unverändert

### Roadmap-Umnummerierung

- v0.12.3 wird Claude-CLI-Konsum-Spurprobe (vormals v0.12.2)
- v0.12.4 wird `scoring.py` + 8 Eval-Cases (vormals v0.12.3)
- v0.13.0 Phase-2-Quintessenz unverändert
- Siehe `FOLGE-WELLEN-ROADMAP.md`

### Backlog v0.12.3+

Aus dem Post-Tag-Audit verbleiben 5 nicht-blockierende Befunde (H-5 Logging-Defense-in-Depth, F-M2 `.tmp`-Cleanup, F-L1/H-7 Doku-Stefan-Pfade in alten Migration-Specs, F-L3 Spec-interne Tabellen-Doppelung) plus die 12 Vor-Tag-Reste aus v0.12.1. Alle in `V0.12.1-BACKLOG.md` dokumentiert.

## [0.12.1] — 2026-05-17

PATCH-Release: Konsolidierungs-Welle vor Wave E. **Keine Skill-Migration** — Welle-1-Stand bleibt 16 von 25. Meta-Welle: definiert Bündel-Modus-Bereitschaftskriterien, konsolidiert 17 Wave-1-Lessons auf 10 (mit L3a/L3b-Split für In-Process-Mock vs. CLI-Subprocess), gliedert stabile Patterns in neue `.maintainer/docs/PATTERNS/`-Familie aus (5 Dateien), liefert §12-Folge-Wellen-Umsortierung nach Brille-ε E-C1/E-C2/E-H5, und ergänzt zwei neue Maintainer-Skripte: `setup_smoke_test.py` (End-to-End-Setup-Verifikation gegen Mock-Bundle ohne Live-Download) und `check_vault_sync.py` (Vault-/Bundle-Tag-Drift-Check, read-only mit `CHECK_VAULT_SYNC_ALLOWED_ROOTS`-Containment).

### Neu im Bundle

- `.maintainer/docs/PATTERNS/SUBPROCESS-DI-CONSUMER.md` (134 Zeilen) — Subprocess-Dependency-Injection-Pattern für CLI-Konsumenten
- `.maintainer/docs/PATTERNS/MOCK-API-CONTRACT-WORKFLOW.md` (118 Zeilen) — API-Vertrag-Verifikations-Subagent + verbatim-Pflicht-Read
- `.maintainer/docs/PATTERNS/MULTI-ACHSEN-AUDIT.md` (118 Zeilen) — Brillen-Achsen-Kanon A-K plus Konvergenz-Regeln
- `.maintainer/docs/PATTERNS/HOOK-HELPER-CLASS.md` (156 Zeilen) — PreToolUse-Hook-Helper-Konvention
- `.maintainer/docs/PATTERNS/README.md` (65 Zeilen) — Pattern-Familie-Index
- `.maintainer/docs/BUNDLE-MODE-READINESS.md` (68 Zeilen) — Vier Trigger-Kriterien plus Anti-Trigger
- `.maintainer/docs/FOLGE-WELLEN-ROADMAP.md` (62 Zeilen) — gesplittete Folge-Wellen v0.11.2/v0.11.3/v0.12.0/v0.12.2/v0.12.3/v0.13.0
- `.maintainer/docs/V0.12.1-BACKLOG.md` — 12 nicht-blockierende Backlog-Befunde aus dem Vor-Tag-Audit
- `.maintainer/scripts/setup_smoke_test.py` (193 Zeilen) — End-to-End-Setup-Smoke-Test gegen Mock-Bundle-ZIP
- `.maintainer/scripts/check_vault_sync.py` (170 Zeilen) — Vault-/Bundle-Tag-Drift-Check mit Pfad-Containment-Schutz
- `tests/integration/test_setup_smoke.py` (104 Zeilen) plus `tests/integration/__init__.py` — 3 Cases
- `tests/unit/test_check_vault_sync.py` (108 Zeilen) — 4 Cases

### Aktualisiert

- `WAVE-2-MIGRATION-BRIEF.md` — Wave-1-Lessons-Block 17 → 10 konsolidiert (L3a/L3b-Split); neue §7-Sektion „Stefan-Routing-Entscheidungen" mit drei Einträgen vom 2026-05-17 (Designsystem-Welle 2 = Option A; Setup-Smoke-Test in v0.12.1; Volle Welle in einer Session)
- `NOTEBOOKLM-KURATOR-MIGRATION-SPEC.md` — §12-Hinweis-Block auf `FOLGE-WELLEN-ROADMAP.md` ergänzt (historische Referenz erhalten)
- `tests/unit/test_no_umlaut_substitutes.py` — `SCAN_EXCLUDE_FILES` erweitert um `KONSOLIDIERUNG-V0.12.1-SPEC.md` (Doku-Selbstvergiftungs-Schutz)

### Audit-Pipeline

- 1 Spec-Critic (Sonnet, 12 Befunde alle in Spec v2 eingearbeitet) + 3 Vor-Tag-Brillen A (Doku-Integrität) / B (Bundle-Code) / E (Strategie-Roadmap)
- Vor-Tag-Bilanz: 0 CRIT, 3 HIGH, 8 MED, 5 LOW, **null 2-Brillen-Konvergenz**
- 4 Trivial-Fixes vor Tag: B-H1 (Test-Assertion auf exakten Token), E-HIGH-1 (Lessons-Header 9 → 10), E-HIGH-2 (Skill-vs-Wellen-Aggregat-Klarstellung), A-M-1 (Handover `## Aktueller Status` auf v0.11.1)
- 12 Backlog-Befunde in `V0.12.1-BACKLOG.md` für v0.12.2+
- **304 pytest passed** (+7: 3 Setup-Smoke + 4 Check-Vault-Sync), 7-Skill-Eval-Regression unverändert (28/26/20/20/11/23/25/16)

### Bündel-Modus-Bereitschaft

Alle vier Trigger-Kriterien aus `BUNDLE-MODE-READINESS.md` für Wave D erfüllt (null CRITICAL Vor-/Post-Tag, Brille-K-Mutationstest grün, eine Session ohne Bruch, max. eine 2-Brillen-Konvergenz pro Welle). Bündel-Modus für Wave E **erlaubt**: Bündel A (linkedin-entwurf + linkedin-ideen + linkedin-kommentar) als erste Bündel-Spurprobe.

## [0.11.1] — 2026-05-16

PATCH-Release: Wave-D-Reife-Härtung nach Post-Tag-Audit mit zwei Sonnet-Brillen F (Adversarial, 4 verifizierte HIGH-Befunde) und H (Security, 4 Defense-in-Depth-Hinweise). Vier echte Bugs gefixt, vier Defense-in-Depth-Härtungen ergänzt, zwei Trivial-Doku-Drift-Korrekturen. Kein Feature-Scope, kein API-Bruch — Wave-D v0.11.0 bleibt funktional kompatibel.

### Geheilte Bugs (Brille F verifiziert)

- **`index_io.load_index()` Provenance-Eskalation (F2-1):** JSON-`null`/Array/String-Top-Level wirft jetzt `ValueError` statt `AttributeError`. Reproduziert Memory `feedback_provenance_json_null_eskalation`. Status-Lüge gegenüber Docstring geheilt.
- **Hook-Regex Flag-First-Ordering + `.exe`-Pfad-Bypass (F1-2):** `_DELETE_PREFIX_RE` + `_extract_source_id()` ersetzen das alte single-Regex. Erkennt jetzt `notebooklm[.exe]? source delete --notebook <UUID> <id>` und `path/to/notebooklm.exe source delete <id>` (wie MOCK-API-CONTRACT.md §10 das selbst getan hat). False-Positive-Denial bei kanonischer Flag-Ordering geheilt.
- **TZ-Konvergenz Hook ↔ backup.py (F2-3):** Hook nutzt jetzt `ZoneInfo("Europe/Berlin")` statt `datetime.now()` (local TZ). Backup-Suche scheitert nicht mehr still bei Maschinen außerhalb Berlin oder über Mitternacht UTC.
- **Hook-Skill `eval/`-Verzeichnis (F5-1):** `guard_notebooklm_delete/eval/README.md` angelegt — Konvention-Bruch (einziger Hook-Skill ohne eval/) geheilt.

### Defense-in-Depth (Brille H)

- **backup.py Path-Härtung (H.1):** `notebook_slug` und `source_id` werden gegen `^[A-Za-z0-9._-]+$` validiert, bevor sie in den Backup-Zielpfad fließen. `..`-Traversal-Klasse via mutmaßlich kompromittierte API-Responses geschlossen (OWASP A01 Defense-in-Depth).
- **yt-dlp `--`-Separator (H.2):** `content_verify._YTDLP_CMD` fügt `--` zwischen Optionen und User-URL ein. yt-dlp-Argument-Smuggling-Klasse geschlossen (OWASP A03 Defense-in-Depth).
- **stderr-Token-Maskierung (H.3):** `resync.py` maskiert `Bearer`/`token=`/`api[_-]?key=`-Pattern in stderr-Slices vor `audit_append`. OWASP A09 Logging-Failures Defense-in-Depth (NotebookLM-CLI exponiert aktuell kein Token in stderr, Schutz für zukünftige CLI-Versionen).
- **Backup-Retention-Doku (H.4):** SKILL.md Sicherheitsregel 2 erweitert um Retention-Empfehlung (12 Monate manuell prüfen). DSGVO-Echo dokumentiert, Auto-Cleanup-Backlog für v0.12.0+.

### Trivial-Fixes

- **Eval-Manifest-Description aktualisiert (F4-1):** `eval/notebooklm-kurator.eval.json` sagt jetzt "Eine von 28 Assertions" statt "27" (Drift seit Vor-Tag-Audit-Z1-Fix nicht synchron gezogen).
- **Hook-Name Konvention (F4-2):** `hook.yaml.name` von `guard-notebooklm-delete` auf `guard_notebooklm_delete` (Underscore-Konvention konsistent mit allen anderen 6 Bundle-Hook-Skills).

### Test-Status

- pytest tests/: 297 passed, 0 failed.
- python .skills/notebooklm-kurator/run_evals.py: 28/28 PASS.
- 7-Skill-Regression alle PASS.

### Audit-Pipeline Wave D (Post-Tag-Bilanz)

Schlanker Post-Tag-Audit (γ-2-Effizienz-Hebel angewendet): nur 2 Brillen F + H statt 5. Brille F fand 4 echte HIGH-Bugs net-new (null Doppelbefunde mit Vor-Tag-3-Brillen). Brille H ist initial in Brief-Falle gelaufen (relative `.skills/`-Pfade CWD-relativ zum Vault statt Bundle aufgelöst — Wave-D-Lesson 17 in WAVE-2-MIGRATION-BRIEF), lieferte aber trotzdem 4 wertvolle Defense-in-Depth-Befunde gegen den Vault-Source-Code, die für den Bundle-Code identisch gelten.

## [0.11.0] — 2026-05-16

MINOR-Release: Wave-D Welle-1-Migration `notebooklm-kurator` ins Bundle. Erstes `automation`-Profil-Skill, erster Bundle-Skill mit echtem CLI-Konsum (notebooklm-CLI als externe Quasi-API). Zweite Anwendung des API-Vertrag-Verifikations-Subagents (Wave-1-Lesson 2), erste Anwendung von `require_path_env_var` auf Hook-Allowlist. Drei neue Bundle-Assets: Subprocess-DI-Pattern als Standard für CLI-Konsumenten, `make_notebooklm_cli_mock`-Fixture, Python-Hook-Helper als zweite Hook-Klasse nach `output_filter`.

### Neu im Bundle

- **`.skills/notebooklm-kurator/`** — Kurator für NotebookLM-Notebooks. 10 Phase-1-Helper, drei Varianten (`--variant {standard,resync,dedup-check}`). SKILL.md komplett neu geschrieben mit Bundle-Frontmatter (α-1 CRIT — Quell-SKILL.md hatte keines).
- **`.skills/guard_notebooklm_delete/`** — Python-Hook als eigener Bundle-Skill (Konvention analog `output_filter`). PreToolUse blockt `notebooklm source delete` ohne Backup, Path-Containment via `require_path_env_var`.
- **`.skills/_lib/test_utils.make_notebooklm_cli_mock`** — Mock-CLI-Fixture als ausführbares Subprocess-Stub-Verzeichnis. Verbatim-Spiegelung der MOCK-API-CONTRACT.md §9.2-Pflichten: Matched-Vorzeile, `content`-Feld (nicht `fulltext`), `sources`-Wrapping, PYTHONIOENCODING-Crash-Spiegelung, Stateful-Delete, kein Auto-Dedup, Default-Mix mit 5 typischen Quellen.
- **`.skills/_lib/test_utils.STEFAN_PRIVATE_NAMES_PATTERNS`** — 8 neue Kurator-Patterns (26 → 34).
- **`templates/.skills/notebooklm-kurator/`** — 4 Templates plus 12 Eval-Fixtures unter `.skills/notebooklm-kurator/eval/fixtures/`.
- **`manifest.json.theme_profiles.automation`** — neues Profil.
- **`manifest.json.hooks_index`** — `guard_notebooklm_delete`.

### Test-Disziplin

- **28 Eval-Assertions** (12 Klasse A + 13 Klasse B + 1 Cross-Skill + 1 Klasse C, inkl. neuer Brille-K-Drift-Survival-Assertion `mock_cli_subprocess_drift_survival`).
- **Brille-K-Mutationstest operativ verifiziert:** Mutation `content`→`fulltext_LEAK` im Mock-CLI → Assertion fail mit klarer Drift-Diagnose; Rollback grün. Wave-1-Lesson 2 mit Subprocess-Smoke-Anker.
- **297 pytest passed** (+12 neue Wave-D-Coverage).
- **7-Skill-Regression alle PASS:** gmi-accountant 26, getmyinvoices 11, auditor 20, vault-gap-analysis 20, curator 23, reflector 25, session-log 16.

### Strategie-Korrektur (Stefan-Entscheidung 2026-05-16 nach Brille ε)

Wave D ist die **zweite CLI-Konsumenten-Spurprobe** (nach API-Konsum in Wave C), nicht "letzte vor Bündel-Modus". Bündel-Modus-Bereitschaftskriterien werden in Konsolidierungs-Welle v0.12.1 definiert. §12 umsortiert: Phase-2-Scoring v0.11.1 vor Multi-Notebook-Härtung v0.12.0.

### Spec-Pipeline (dokumentiert in `.maintainer/docs/`)

`NOTEBOOKLM-KURATOR-MIGRATION-SPEC.md` (Spec v3), `NOTEBOOKLM-KURATOR-SPEC-CRITIC-PASS-V1.md` (29 Befunde), `NOTEBOOKLM-KURATOR-AUDIT-BRILLE-{ALPHA,BETA,GAMMA,DELTA,EPSILON}.md` (91 Pre-Implementer-Befunde), `NOTEBOOKLM-KURATOR-VORTAG-AUDIT-BRILLE-{A,B,E}.md` (Vor-Tag-3-Brillen-Audit inkl. Brille K als A.2), `MOCK-API-CONTRACT.md` (γ-2-Hebel: Brille K eingeklinkt statt sechste Brille gespart 200-230k Token).

### Backlog v0.11.x (Vor-Tag-Audit-LOW-Befunde, non-blocking)

- Spec §8 veraltete Hook-Yaml-Felder; `_STEFAN_KURATOR_PATTERNS`-Klon-Härtung; AGENTS.md Externe-Plugin-Tabelle; Audit-Log-Atomic-Write-Härtung; Auth-Vorprüfung in `_cmd_standard`; Sicherheitsregel-4-Code-Guard; `SCAN_TARGETS` `.templates` → `templates/` (Bundle-weit, seit Wave A).

## [0.10.1] — 2026-05-16

PATCH-Release: Reife-Härtung nach Post-Tag-Tiefen-Audit mit fünf Sonnet-Brillen (F Adversarial / G Effizienz / H Security / I Karpathy-Adherence / J Doku-Backlog). Drei Konvergenz-Fixes plus drei Trivial-HIGHs. Kein Feature-Scope, kein API-Bruch. v0.10.0 bleibt funktional kompatibel — alle Änderungen sind defensive Härtung.

### Geändert

- **`_lib/env_loader.py`** — neue Funktion `require_path_env_var(name, skill_name, *, allowed_roots, must_exist)` plus `PathEnvVarUnsafeError`. Resolved Path-Env-Vars mit `Path.resolve()` und optionalem Containment-Check gegen erlaubte Wurzeln. Schließt Path-Traversal-Klasse (Post-Tag-5+-Brillen-Konvergenz F-H1+F-H2+F-M2+H-H1+H-L6+I-Lücke-1). Bundle-Standard für künftige API-Skills, die Bundle-Pfade aus Env-Vars konsumieren. Fünf neue Unit-Tests (`tests/unit/test_env_loader.py`), `must_exist=True`-Default, `..`-Traversal-Neutralisierung verifiziert.
- **`.skills/gmi-accountant/gmi_bridge.py`** — `_resolve_bundle_root()` nutzt `require_path_env_var("BUNDLE_ROOT", "gmi-accountant", must_exist=True)`. `BUNDLE_ROOT`-Env-Var aus untrusted Setups führt nicht mehr zu Arbitrary-Code-Load über `cross_skill.import_helper`. Stefan-Bezug im Docstring generalisiert.
- **`.skills/gmi-accountant/workflows/download.py`** — `--target`-CLI-Argument wird durch `_resolve_safe_target` mit `Path.resolve()` und Containment-Check gegen System-Temp plus optionale Env-Liste `GMI_ACCOUNTANT_ALLOWED_TARGET_ROOTS` validiert. Path-Traversal in PDF-Bytes-Ziel-Pfad geschlossen (Post-Tag H-H2). Bei Containment-Verletzung Exit 2 mit klarer Fehlermeldung.
- **`.skills/_lib/test_utils.STEFAN_PRIVATE_GMI_PATTERNS`** — Kommentare verdeutlichen die Zwei-Schicht-Schutz-Strategie für USt-IDs (Post-Tag-Audit G-A6+I-B2 Konvergenz): Schema-Form `\bDE\d{9}\b` in `gmi-accountant/run_evals.py:_check_no_hardcoded_vatids` ist kanonische Quelle, die Hardcode-Liste in `STEFAN_PRIVATE_GMI_PATTERNS` ist Defense-in-Depth-Schicht für Skills ohne eigenen Schema-Check.
- **`.skills/_lib/test_utils.make_gmi_client_mock`** — Windows-Long-Path-Sanity-Check beim Fixture-Aufbau. Bei geplanter Pfad-Länge > 250 chars auf Windows wird `OSError` mit Hinweis auf `LongPathsEnabled`-Registry-Setting erhoben, statt Silent-Truncation oder Race-Condition (Post-Tag F-H3).
- **`.skills/manifest.json.theme_profiles`** — `karpathy.templates` und `business.templates` auf `"default"` umgestellt (Post-Tag D-H2+J-A2 Konvergenz). Beide Profile nutzen das default-Template-Bundle, weil keine separaten Theme-Template-Ordner unter `.templates/` existieren. Schema-Realität jetzt konsistent. Description-Felder klären den Fallback explizit.
- **`.skills/gmi-accountant/gmi_bridge.py:_pre_call_pause`-Docstring** — Halluzinations-Falle korrigiert (Post-Tag G-A2): Behauptung „per autouse-Fixture auf no-op gemockt" durch akkurate Beschreibung ersetzt (Mock-Client umgeht `_call_with_retry` komplett, kein Pause-Mock nötig).

### Backlog-Disziplin (offen für v0.11.0)

Audit-Befunde, die keine 2+-Brillen-Konvergenz hatten und nicht als Trivial-Fix-Sonderkategorie geheilt wurden, bleiben dokumentiert im Handover (`02 Projekte/Second Brain Installationspaket/Handover.md` v0.10.0-Backlog-Tabelle). Auswahl:

- `_strip_filecontent` tuple/set-Branch (Brille H-M1).
- `_calls_log.json` strippt `fileContent` als zweite Verteidigungslinie (Brille H-M2).
- `download.py` PDF-Cleanup im Fehlerpfad (Brille H-M3, DSGVO-Echo).
- Audit-Stempel UTC vs. lokal — Doku-Klärung (Brille F-M1).
- Singleton-Client-Cache öffentliches Teardown (Brille F-H2).
- `_mock_state.json` + `pflichtfelder.json` JSON-invalid-Härtung (Brille F-M3+M4).
- `make_subprocess_api_mock` als generisches `_lib`-Asset (Brille I-Lücke 2).
- `cross_skill.assert_skill_exports` als Lint-Helper (Brille I-Lücke 3).
- `--batch <input.jsonl>` für operativen 100-Belege-Lauf (Brille G-A4).
- Spec §11.3-Status nachpflegen auf „umgesetzt (Option a)" (Brille J-A8).
- Quickstart-URL HEAD-Verifikation vor Release-Announce (Brille J-A1).

### Methodische Erkenntnisse aus Post-Tag-Audit v0.10.0

- **Post-Tag-Tiefen-Audit findet, was Vor-Tag-Audit nicht sieht (Wave-1-Lesson 5).** Die fünf Vor-Tag-Brillen (Cross-Skill / Stefan-Daten / Eval-Pipeline / Architektur / Doku) hatten den `BUNDLE_ROOT`-Path-Traversal-Komplex nicht erfasst. Die fünf Post-Tag-Brillen mit anderem Achsen-Fokus (Adversarial / Effizienz / Security / Karpathy-Adherence / Doku-Backlog) fanden eine **5+ Brillen-Konvergenz** auf demselben Architektur-Punkt. Konsequenz: Post-Tag-Audit ist Pflicht-Gate, nicht Kür.
- **Bundle-Asset-Erweiterung statt Konsumenten-Workaround (Wave-1-Lesson 1).** `require_path_env_var` als drittes Bundle-Asset abwärtskompatibel ergänzen schließt eine Sicherheits-Klasse für alle künftigen API-Skills automatisch. Konsumenten-spezifische `resolve()`-Wrapper wären Drift-Falle.
- **Vault-Steuerungs-Layer-Pflege nach jedem Tag (Wave-1-Lesson 7).** `Handover.md`, `Welle-1-Readiness-Audit.md`, `WAVE-2-MIGRATION-BRIEF.md` werden mit jedem Tag mitgezogen. v0.10.0 hatte das übersehen, v0.10.1 holt es nach.

## [0.10.0] — 2026-05-16

MINOR-Release: Welle 1 Wave C ausgeliefert. `gmi-accountant` als **17. Bundle-Skill** und erster `business`-Profil-Skill migriert. Erster API-konsumierender Bundle-Skill (`depends_on: [getmyinvoices]` in API-Konsumenten-Form, nicht nur Helper-Konsum wie auditor → vault-gap-analysis). Drei Bundle-weite Assets neu: `_lib/env_loader.py` für API-Key-Management, `_lib/test_utils.make_gmi_client_mock` als Mock-Fixture-Vorbild für künftige API-Skills, `cross_skill.import_helper` um optionalen `subpath`-Parameter erweitert. Spec-Critic-Pipeline (Spec v1 → Spec-Critic → Spec v2 → 2× paralleler Implementer mit disjunktem File-Scope → Hauptagent-Sync-Konvergenz-Fix) durchlaufen. Keine Schema-Brüche gegenüber v0.9.0; `cross_skill.import_helper`-Signatur ist abwärtskompatibel erweitert.

### Neu

- **`.skills/gmi-accountant/`** als 17. Bundle-Skill. `default_active.allgemein: false`, `default_active.business: true` (aktiv im business-Profil). MVP-Scope: sechs Workflows (onboarding, trigger, download, write, verify, report), Tag-Ampel (`agent-done`, `agent-review`, `agent-skip`), Confidence-Gate (Brutto > 1000€ oder fehlende Quote-Quelle → Critic), Audit-Stempel-Format `[Agent v1, ...]` als Bundle-Standard eingefroren. Intelligence-Layer (Compliance, Cashflow, Health-Score, supplier_fix, kategorisierung, StB-Paket, Anomalie-Erkennung) bleibt im Vault-Skill, folgt in v0.10.x-Wellen. **26 Eval-Assertions** inkl. zwei depends_on-Degradierungs-Tests (Fall a + b), positivem Cross-Skill-Smoke, fileContent-Sicherheits-Eval, hardcoded-USt-ID-Lint.
- **`.skills/_lib/env_loader.py`** (drittes Bundle-Asset) mit `require_env_var(name, skill_name, *, setup_hint)`, `get_env_var(name, default)`, `EnvVarMissingError`-Exception. Sekret-Hygiene: Env-Var-Wert wird niemals in Exceptions, Logs oder Returns geleakt. Standardpattern für alle künftigen API-konsumierenden Skills. Fünf Unit-Tests.
- **`.skills/_lib/test_utils.make_gmi_client_mock`** als Mock-Fixture für gmi-accountant-Evals plus alle künftigen API-Skill-Tests. Spiegelt die echte `GmiClient`-API (`call(**params)`, `paginate(items_key, ...)`-Generator, `call_path(binary=True)`). Drei Modi: voller Stub, partial (nur `GmiHttpError`, Fall-b-Degradierung), skip_stub (Fall-a-Degradierung). Default-Documents-Vertrag: 5 Belege als Standard-Mix.
- **`templates/.skills/gmi-accountant/`** — fünf Default-Templates (evals.json, evals_verify.json, pflichtfelder.json, extractor-prompt.md, critic-prompt.md) mit `_bundle_template`-/`_please_customize`-Markern. Stefan-spezifische Daten gestrippt: D4-Begleitnamen, konkrete Lieferanten, UIDs, Mandantennamen, hardcoded USt-IDs, Stefan-Vault-Pfade.
- **`.skills/manifest.json.theme_profiles.business`** — neues drittes Theme-Profil neben `allgemein` und `karpathy`: Buchhaltungs- und Finanz-Workflows. Aktiviert `gmi-accountant` plus `getmyinvoices` per Default.

### Geändert

- **`.skills/_lib/cross_skill.py`**: `import_helper(skill_name, module_name, bundle_root=None, subpath="")`-Signatur abwärtskompatibel um optionalen `subpath`-Parameter erweitert. Skills, deren Python-Module unter einem Unterordner liegen (z.B. `getmyinvoices/scripts/gmi_client.py`), können jetzt sauber konsumiert werden — kein Fallback-Workaround mehr im Konsumenten-Code nötig. Cache-Schlüssel-Form unverändert.
- **`.skills/_lib/test_utils.STEFAN_PRIVATE_NAMES_PATTERNS`** um 22 GMI-spezifische Patterns erweitert (D4-Begleitnamen, Lieferanten, konkrete UIDs, hardcoded USt-IDs). Zukunftsschutz: alle künftigen Skill-Migrationen scannen automatisch gegen diese Patterns.
- **`.skills/manifest.json`**: neuer `gmi-accountant`-Eintrag, `getmyinvoices.default_active.business: true` ergänzt (Konsistenz mit neuem business-Profil).
- **`.templates/default/AGENTS.md`**: `gmi-accountant`-Tabellenzeile ergänzt (inaktive Bundle-Skills, business-Profil-only, depends_on-Vermerk).
- **`tests/unit/test_no_umlaut_substitutes.py`**: `GMI-ACCOUNTANT-MIGRATION-SPEC.md` in `SCAN_EXCLUDE_FILES` aufgenommen — Spec führt per Design Pre-Implementer-Grep-Pattern-Strings mit Umlaut-Substituten als Suchpattern (F.5-Lesson-3-Falle).
- **Bundle-Skill-Anzahl**: 16 → **17**. Theme-Profile: 2 → **3** (allgemein + karpathy + business).

### Methodische Erkenntnisse aus Wave C

- **Disjunkter Owner-A/B-File-Scope mit API-Vertrag** funktioniert tokeneffizient bei zwei parallelen Implementern. Spec v2 fixierte `env_loader`-Signatur und `make_gmi_client_mock`-Vertrag verbatim — beide Subagents konnten ohne Sync-Wartezeit parallel arbeiten. Konvergenz-Fixes durch Hauptagent erst nach beider Completion in einem Bundle.
- **Bundle-Asset-Erweiterung statt Konsumenten-Workaround.** Wave-A `cross_skill.import_helper` hatte keinen `subpath`-Parameter, was zum Fallback-Workaround in `gmi_bridge.py` führte. Hauptagent-Sync hat den Workaround zurückgenommen und stattdessen `import_helper` um `subpath` erweitert (abwärtskompatibel). Künftige API-Skills profitieren automatisch.
- **Mock-API spiegelt echte API verbatim, nicht semantisch.** Erste Owner-B-Mock-Version hatte `call(operation_id, params=None)`, echter Client hat `call(operation_id, **params)`. Result: 9 von 11 Behavior-Tests failed. Lesson: Mock-Signatur-Tests sollten im Spec-Critic-Pass mit Verifikations-Call gegen echten Client-Code abgesichert werden.
- **Doku, die das Umlaut-Verbot thematisiert, frisst sich selbst (F.5-Lesson 3 Reaktivierung).** Spec-Datei mit Pre-Implementer-Grep-Pattern-Strings muss explizit in `SCAN_EXCLUDE_FILES` aufgenommen werden. Maintainer-Doku, wandert nicht in den User-Vault — Exclude ist scope-konform.

## [0.9.0] — 2026-05-16

MINOR-Release: Welle 1 Wave B der Karpathy-Compiler-Kette ausgeliefert. `auditor` als 16. Bundle-Skill und 5. Karpathy-Compiler-Skill migriert — damit ist die Compiler-Kette vollständig. Cross-Skill-Code-Konsum via `_lib/cross_skill.import_helper` etabliert: `auditor` importiert `graph_analyzer`-Helfer aus `vault-gap-analysis` (`depends_on: [vault-gap-analysis]`). Drei-Stufen-Subagent-Pipeline (Spec v2 → Implementer → Critic → Verifikations-Brille) durchlaufen. Keine Schema- oder API-Brüche gegenüber v0.8.0.

### Neu

- **`.skills/auditor/`** als 16. Bundle-Skill. `default_active.allgemein: false`, `default_active.karpathy: true` (aktiv im Karpathy-Compiler-Profil). Multi-Mode-Orchestrator `weekly_run.py` mit `_get_now()`-Wrapper und `--override-now`-Flag für deterministische Tests. Wirehead-Schranke default-off. Importiert `graph_analyzer`-Helfer aus `vault-gap-analysis` via `_lib/cross_skill.import_helper`. **20 Eval-Assertions** inkl. zwei Degradierungs-Tests (Fall a: `vault-gap-analysis` fehlt, Fall b: Helfer-Funktion nicht exportiert).
- **`.maintainer/commands/auditor-judge.md`** als Bundle-Slash-Command für Stufe-2-Judge-Pass (manuell auslösbarer Critic-Durchlauf nach wöchentlichem Audit-Bericht). Wird via `.maintainer/scripts/sync_local_commands.py` nach `.claude/commands/` synchronisiert.
- **`templates/.skills/auditor/`** — vier Templates mit `bundle_template`- und `please_customize`-Markern. Stefan-spezifische Pfade und Daten herausgekürzt, sodass Templates portabel für andere Vault-Setups sind.

### Geändert

- **`.skills/manifest.json`**: `auditor`-Eintrag mit `default_active.karpathy: true`, `depends_on: [vault-gap-analysis]`, `bundle_skill: true`. Karpathy-Compiler-Kette-Beschreibung auf 5 von 5 aktiv aktualisiert (curator, reflector, session-log, vault-gap-analysis, auditor).
- **`.skills/_lib/cross_skill.py`**: `bundle_root`-Parameter ergänzt (rückwärtskompatibel, optionaler Keyword-Arg). Dient als Test-Hook für Degradierungs-Tests, bei denen ein gefakter `bundle_root` ohne `vault-gap-analysis` übergeben wird — ohne dass die echte Verzeichnisstruktur verändert werden muss.
- **`.templates/default/AGENTS.md`**: `auditor`-Tabellenzeile ergänzt (Karpathy-Profil-only, `depends_on: vault-gap-analysis` sichtbar).
- **Bundle-Skill-Anzahl**: 15 → **16**. Karpathy-Compiler-Profil aktiv: 4 → **5**. README-Inventar, Architektur-Beschreibung und Quickstart-URL entsprechend aktualisiert.

### Methodische Erkenntnisse aus Wave B

- **Trivial-Fix-Sonderkategorie heilt Critic-Einzelmeinungen ohne Konvergenz-Pflicht.** 1–3-Zeilen-Fixes, die objektiv klar und risikoarm sind (fehlende Tabellenzeile, Tipp-Fehler in Doku, offensichtlicher Import-Alias falsch), werden ohne Zwei-Brillen-Konvergenz geheilt. Der Hauptagent hält das Schiedsrichter-Amt; Sonderkategorie nicht ausweiten auf größere Änderungen.
- **Wave-A-API-Erweiterung via Parameter statt skill-spezifischer Env-Var hält Shared-Helper agnostisch.** `bundle_root`-Parameter in `cross_skill.py` statt `AUDITOR_BUNDLE_ROOT`-Env-Var: der Helper bleibt für alle Skills gleich, Tests injizieren einen gefakten Pfad per Argument. Env-Vars führen zu versteckten Abhängigkeiten und erschwerter Parallelisierbarkeit.
- **Cross-Skill-Konsum via `sys.path`-Trick für `_lib`-Import in VGA-Spec §10 als Vorlage dokumentiert.** `auditor` importiert via `_lib/cross_skill.import_helper(skill_name, module_stem)` — kein manuelles `sys.path.insert`, keine fragilen relativen Imports. §10 gilt als Referenz-Pattern für alle künftigen `depends_on`-Skills.

## [0.8.0] — 2026-05-16

MINOR-Release: Welle 1 Wave A der Karpathy-Compiler-Kette ausgeliefert. `vault-gap-analysis`-Skill ist als Bundle-Skill migriert (Spurprobe der Welle-1-Pipeline nach D.0-Tooling). Neues `_lib/cross_skill.py`-Modul ermöglicht saubere Cross-Skill-Code-Imports zwischen Bundle-Skills mit Bindestrich-Ordnernamen — Voraussetzung für Wave B (`auditor` als Konsument). Drei-Stufen-Subagent-Pipeline (Spec-Critic → Implementer → Multi-Achsen-Audit mit 6 Sonnet-Brillen) etabliert und durchlaufen. Keine Schema- oder API-Brüche gegenüber v0.7.0.

### Neu

- **`.skills/vault-gap-analysis/`** als 15. Bundle-Skill. `default_active.allgemein: false`, `default_active.karpathy: true` (aktiv im Karpathy-Compiler-Profil). Liest den Vault als Wissensgraph, identifiziert schwach verbundene Themen-Cluster und Waisen-Dateien, schlägt konkrete Brücken zwischen isolierten Themen vor. Helper-Module unter `graph_analyzer.py`, deutsche Lokale-Daten unter `locale_data/de.py`. **20 Eval-Assertions** in `eval/vault-gap-analysis.eval.json` (Klassen A/B/C, Wrapper-Pattern für Eval-ID-Stabilität).
- **`.skills/_lib/cross_skill.py`** (neues Modul, 2041 Bytes) mit `import_helper(skill_name, module_stem)`-Funktion: kapselt `importlib.util.spec_from_file_location`-Mechanik für Cross-Skill-Imports zwischen Bundle-Skills. Behandelt Bindestrich-Ordnernamen sauber (`vault-gap-analysis` → Cache-Key `vault_gap_analysis`), gibt klare `FileNotFoundError` mit Diagnose-Pfad bei fehlender Dependency. API-Vertrag für Wave B (`auditor` importiert `graph_analyzer`-Helfer darüber).
- **`.maintainer/commands/vault-gap-analysis.md`** als Bundle-Slash-Command. Wird via `.maintainer/scripts/sync_local_commands.py` nach `.claude/commands/` synchronisiert.
- **`templates/.skills/vault-gap-analysis/gap-history.example.json`** — Default-Historie-Template für User-Onboarding.

### Geändert

- **`.skills/manifest.json`**: `vault-gap-analysis`-Eintrag (default_active mit Karpathy-Profil-Flag, `depends_on: []`, `bundle_skill: true`). Karpathy-Compiler-Kette enthält nun 4 von 5 Skills (`curator`, `reflector`, `session-log`, `vault-gap-analysis`); `auditor` folgt in v0.9.0 als fünfter.
- **`pyproject.toml`**: `python-louvain<1.0` als Pflicht-Bundle-Dependency für `vault-gap-analysis` (Graph-Cluster-Erkennung via Louvain-Methode). Pin auf `<1.0` gegen Maintenance-Risiko. Wird im allgemein-Profil mitgeladen, weil vault-gap-analysis im _lib/cross_skill-Pfad zur Skill-Discovery beiträgt.
- **Bundle-Skill-Anzahl**: 14 → **15**. Aktiv per Default unverändert bei 11 (vault-gap-analysis ist Karpathy-Profil-only). README-Inventar und Architektur-Beschreibung entsprechend aktualisiert.

### Methodische Erkenntnisse aus Wave A

- **Spec-Critic-Subagent VOR Implementer fängt Cross-Skill-Strukturfehler ab.** 13 Befunde im ersten Pass auf Wave-A-Spec v1 (1 CRITICAL, 6 HIGH, 5 MEDIUM, 1 LOW). Stopper waren: `_lib/cross_skill.py`-Modul vergessen in Owner-1-Liste, Import-Mechanik Wave-A↔Wave-B inkompatibel formuliert, `pyproject.toml` statt `requirements.txt` als Dependency-Anker. Spec v2 nach Critic-Pass eingefroren, Implementer arbeitete dann ohne Friktion in einer Welle.
- **Multi-Achsen-Audit mit 6 Sonnet-Brillen als Pflicht-Gate vor jedem Tag.** Sechs Achsen A–F (Architektur, Eval-Vertrag, Cross-Skill-Zahnrad, Doku-Konsistenz, Adversarial-Edge-Case, langfristige Wartung). Audit fand 1 FALSE-POSITIVE CRITICAL — Reviewer-Brille behauptete `_lib/cross_skill.py` fehle, Datei existiert aber mit 2041 Bytes und Eval-Assertion PASS. Plus 2 echte Konvergenz-Pflicht-Fixes (karpathy-Compiler-Kette in manifest.json fehlte noch, frontmatter-Sektion in `run_evals.py` unvollständig) und 3 Trivial-Fixes. Hartregel daraus: **Halluzinations-Verifikation vor Severity-Fix-Pflicht** — Reviewer-Befund ist Hypothese, Datei-Existenz per `ls`/`grep`/`python` verifizieren vor Fix-Entscheidung. Hauptagent hält Severity-Schiedsrichter-Amt.
- **Konvergenz über 2+ Brillen als einziges Pflicht-Fix-Gate vor Tag.** Einzelmeinung bleibt Backlog, egal wie hoch die Severity. Trivial-Fixes (1–3 Zeilen, objektiv klar) sind Sonderkategorie, die geheilt werden ohne Konvergenz-Pflicht. Aus Welle 4 etabliert, in Wave A zur Tag-Hartregel hochgezogen.
- **Wrapper-Pattern für Eval-ID-Stabilität bei jeder `_lib`-Sammel-Assertion Pflicht.** Bindestriche im Skill-Namen werden zu Underscores in Wrapper-Funktionen, die Eval-IDs in `eval/<skill>.eval.json` bleiben generisch und stabil. Verhindert ID-Drift bei künftigen `_lib`-Konsolidierungen.
- **Welle-1-Reihenfolge nach Stefan-Entscheidung 2026-05-16:** Cross-Skill-Code-Dependency `auditor → vault-gap-analysis` führt zu Wave A (`vault-gap-analysis` zuerst, eigenständig) → Wave B (`auditor`, importiert via `_lib/cross_skill.import_helper`). Jede Welle erhält einen eigenen Tag. Argumente: schärferer Post-Konsolidierungs-Smoke-Audit-Scope pro Tag, echter Dependency-Vertrag (Wave B baut auf released Wave A), Risiko-Isolierung, etabliertes Klein-und-häufig-Tag-Pattern.

### Offen für v0.9.0

- **Welle 1 Wave B — `auditor`-Bundle-Migration.** Spec v2 eingefroren 2026-05-16 mit zwei Stefan-Entscheidungen: Slash-Command `/auditor-judge` als `.maintainer/commands/auditor-judge.md` ins Bundle (Option A), `vault-gap-analysis` als Code-Dependency via `_lib/cross_skill.import_helper` (Option α). 17–20 Eval-Assertions geplant inklusive zwei Degradierungs-Tests (Fall a: `vault-gap-analysis` fehlt, Fall b: Helfer-Funktion nicht exportiert). Karpathy-Compiler-Kette wird dann 5 von 5 komplett.
- **Backlog aus Multi-Achsen-Audit Wave A:** Atomare Writes für `gap-report.md` (D.MEDIUM, F.7-Lesson 4), Cold-Start-Doku in `vault-gap-analysis/SKILL.md` (D.MEDIUM), Soft-Privacy in Maintainer-Docs zu absoluten Stefan-Vault-Pfaden (B.MEDIUM), Eval 14a/14b Inhalts-Tiefe für `build_link_index`/`tokenize` (wandert in Wave-B-Implementer-Brief), Standard-Erweiterung um `scope` als legitime fünfte Sektion (A.5), python-louvain Maintenance-Risiko langfristig (F.langfristig).

## [0.7.0] — 2026-05-15

MINOR-Release nach DRY-Konsolidierung Welle 4 plus Härtung 4.1 aus einem Vier-Brillen-Tiefen-Audit. Eliminiert 462 LoC Eval-Runner-Boilerplate über zwei neue `_lib`-Module und einen generischen Sammel-Helper, ohne dass eine einzige Eval-ID bricht. Drei Härtungs-Fixes aus dem nachfolgenden Adversarial-Audit. Keine Schema- oder API-Brüche gegenüber v0.6.1.

### Neu

- **`_lib/eval_runner.py` (neues Modul, 134 LoC)** mit drei Bausteinen für jeden Bundle-Skill-Eval-Runner: `ArgSpec`-NamedTuple für skill-spezifische argparse-Extra-Args, `build_argparser(description, default_evals_file, extra_args=None)` als Standard-Argparser-Fabrik (mit `--verbose` und `--evals-file`), `run_eval_loop(results, verbose) -> int` als Standard-Druck-Loop inklusive zentralem `sys.stdout.reconfigure(encoding="utf-8", errors="replace")`. Wrapper-Pattern in den Skill-Runnern hält die Eval-IDs in `eval/<skill>.eval.json` stabil.
- **Zwei neue Helper in `_lib/test_utils.py`:** `extract_body(text)` ersetzt das `fm_end = text.find("---", 3); body = text[fm_end + 3:]`-Pattern, das in 14 Runnern wortgleich stand. Härtung 4.1: jetzt mit `startswith("---")`-Guard und `\n---`-Anker (Brille 1+3-Konvergenz K1/H1: body-only-Text mit Markdown-Trennlinie wurde vorher falsch geschnitten). `assert_skill_md_mentions_all_feature_flags(skill_md_text, example_yaml_path)` zieht die Welle-3-Pflicht-Assertion `skill_md_mentions_all_feature_flags` zusammen, die in 11 Runnern (von 14, drei ohne Feature-Flag-Sammel-Assertion: cross-check, memory-router, natur-sprech-check) jeweils ~15 Zeilen wortgleich stand.
- **Spec-Dokument `WELLE-4-DRY-SPEC.md`** unter `.maintainer/docs/` als eingefrorene v2-Spec mit Hands-off-Liste (`getmyinvoices.assert_skill_md_mentions_all_feature_flags` wegen Hardcode-Liste, `assert_skill_md_frontmatter_complete` in index-rebuild wegen yaml-Listen-Reads, `get_frontmatter_field` in reflector wegen abweichender Signatur).
- **5 neue Unit-Tests** unter `tests/unit/`: `test_eval_runner.py` (8 Tests inklusive Edge-Case `default_evals_file=None → ValueError`), `test_extract_body.py` (6 Tests inklusive body-only-Trenner und kaputtes Frontmatter), `test_skill_md_mentions_feature_flags.py` (7 Tests inklusive `features:` als Liste statt Dict, leere YAML-Datei).

### Geändert

- **Alle 14 Skill-Eval-Runner** auf die neuen `_lib`-Helper umgestellt. LoC-Total `.skills/*/run_evals.py`: 7133 → **6671 (-462 LoC)**. Eval-IDs unverändert (Snapshot-Diff von 237 IDs vor/nach: leer).
- **Wrapper-Naming-Konvention** etabliert: jeder Skill-Runner mit Sammel-Assertion hält einen lokalen `assert_<skill_unterstrich>_mentions_all_feature_flags(skill_md_text)`-Wrapper, der intern auf `_assert_flags_generic` durchreicht. Bindestriche im Skill-Namen werden zu Underscores (`cross-check` → `assert_cross_check_...`), Eval-ID `skill_md_mentions_all_feature_flags` bleibt stabil.
- **`sys.stdout.reconfigure(encoding="utf-8", errors="replace")`** zentral in `run_eval_loop` statt vorher in 2 von 14 Runnern (`migration`, `getmyinvoices`) doppelt — Encoding-Verhalten ist jetzt für alle 14 Runner konsistent. Doppel-Calls entfernt.
- pytest-Assertion-Zahl: 266 → **287 passed** (266 Bestand + 21 neue Edge-Case-Tests aus Welle 4 + Härtung 4.1).

### Behoben (Härtung 4.1 aus Vier-Brillen-Tiefen-Audit)

- **`extract_body` schneidet body-only-Text mit Markdown-Trenner nicht mehr falsch** (Brille 1 HOCH + Brille 3 K1/H1/H4, einzige Konvergenz im Audit). Vorher: `text.find("---", 3)` traf bei einem Text wie `"# Überschrift\n\n---\n\nBody danach"` den Body-Trenner und gab `"\n\nBody danach"` zurück statt des vollen Texts — stiller Datenverlust. Jetzt: `startswith("---")`-Guard zuerst, dann `\n---`-Anker. Zwei neue Tests: `test_extract_body_body_trenner_kein_frontmatter`, `test_extract_body_frontmatter_und_body_trenner`.
- **`assert_skill_md_mentions_all_feature_flags` crasht nicht mehr bei `features:` als YAML-Liste** (Brille 3 K2). Vorher: uncaught `AttributeError: 'list' object has no attribute 'keys'`. Jetzt: `isinstance(features, dict)`-Check mit klarer FAIL-Note `"features muss ein Mapping sein, ist: list"`. Neuer Test: `test_features_als_liste_statt_dict_fail`.
- **`build_argparser` wirft jetzt `ValueError` bei `default_evals_file=None`** (Brille 3 H3). Vorher: argparse-Default `None` schlug stillschweigend durch, `args.evals_file.resolve()` crashte beim Aufruf eines Runners ohne `--evals-file`-Flag mit `AttributeError`. Schützt vor stillen Crashes beim 15. Bundle-Skill. Neuer Test: `test_build_argparser_default_evals_file_none_raises`.

### Methodische Erkenntnisse aus Welle 4

- **Spec-First mit Critic-Pass spart Implementer-Token.** Spec v2 (nach Spec-Critic mit Sonnet-Subagent) hat zwei Spec-Stopper vor Implementer-Welle abgefangen: `parse_frontmatter`-Helper wurde gestrichen wegen Overlap mit existierendem `get_fm_field` plus C-2-Risiko bei Listen-Reads (index-rebuild liest `depends_on`/`conflicts_with` als Listen via `yaml.safe_load`), und `getmyinvoices.assert_skill_md_mentions_all_feature_flags` wurde zu Hands-off, weil die Hardcode-Liste-statt-yaml-Read sonst lautlos Drift erzeugt hätte.
- **Disjunkter Datei-Owner-Schnitt + Sonnet statt Haiku für Implementer.** Owner 2 (7 Runner) und Owner 3 (7 Runner) parallel mit null File-Overlap, beide Sonnet trotz deterministischer Refactor-Aufgabe. Begründung: die Sonderfälle (cross-check ohne feature_flags, natur-sprech-check mit per-Flag-Assertions statt Sammel, getmyinvoices Hardcode-Liste, `--vault`-Default-Varianten zwischen session-log und index-rebuild) hätten Haiku blind konsolidiert. Token-Aufpreis Sonnet war günstiger als der Fix-Aufwand für einen Eval-ID-Bruch.
- **Post-Konsolidierungs-Smoke-Audit hat H-1 gefunden (Wrapper-Naming).** Pflicht-Gate aus der v0.6.1-Hartregel. Smoke-Audit-Subagent fand: vier Runner (curator, decomplex, index-rebuild, kreuzverhoer) hatten ihre Wrapper als `assert_skill_md_mentions_all_feature_flags` ohne Skill-Prefix angelegt — funktional korrekt (Eval-ID kommt aus dem `results.append`-String), aber Spec-Bruch und Drift-Falle für künftige Copy-Paste-Refactors. Vor Tag gefixt.
- **Vier-Brillen-Tiefen-Audit als zweites Gate nach Smoke-Audit.** Architektur, Cross-Skill-Zahnrad, Adversarial-Edge-Case (alle Sonnet) plus Doku-Konsistenz (Haiku). Echte Konvergenz nur bei einem Befund (`extract_body`-Magic-Number-3-Problem) — Konvergenz schlägt Einzelmeinung, weil sie Bias-resistent ist. Haiku-Brille lieferte zwei False Positives — Lesson für künftige Audit-Wellen: Konsistenz-Brille trotz deterministischer Aufgabe Sonnet.

### Offen für v0.7.x / v0.8

- **yaml-Mehrfach-Reads ohne Cache** (Brille 1 Effizienz-HOCH). `assert_skill_md_mentions_all_feature_flags` liest `skill.config.example.yaml` bei jedem Aufruf neu. Auf SSD unmessbar, auf OneDrive messbar.
- **Flag-Substring-False-Positive** (Brille 3 H2). `flag not in body` ist Substring-Match — Flag `auth` matcht `authentication`. Heute keine konkrete Drift, weil Flag-Namen lang genug sind. Welle-5: Wortgrenzen-Regex.
- **`session-log` Hybrid-Subprocess** (Brille 2 HOCH, pre-existing): `run_write_log()` nutzt subprocess.run direkt statt `run_subprocess_utf8` aus `_lib`.
- **`session-log` Lint-Asserts außerhalb tempfile-Block** (Brille 2 HOCH, pre-existing): strukturelle Abweichung als Copy-Paste-Vorlage.
- **`run_subprocess`-Alias-Drift** (Brille 2 MITTEL): `index-rebuild` und `project-session-end` importieren als `run_subprocess`, andere voll qualifiziert.
- **build_argparser-Aufrufstil-Inkonsistenz** (Brille 2 MITTEL): 6 Runner positional, andere keyword.
- **`ArgSpec` als `namedtuple` statt `dataclass(frozen=True, slots=True)`** (Brille 1 MITTEL).
- **`extract_body`-Modul-Zuordnung** (Brille 1 MITTEL): gehört konzeptionell nicht in `test_utils.py`.
- **BOM-Offset in `extract_body`** (Brille 3 H4): mit UTF-8-BOM würde `startswith("---")` `False` zurückgeben. Heute kein SKILL.md mit BOM.
- **`getmyinvoices` Hardcode-Liste vs yaml** (Brille 2 NIEDRIG, strukturell): heute synchron, Drift-Falle bleibt.
- Bestehende Backlog-Punkte aus [0.6.1]: Codex-Hook-Aktivierung, Profil-Aware `mirror_skills`, GMI-Smart-Skip-WARN, INSTALL.md-Vokabular, `bundle_version_drift_check` gegen `sync-state.json`, 9 Welle-2-Skills `skill_md_frontmatter_complete`-Erweiterung, `datetime.utcnow()`-Migration.

## [0.6.1] — 2026-05-15

PATCH-Release nach Post-Tag-Tiefen-Audit (sechs Achsen F/G/H/I/J/K, jede mit qualifiziertem Sonnet-Subagent). Drei CRITICALs und fünf weitere HIGHs aus dem Audit nachgezogen. Keine Schema- oder API-Brüche gegenüber v0.6.0.

### Behoben

- **`trigger_enforcer._load_active_skills` crasht nicht mehr bei OneDrive-NTFS-File-Locks** (Audit H-C1, CRITICAL). Der Hook fing bisher nur `json.JSONDecodeError`, aber kein `OSError`. Während OneDrive-Sync mid-write den atomic-replace ausführt, konnte `read_text()` einen `PermissionError` werfen und damit den UserPromptSubmit-Hook crashen. Jetzt zusätzlicher `OSError`-Handler mit stderr-Warnung und sauberem Fallback auf `default_active`-Approximation.
- **`wikilink_validator` blockt `memory-router`-Writes nicht mehr stillschweigend** (Audit I-C1, CRITICAL). `type: notiz` war seit Welle 1 nicht in der `exempt_types`-Liste des Hooks. memory-router gab Exit 0 zurück, aber der Hook hat jeden Schreibversuch blockiert — Inbox-Notes wurden silent verworfen. Jetzt ist `notiz` in `exempt_types` ergänzt. Regression-Test `test_notiz_type_is_exempt` neu in `test_wikilink_validator.py`.
- **`/skill-activate`-Command existiert real** (Audit J-C1, CRITICAL). `.commands/skill-activate.md` neu mit Workflow: Vorprüfung, Manifest-Edit-Vorschau, sync.py-Aufruf, Fehler-Rollback. Schließt die Lücke zwischen Doku-Versprechen (README, INSTALL, AGENTS.md, migration/SKILL.md) und tatsächlicher Aktivierungs-Implementierung für Opt-in-Skills (`migration`, `getmyinvoices`, `projekt-mentor`).
- **`bundle_version_drift_check`-Hook ist nicht mehr dauerhaft stumm** (Audit F-H2, HIGH). `sync.py` spiegelt jetzt `bundle.json` nach `.docs/bundle.json` (analog zu `sync-state.json`, atomarer Write via `Path.replace()`). Bisher las der Hook eine nie geschriebene Datei und gab silent allow zurück — seit v0.5.0 funktionslos.
- **`mirror_skills` ist atomar** (Audit K-H2, HIGH). Vorher: `shutil.rmtree(dst)` + `shutil.copytree(src, dst)` mit Korruptions-Fenster zwischen den beiden Operationen. SIGKILL oder OneDrive-Lock mid-delete konnte zu leerem Skill-Spiegel führen. Jetzt: copytree in `.new`-Staging, dann atomares Rename mit Rollback auf `.old`-Sicherung bei OSError.
- **`gmi_client.py` gibt klare Fehlermeldung bei fehlendem `requests`** (Audit H-H2, HIGH). PEP-723-Header ergänzt (`dependencies = ["requests..."]`) für direkten `uv run`-Aufruf. `try/except ImportError` um den Import-Block mit Hinweis auf `uv sync --extra gmi`. Vorher: ungefilterter `ModuleNotFoundError` ohne Setup-Anleitung.
- **`output_filter` fängt Compound-Wörter mit Praefix Ü und Suffix -fügen** (Audit I-H2, HIGH). Bisher kannte `UMLAUT_REPLACEMENTS` nur ganze Wörter — Compounds wurden vom Stop-Hook nicht ersetzt, obwohl `_lib/test_utils.UMLAUT_SUBSTITUTES_PATTERNS` sie seit f.8/f.9 fängt. 13 neue Wort-Einträge ergänzt: übernommen, übergeben, überschreiben, überschrieben, überspringen, überlegen, übertragen, überträgt, übergebenen sowie hinzufügen, einfügen, ausfügen, zusammenfügen.
- **AGENTS.md-Template dokumentiert Codex-Hook-Asymmetrie korrekt** (Audit F-H3, HIGH). Bisher behauptete die Codex-Sektion „Hooks aktiv: PreToolUse, SessionStart, Stop, UserPromptSubmit" — tatsächlich ist `tool_support.codex: false` in allen sechs `hook.yaml`-Dateien. Codex-User glaubten falsche Sicherheit. Jetzt steht explizit drin, dass alle Hooks in der Codex-Schicht aktuell deaktiviert sind und Codex-Aktivierung v0.7-Backlog ist.

### Geändert

- README und CHANGELOG auf v0.6.1 hochgezogen. pytest-Assertion-Zahl 265 → 266 (neuer Regression-Test für I-C1).
- Test-Fixtures in `tests/unit/test_wikilink_validator.py`, `tests/unit/test_hook_io_contract.py` und `tests/scenarios/test_scenario_03_wikilink_protection.py` von `type: notiz` auf `type: bereich` umgezogen — sonst hätten die Tests die neue `exempt_types`-Ausnahme als „Test bestanden trotz fehlender Wikilink-Anforderung" falsch belohnt. `type: bereich` ist die nächstliegende nicht-exempte Vault-Kategorie.

### Methodische Erkenntnisse aus dem Audit

- **Post-Konsolidierungs-Audit als Pflicht-Gate (neue Hartregel).** Der v0.6.0-Tag hatte das fünfte Auftreten des Premature-Tag-Musters: Audit lief auf dem Stand vor der Konsolidierung, Konsolidierungs-Commit selbst (f.9 mit 34 Dateien) lief ungeprüft in den Tag. pytest-Grün ist KEIN Audit-Ersatz. Ab v0.6.1 muss jeder Bump-Commit einen Post-Konsolidierungs-Smoke-Audit-Subagent als Gate haben. Dieser Patch-Release demonstriert das Pattern: 8 Fixes plus ein Smoke-Audit vor dem Tag.
- **Doku-versprochene Commands müssen vor dem Tag existieren.** `/skill-activate` wurde an fünf Doku-Stellen versprochen, die Command-Datei fehlte. Das war kein Backlog-Punkt, sondern eine strukturelle Lücke im Aktivierungspfad für Opt-in-Skills.
- **Sechs-Achsen-Tiefen-Audit findet, was Drei-Stufen-Pipeline nicht sieht.** Achsen F (Fresh-User), G (DRY), H (Architektur-Adversarial), I (Cross-Skill-Zahnrad), J (Session-Eigenkritik), K (Worst-Case) haben drei CRITICALs aufgedeckt, die der lokale Critic-Pass auf den Phase-2-Implementer-Outputs übersehen hat. Speziell I-C1 (memory-router silent broken seit Welle 1) und H-C1 (trigger_enforcer-Crash auf OneDrive) waren Cross-Skill-Defekte außerhalb des Critic-Scopes.

### Offen für v0.7

- DRY-Konsolidierung Welle 4: `run_eval_loop()`-Helper in `_lib`, `assert_skill_md_mentions_all_feature_flags`-Helper, `parse_frontmatter()`-Helper, `extract_body()`-Helper. Audit G hat ~450–500 eliminierbare Zeilen über die 14 Eval-Runner identifiziert.
- Codex-Hook-Aktivierung. `tool_support.codex: true` in den Hooks freigeben, nachdem die `hookSpecificOutput`-Schema-Differenz validiert ist.
- Profil-Aware `mirror_skills`. Bisher spiegelt jeder Sync-Lauf alle vault-scope-Skills, unabhängig vom Profil. Bei zwei Profilen mit unterschiedlichen aktiven Skills entsteht stille Inkonsistenz (Audit H-H3).
- GMI-Smart-Skip auf WARN-Status statt PASS heben (Audit C-M2/J-H2).
- INSTALL.md-Vokabular-Umstieg `default_active` → `active_skills via Profil`.
- `bundle_version_drift_check` gegen `sync-state.json.bundle_version` prüfen statt zwei separate Versions-Quellen zu pflegen.
- 9 Welle-2-Skills nutzen `skill_md_frontmatter_complete` mit 4 Feldern statt 6 (Audit A-M1).
- `datetime.utcnow()` in `sync.py` durch `datetime.now(datetime.UTC)` ersetzen (16 DeprecationWarnings bei pytest).

## [0.6.0] — 2026-05-15

MINOR-Release nach drei aufeinanderfolgenden v0.6.0-Tech-Debt-Wellen: f.7 Profil-Resolution + State-Vertrag, f.8 migration Welle 2 + getmyinvoices Eval-Hub, f.9 Konsolidierung nach 5-Achsen-Audit (HEAD `ccd7964`). Kein Schema-Bruch, kein API-Bruch. Bundle reift substanziell gegenüber v0.5.1.

### Neu

- **`resolve_active_skills(manifest, profile) -> list[str]`** in `.skills/sync.py` (f.7) — Kahn-Toposort mit alphabetischem Tie-Break, BFS-Dep-Expansion auch über inaktive Deps, Zyklus-Erkennung. Externe Cloud-Skill-Deps (z.B. `notebooklm` als Backend für `notebook-research`) werden mit stderr-Warnung übersprungen statt hartem raise — der konsumierende Skill bleibt aktiv (F.4.13-Lesson 1, Doku-Test als Eval-Typ).
- **`--profile <name>`-Parameter** für `sync.py` (f.7). Default: erstes Profil alphabetisch aus `theme_profiles` (heute „allgemein").
- **`.docs/sync-state.json`** um zwei Felder erweitert (f.7): `active_profile` (str) und `active_skills` (list[str], topologisch sortiert). Atomarer Write via `Path.replace()` schützt gegen truncated-State bei Prozess-Abbruch oder OneDrive-Sync mid-write.
- **`_load_active_skills(cwd)`-Helper** in `trigger_enforcer.py` (f.7) liest die kanonische `active_skills`-Liste mit drei Fallbacks: Datei fehlt, kaputtes JSON, fehlendes Feld, `schema_version != 1` → Fallback auf alte `default_active`-Approximation. Strikt-Pfad bei Erfolg, Fallback-Pfad bei Erstinstall.
- **migration-Skill auf Welle-2-Logik gehoben** (f.8) — Stub raus, `scan_old_vault.py` mit harter 5-Verzeichnis-Whitelist plus Frontmatter-Filter und Kategorisierung in neun Klassen (read-only via `Path.read_text`). `candidate_filter.py` mit kanonischer Sortierreihenfolge (Glossar → Schreibstil → Branding → Kontext-Sonstiges → Prinzip → Routine → Projekt → Bereich → Ressource), `--only-active-projects`-Flag und `--category`-Filter. `default_active.allgemein: false` bleibt — Aktivierung opt-in über `/skill-activate migration` (kommt mit v0.6.x). Drei Verhaltens-Toggles in `skill.config.example.yaml`: `include_active_projects_filter`, `include_areas_and_resources`, `include_size_limit`. SKILL.md-Abschnitt „Schreib-Allowlist und Schutzumfang" dokumentiert den Read-only-Garantie-Umfang.
- **getmyinvoices auf Bundle-Eval-Standard** (f.8) — neue `run_evals.py` als Hub (Muster B mit Subprocess-Delegation) mit 11 Assertions: Lint, Schema/Loader plus Behavior an pytest-Suite (`tests/`, ~190 Tests) und Healthcheck-Import. Neue `skill.config.example.yaml` mit drei Toggle-Flags (`include_banking_features`, `include_write_operations`, `include_payment_runs`; Code-Verdrahtung als v0.7-Tech-Debt vermerkt). Bestehende pytest-Suite unangetastet.
- **`[project.optional-dependencies] gmi = ["requests>=2.31,<3.0"]`** in `pyproject.toml` (f.8) — opt-in via `uv sync --extra gmi`. Bundle-venv bleibt schlank; die zwei Behavior-Assertions im GMI-Eval-Hub werden bei fehlender Extra als `[SKIP]` markiert (zählen als PASS mit klarem Hinweis), Lint und Loader laufen trotzdem.
- **`tests/unit/test_sync_resolve.py`** mit 12 Tests (f.7).
- **`tests/unit/test_migration_scripts.py`** mit 14 Tests (f.8) — Unit-Tests gegen direkt importierte `scan_vault()` und `filter_candidates()`-Funktionen.
- **5 neue Tests in `test_trigger_enforcer.py`** (f.7) für strikten Profil-Filter, Dep-only-Skill, Erstinstall-Fallback, Defekt-JSON-Fallback, Empty-Array-Stille, Schema-Version-Guard, Stale-Skill-Drift.
- **3 weitere Critic-Audit-Tests in test_sync_resolve.py** (f.7): Self-Loop-Zyklus, Three-Way-Tie-Break, Stale-Skill-Name.
- **`expected_ids_match_runner_results`-Abschluss-Block in 11 Bundle-Skills nachgezogen** (f.9, Audit-Befund C-H1) — Welle-1- und frühe Welle-2-Skills (cross-check, curator, decomplex, index-rebuild, kreuzverhoer, natur-sprech-check, notebook-research, project-session-end, projekt-mentor, reflector, session-log) bekommen den Drift-Guard analog `getmyinvoices` / `migration` / `memory-router`. Jeder Skill +1 Assertion (z.B. reflector 24 → 25, project-session-end 21 → 22).
- **`assert_default_active_allgemein_is_false` in projekt-mentor-Eval** (f.9, Audit A-M2) — Persona-Modus-Skill ist opt-in, Eval-Drift-Schutz analog migration und getmyinvoices.
- **`skill_md_no_umlaut_substitutes` in index-rebuild-Eval** (f.9, Audit A-M3) — Klasse-B-Konsistenz mit den anderen 13 Skills nachgezogen.

### Geändert

- `aggregate_mcp(vault, manifest, active_skills)` neue Signatur (f.7). Iteriert über die topologische Liste statt der `any(default_active.values())`-Approximation. Verhalten bei Single-Profil-Manifesten unverändert.
- `sync.log` ergänzt um `active_profile=<name> active_skills=[...]` (f.7).
- `tests/unit/test_sync.py` und `tests/unit/test_sync_mcp.py` nutzen jetzt `PYTHONUTF8=1 + PYTHONIOENCODING=utf-8` in allen Subprocess-Aufrufen (f.7).
- `UMLAUT_SUBSTITUTES_PATTERNS` in `.skills/_lib/test_utils.py` (f.8 + f.9) — zwei neue Compound-Stem-Patterns ergänzt, die das Suffix `fügen` (Wortenden wie hinzufügen, einfügen) und das Präfix `über` mit nachfolgendem Buchstaben (Compounds wie übernehmen, übergeben, überschreiben) fangen. Vorher fielen beide Wortfamilien durch die ganzwortige Wortgrenzen-Architektur (F.5-Lesson 2 in Aktion).
- **9 user-facing Umlaut-Substitut-Stellen gefixt** (f.9, Audit B-HIGH): `companies.py` und `documents.py` Substitut-Form für „übernommen" → echtes Unicode (User-Output bei silently_dropped-Feldern), `search_documents.py` Substitut-Form für „übergeben" → echtes Unicode (argparse help-Text), analoge Korrekturen in Kommentaren von `gmi_client.py`, `get_document.py`, `frontmatter_validator.py`, `bank_transactions.py`, `test_workflow_lookup.py`, `conftest.py`.
- **AGENTS.md-Template** (f.9, Audit D-M3): migration-Skill-Beschreibung von „B.1-MVP-Stub, volle Logik kommt mit Welle 3" auf „Welle-2-Logik vollständig (scan_old_vault.py + candidate_filter.py); Aktivierung opt-in über `/skill-activate migration` (kommt mit v0.6.x)" aktualisiert.
- **README.md** (f.9, Audit E-M1+M2+M3): Skill-Inventar-Überschrift v0.5.0 → v0.5.1, pytest-Zahl 231 → 265 im Status-Block, „Offen für v0.6.0"-Liste bereinigt (erledigte Punkte raus, neue Tech-Debt aus f.7+f.8-Audits rein), migration-Zeile auf Welle-2-Logik aktualisiert.
- pytest-Assertion-Zahl: 231 → 265 (20 in f.7 + 14 in f.8 = 34 neue Tests). Eval-Pipeline 13 → 14 mit run_evals.py (getmyinvoices jetzt vollwertiger Eval-Hub).

### Offen für v0.6.x (Backlog)

Tech-Debt aus den 5-Achsen-Audits am Ende von f.7 und f.8:

- Slash-Command `/skill-activate` implementieren — Doku verspricht ihn an mehreren Stellen (README, INSTALL, AGENTS.md, migration/SKILL.md), kein Command-File unter `.commands/`. Ohne ihn ist die neue Profil-Resolution read-only.
- INSTALL.md Vokabular-Umstieg `default_active` → `active_skills via Profil`, plus Abschnitt „Profile".
- `bundle_version_drift_check` gegen `sync-state.json.bundle_version` prüfen oder Designentscheid dokumentieren.
- AGENTS.md trigger_enforcer-Beschreibung um Profil-Resolution-Erweiterung ergänzen.
- 9 Welle-2-Skills nutzen `skill_md_frontmatter_complete` mit 4 Feldern statt 6 — `scope` und `default_active` brauchen direkten Eval-Guard (Audit A-M1).
- GMI Smart-Skip-Output deutlicher als „unvollständige Coverage" markieren (Audit C-M2).
- Datums-abhängige Assertions in index-rebuild und memory-router robuster machen (Audit C-M3).
- Codex-Spiegel-Asymmetrie (`mirror_skills` schreibt nur nach `.claude/skills/`) entweder umsetzen oder BOOTSTRAP.md-Formulierung präzisieren (Audit D-M1).
- FORBIDDEN_WORDS-Test-Architektur ganzwortig → stem-match konsolidieren (F.5-Lesson 2 weiter offen).

## [0.5.1] — 2026-05-13

PATCH-Release nach Multi-Achsen-Audit der v0.5.0-Welle. Sieben Konsolidierungs-Commits in der f.5.x-Welle (Versions-Drift CRITICAL, Umlaut-Pattern-Härtung, Welle-1-Nachpflege, AGENTS.md-Discovery, README-Onboarding, Brief-Lessons) plus fünf Commits in der f.6.x-Welle (Stem-Match-Test-Architektur, Body-Leak-Sweep, Doku-Fakten, neue Drift-Tests, Versions-Bump). Bundle ist substanziell reifer als v0.5.0, ohne Schema- oder API-Brüche.

### Behoben

- **Pattern-Architektur:** `tests/unit/test_no_umlaut_substitutes.py` nutzt jetzt sowohl die ganzwortige `EXPLICIT_FORBIDDEN_WORDS`-Liste (Legacy) als auch die Stem-Pattern-Liste `UMLAUT_SUBSTITUTES_PATTERNS` aus `.skills/_lib/test_utils.py`. F.5-Lesson 2 operationalisiert — eine neue Pattern-Erweiterung in `_lib` fängt automatisch alle Wortvariationen im globalen Test. SCAN_TARGETS um `README.md`, `.templates/`, `.maintainer/` erweitert.
- **~45 Umlaut-Substitute** in `getmyinvoices`-Skill (SKILL.md plus alle Workflow-Skripte plus gmi_client.py plus tests/-Suite) sowie `index-rebuild/run_evals.py`, `memory-router/write_inbox_note.py` und `.maintainer/scripts/_private_patterns.py`. User-sichtbare CLI-Help-Texte und Skill-Bodies durchgehend mit echten Umlauten.
- **Pattern-Liste** `UMLAUT_SUBSTITUTES_PATTERNS` um neun Stems erweitert: abhäng-, Abwärts, anhäng-, ausschließ-, enthält, Lädt, Läng-, unabhäng-, zusätzlich (alle als lowercase mit `re.IGNORECASE`).
- **index-rebuild Klasse-B-Frontmatter-Sammel-Assertion:** Neuer Eval-Eintrag `skill_md_frontmatter_complete` analog zur Welle-Mehrheits-Variante (Audit γ MEDIUM). Schließt Drift bei `default_active`, `description`, `depends_on`, `conflicts_with`.
- **README + CHANGELOG Doku-Fakten:** „12 mit run_evals.py + 2 mit tests/-Suite" auf korrekte 13 + 1 (nur getmyinvoices) korrigiert. „228+ pytest" auf exakte aktuelle Zahl. „Architektur in zwei Sätzen" auf drei Sätze.
- **Versions-Bump 0.5.0 → 0.5.1** in `bundle.json`, `manifest.json.bundle.version` und allen 14 SKILL.md-`bundle_version`-Feldern. `bundle_version_drift_check`-Hook bleibt wirksam.

### Neu

- **`tests/unit/test_manifest_skill_md_drift.py`** mit zwei Tests:
  - `test_manifest_skill_md_consistency`: erzwingt Drift-Freiheit zwischen `manifest.skills.<name>` und `<skill>/SKILL.md`-Frontmatter für `default_active.allgemein`, `depends_on`, `bundle_skill`. Fängt jede zukünftige `cross-check`-Klasse-Drift in CI.
  - `test_bundle_version_consistency`: erzwingt, dass `bundle.json.version` exakt mit jedem SKILL.md-`bundle_version` übereinstimmt. Hand-Bump-Schutz beim Versions-Update.

### Geändert

- README-Versions-String, Quickstart-URL und Status-Block zeigen jetzt v0.5.1.
- pytest-Assertion-Zahl: 229 → 231 (zwei neue Drift-Tests).
- `WAVE-2-MIGRATION-BRIEF.md` enthält den vollen F.5.1–F.5.6-Lessons-Block (Repo-Inventur als Schritt -1, Test-Architektur-Wechsel, Doku-frisst-sich-selbst-Falle, Welle-Mehrheits-Konsistenz, Multi-Achsen-Audit-Pflicht).

### Offen für v0.6.0

- `trigger_enforcer`-Asymmetrie: nach `/skill-activate` zieht der Push-Hook nicht automatisch nach (Sync-Lauf nötig).
- `sync.py` Dep-Resolution und Profil-Selektion.
- `migration`-Skill auf vollwertige Logik heben (B.1-Stub auflösen).
- `getmyinvoices` auf einheitlichen Eval-Standard (Tech-Debt #60 und #64).
- Slash-Command `/skill-activate` implementieren oder aus Doku entfernen.
- Naming-Konvention dokumentieren (kebab-case Skills, snake_case Hooks, ASCII-Slug `kreuzverhoer`).

## [0.5.0] — 2026-05-13

Welle-2-Wave-3-Release. 14 Bundle-Skills sind im Manifest, alle mit `bundle_skill: true`, 11 davon `default_active: true`. Drei Migrations-Wellen (D, F.3, F.4) abgeschlossen, 229 pytest-Assertions grün, kein Stefan-Daten-Leak im Bundle-Body, keine Umlaut-Substitute im Produktiv-Code.

Post-Release-Konsolidierung in f.5.1–f.5.5 hat Audit-Befunde nachgezogen (Versions-Drift in Manifest und bundle.json, ~60 Umlaut-Leaks in `getmyinvoices`-Workflows, `cross-check`-Manifest-Drift, Welle-1-Nachpflege bei `session-log`/`index-rebuild`/`reflector`, AGENTS.md-Sichtbarkeit für inaktive Skills, `notebooklm`-Plugin-Abhängigkeit transparent).

### Neu

- **14 kuratierte Skills** mit voller Eval-Pipeline: `cross-check`, `curator`, `decomplex`, `getmyinvoices`, `index-rebuild`, `kreuzverhoer`, `memory-router`, `migration`, `natur-sprech-check`, `notebook-research`, `project-session-end`, `projekt-mentor`, `reflector`, `session-log`. Dreizehn davon mit `run_evals.py` plus Eval-Manifest, einer (`getmyinvoices`) mit eigener pytest-basierter `tests/`-Suite.
- **AGENTS.md-Cross-Tool-Verfassung** mit Skill-Index, Hook-Index, Pflicht-Checks, Sektion für inaktive Bundle-Skills und externe Plugin-Abhängigkeiten.
- **Drei-Schichten-Generalisierungs-Standard** für Skills (Loader-API, Pfad-Placeholder, vier Pflichtsektionen in `skill.config.example.yaml`).
- **`_lib/test_utils.py`** mit gemeinsamen Lint-Patterns (`STEFAN_PRIVATE_NAMES_PATTERNS`, `UMLAUT_SUBSTITUTES_PATTERNS`) und Helper-Funktionen (`setup_bundle_json`, `run_subprocess_utf8`, `assert_template_has_bundle_markers`).
- **6 aktive Hooks**: `frontmatter_validator`, `wikilink_validator`, `trigger_enforcer`, `output_filter`, `sync_drift_check`, `bundle_version_drift_check`.
- **Konsistenz-Tests** (`tests/unit/test_agents_md_consistency.py`) erzwingen Manifest ↔ AGENTS.md ↔ Hook-Index in beide Richtungen — auch für inaktive Skills.

### Behoben

- **Versions-Drift (CRITICAL):** `manifest.bundle.version` und `bundle.json.version` standen vor f.5.1 noch auf `0.0.1` trotz Welle-2-Reifegrad. `bundle_version`-Felder in allen 14 SKILL.md auf `"0.5.0"` gesetzt — `bundle_version_drift_check`-Hook ist jetzt erstmals wirksam.
- **Umlaut-Hygiene:** `UMLAUT_SUBSTITUTES_PATTERNS` von 14 auf 42 Stems erweitert (neue Stamm-Familien für die Wörter bestätig-, binär-, führ-, geprüft, gelöscht, lösch-, möglich, natürlich, Rückgabe, tatsächlich, unabhängig, zurück- und weitere). `FORBIDDEN_WORDS` im globalen pytest-Test analog erweitert. ~60 konkrete Substitut-Stellen in `getmyinvoices`-Workflows, `gmi_client.py`, `frontmatter_validator` und `memory-router` gefixt.
- **Welle-1-Nachpflege:** `session-log` und `index-rebuild` haben jetzt die Feature-Flag-Body-Symmetrie-Assertion (F.4.4-Lesson 1). `reflector` hat zwei neue depends_on-Tests (Fall a: session-log-Output fehlt komplett; Fall b: session-log-Datei ohne `processed`-Feld) — beide via `reflect.py`-Subprocess mit tempfile-Vault.
- **Konsistenz:** `bundle_skill_name`-Outlier im `cross-check`-Manifest entfernt. Welle ist Mehrheits-konform (nur `skill`-Identifier).
- **Discovery:** AGENTS.md-Skill-Index zeigt jetzt auch die drei inaktiven Skills (`getmyinvoices`, `migration`, `projekt-mentor`) in einer eigenen Sektion plus externe Plugin-Abhängigkeiten (`notebooklm`, Key-Wrapper).

### Geändert

- Bundle-Reihenfolge im Manifest-`skills`-Objekt: alphabetisch (vorher unsortiert nach Welle-1-Stand).
- `notebook-research/SKILL.md`: expliziter „Externe Abhängigkeit"-Block am Anfang erklärt, dass `notebooklm` als Plugin-Skill erwartet wird (kein Bundle-Skill).

### Offen für v0.6.0

- `sync.py`-Refactor: Dep-Auflösung bei Profil-Selektion, Symmetrie zwischen `mirror_skills` und `aggregate_mcp` bzgl. `default_active`.
- `migration`-Skill auf vollwertige Logik heben (B.1-Stub auflösen).
- `getmyinvoices` auf einheitlichen Eval-Standard (Tech-Debt #60 und #64).
- FORBIDDEN_WORDS-Test-Architektur von ganzwortig auf Stem-Matching umstellen (konsolidieren mit `UMLAUT_SUBSTITUTES_PATTERNS`).

## [0.1.2] — 2026-05-11

Mini-Hotfix nach Sub-Projekt B+. Adressiert einen latenten A-Severity-Bug aus
dem v4-Re-Run (Edit/MultiEdit-Pfad im `frontmatter_validator`). Eine
Fehlbeobachtung aus dem v4-Re-Run wird zurückgezogen (Hook-Reihenfolge in
`settings.json` war bereits korrekt — Manifest und Live-Vault stimmen überein).

### Behoben

- **Edit/MultiEdit-Post-Simulation im `frontmatter_validator`.** Vor 0.1.2 hat
  der Hook bei `Edit` und `MultiEdit` auf den Disk-Stand vor dem Edit
  zurückgegriffen. Ein Edit, das valides Frontmatter zerstört, rutschte durch,
  wenn die Datei vorher korrekt war. Neue Helper `_apply_edit()` und
  `_apply_multi_edit()` simulieren den Post-State (inkl. `replace_all` und
  MultiEdit-Sequenz) und prüfen erst danach gegen die Pflichtfelder. Elf neue
  Unit-Tests decken Block-, Allow-, replace_all-, Empty-Edits- und
  Nonexistent-File-Pfade ab. Drei bestehende Tests wurden auf die neue
  Edit-Wirkungs-Semantik umgestellt — der Hook ist jetzt **Edit-Wirkungs-Prüfung**
  (zerstört das Edit das Frontmatter?), nicht mehr **Datei-Gesundheits-Prüfung**
  (jede angefasste Datei muss valides Frontmatter haben). Nebeneffekt: kaputte
  Frontmatter-Dateien können jetzt repariert werden, statt blockiert zu
  bleiben.
- **TOCTOU-Schutz im Disk-Read.** `path.exists()` plus separates `path.read_text()`
  ist nicht atomar — die Datei kann zwischen Check und Read verschwinden
  (OneDrive-Sync, paralleler Prozess, Windows-File-Lock). Neuer Helper
  `_read_disk()` fängt `OSError` direkt und liefert `None`, was vom Aufrufer
  als Allow-Fallback interpretiert wird. Verhindert ungefangenen
  `FileNotFoundError` mit Exit 1 (kein CC-Hook-Contract).

### Zurückgezogen

- **Welle-2-Item „Hook-Reihenfolge in `.claude/settings.json` umdrehen".** Die
  v4-Re-Run-Beobachtung war falsch. `.skills/manifest.json` listet
  `frontmatter_validator` bereits vor `wikilink_validator`, und die im Vault v4
  generierte `settings.json` spiegelt diese Reihenfolge korrekt. Item entfällt
  aus dem Welle-2-Backlog.

### Welle-2-Backlog (unverändert gegenüber 0.1.1, eines weniger)

F3, F4, F5, F7, F8, F13, F15 plus neue Beobachtungen aus dem v4-Re-Run
(OneDrive-Cleanup-Retry, `trigger_enforcer`-UserPromptSubmit-Probe,
`bundle.json`/`manifest.json`-Repo-Files-Diagnose, Stop-Hook-Block-Variante,
SessionStart-Block-Probe).

## [0.1.1] — 2026-05-11

Patch-Release nach Sub-Projekt B+ (MVP-Anwendung des v0.1.0-Bundles auf einen
frischen Test-Vault). Sechs Findings aus dem Testlauf adressiert plus eine
Follow-up-Welle für Befunde aus drei Subagent-Reviews. Kein Feature-Zugang,
keine Spec-Bruchstellen — nur Hardening.

### Behoben

- **F11 — Hook-Output-Protokoll-Mismatch.** Drei Hooks (`frontmatter_validator`,
  `wikilink_validator`, `sync_drift_check`) gaben `{"action": "block", ...}`
  mit Exit 0 zurück. Claude Code kennt nur Exit 2 + stderr,
  `{"decision": "block", "reason": "..."}` oder `hookSpecificOutput` und
  winkte das Tool bei dem unbekannten JSON durch. `_decide()`/`decide()`
  bleiben pure, `main()` interpretiert das Decision-Dict und wechselt aufs
  Exit-2-Pattern. Neuer Hook-Contract-Test als Vorlage für künftige Hooks.
- **F14 — UTF-8 für Hook-stdout/stderr.** Fünf Hook-Skripte rufen am
  `main()`-Anfang `sys.stdout.reconfigure(encoding="utf-8", errors="replace")`
  und analog für stderr auf. Verhindert Replacement-Zeichen und Mojibake bei
  deutschen Umlauten auf Windows-cp1252-Default. Subprocess-Aufrufe in den
  Hook-Tests bekommen `encoding="utf-8"` für Pipe-Symmetrie.
- **F2 — `.codex/config.toml` in jedem sync-Lauf schreiben.** `sync.py` legte
  die Datei nur an, wenn ein Hook `tool_support.codex: true` hatte. Im MVP
  haben alle Hooks `codex: false`, also fehlte die Datei trotz expliziter
  BOOTSTRAP.md-Spec („IMMER beide Tool-Konfigurationen"). Jetzt symmetrisch
  zu `.claude/settings.json` mit Stub-Header bei leeren codex-Hooks.
- **F10 — `memory-router` Pflicht-Quoting für description.** Skill schrieb
  Frontmatter ohne explizite `description: "..."`-Vorgabe. Latente
  YAML-Bombe bei einem `: ` im Beschreibungstext. SKILL.md-Workflow-Schritt
  präzisiert, Eval um Quoting-Szenario erweitert, statischer Test gegen
  Skill-Template-Drift.
- **F6+F9 — Setup-Doku raus aus dem Vault-Root (Option C).** `BOOTSTRAP.md`,
  `INSTALL.md` und Repo-`README.md` landeten nach Setup im Vault-Root.
  Repo-README jetzt in `.bundleignore`; Phase 10b in INSTALL.md löscht
  BOOTSTRAP.md und INSTALL.md aus dem Staging vor dem atomaren Move. Setup-
  Doku bleibt auf GitHub im versionierten Repo abrufbar. Eine frühere
  Variante mit `.docs/setup/`-Move wurde verworfen, weil Obsidian
  versteckte Ordner standardmäßig nicht indexed (Subagent-Review).
- **F1 — uv-Check Bash primär.** BOOTSTRAP.md-Anweisung präzisiert: erst
  `bash -c "uv --version"`, dann robuster PowerShell-Fallback mit
  `where.exe uv`. Beendet die Vier-Versuche-Schleife im B+-Testlauf auf
  Windows.

### Follow-up (drei Subagent-Reviews der v0.1.1-Welle)

- **Umlaut-Verstöße in `.skills/sync.py` und Hook-Docstrings.** ae/oe/ue-
  Ersatz in TOML-Stub-Header und in fünf `main()`-Docstrings korrigiert.
  Neuer statischer Test `tests/unit/test_no_umlaut_substitutes.py` scannt
  `.skills/`, INSTALL.md, BOOTSTRAP.md, CHANGELOG.md gegen eine kuratierte
  Verbots-Liste; `output_filter.py` ausgenommen (UMLAUT_REPLACEMENTS-dict
  enthält die ae/oe/ue-Formen per Design).
- **F14-Lücke in `sync_drift_check.py:141`** — `subprocess.run`-Aufruf um
  `encoding="utf-8"` und `errors="replace"` ergänzt. Stellt sicher, dass
  sync.py-Fehlermeldungen mit Umlauten auf Windows nicht cp1252-decodiert
  durch den Drift-Check tunneln.

### Welle-2-Backlog (nicht in 0.1.1)

F3 (Schritt-7-Whitelist), F4 (OneDrive-Robustheit), F5 (AGENTS.md-Pre-Fill),
F7 (TaskNotes-Präfix), F8 (ZIP-Timestamps), F13 (Path-Format-Hardening im
sync_drift_check), F15 (`00 Kontext/`-Templates). Zusätzlich: F11-Variante
für `trigger_enforcer` (UserPromptSubmit-Schema `hookSpecificOutput` gegen
echte Session proben), Edit-Pfad-Post-Simulation im `frontmatter_validator`.

## [0.1.0] — 2026-05-10

Erstes öffentliches Release des Second-Brain-Bundles.

### Enthalten

- **3 Skills (Vault-Scope):** `session-log`, `memory-router` (Inbox-only Phase B.1),
  `natur-sprech-check`
- **5 Hooks:** `frontmatter_validator`, `wikilink_validator`, `trigger_enforcer`,
  `output_filter` (warn-only), `sync_drift_check`
- **4 Slash-Commands:** `/skill-new`, `/skill-edit`, `/sync-repair`, `/index-rebuild` (Stub)
- **Setup-Pipeline:** 13 Phasen via `tools/sync.py` mit atomarem Move, Drift-Check
  und Mirror nach `.claude/` plus `.codex/`
- **6 Eval-Szenarien:** fresh_install, frontmatter_block, wikilink_protection,
  drift_repair, atomic_setup, hook_next_session
- **Release-Pipeline:** GitHub-Pages-Distribution unter `bootstrap.lehnisch.de`,
  versionierte Pfade, SHA-256-Sidecar, gerenderte BOOTSTRAP.md

### Bekannte Einschränkungen

- `latest.zip` wird nicht erzeugt — Bootstrap-Pattern arbeitet mit versionierten
  Pfaden. Atomic-Promotion für `latest.zip` ist als Backlog für v0.2.0 vermerkt.
- `memory-router` routet ausschließlich nach `01 Inbox/`, volle PARA-Logik kommt mit
  Welle 2.
- `output_filter` läuft als Warn-Hook (Stop-Hook kann den emittierten Output
  technisch nicht umschreiben).
- Pre-Release-Tags (`v*-rc*`) und Production-Tags (`v0.1.0`) sollten auf
  unterschiedlichen Commits liegen — GitHub Pages dedupliziert Deployments auf
  Commit-SHA-Basis.
