← Mac-Diktat
Changelog
Alle nennenswerten Änderungen an Mac-Diktat. Format orientiert an Keep a Changelog, Versionsschema folgt SemVer — siehe ADR-0010.
[Unreleased]
[0.1.16] - 2026-11-10
Added
- Änderungen im Verlauf markiert: Im aufgeklappten Verlauf zeigt die App, was Layer 2 und Layer 3 geändert haben. Entferntes ist rot durchgestrichen, Eingefügtes trägt Textmarker und Unterstreichung. Ein Schalter neben dem Kopierknopf blendet die Markierung aus.
- Wörterbuch: Bindestrich-Begriffe flexibler: Ein Eintrag wie „UI-Experte” greift jetzt auch bei „UI Experte” und „UIExperte”. Gebeugte Formen mit üblicher Endung zählen mit, etwa „UI Experten” → „UI-Experten”.
Fixed
- Glättung mit Apple Intelligence verweigert seltener: Harmlose Technik-Sätze lösten Apples Sicherheitsfilter aus, die Glättung fiel dann auf Layer 2 zurück. Die App nutzt jetzt den Modus für Textumformungen.
- Versionsnummern: „Version 0.1. 15” wird zu „Version 0.1.15”.
- Die Update-Prüfung meldet „kein Update” nicht mehr als Fehler im Log.
[0.1.15] - 2026-11-08
Security
- Parakeet-Download an fester Revision (ADR-0106 Amendment 2): Die App lädt das Parakeet-Modell von einem festen Stand auf Hugging Face, nicht mehr vom beweglichen
main. Jede Datei wird einzeln gegen ihre Prüfsumme geprüft, bevor das Modell installiert wird. Eine Änderung auf main bricht frische Installationen nicht mehr. Der Fortschritt zeigt echte Bytes.
- Modell-Downloads folgen Weiterleitungen nur noch über HTTPS.
[0.1.14] - 2026-11-08
Added
- Geschützte Begriffe bleiben geschützt (ADR-0107): Ändert die Glättung einen Begriff aus dem Wörterbuch, setzt die App ihn zurück.
- Schlusspunkt bei kurzen Diktaten (ADR-0108): Ein kurzer, vollständiger Satz endet mit Satzzeichen, auch wenn die Glättung ihn überspringt. Suchfelder und einzeilige Felder bekommen keinen Punkt.
Changed
- Schneller eingefügt (ADR-0105): Vom Loslassen bis zum Text vergehen im Mittel 1,06 s statt 1,31 s. Lange Ausreißer sind halbiert.
- Viele interne Aufräumarbeiten ohne sichtbare Änderung: Duplikate zusammengelegt, große Funktionen zerlegt, Grenzwerte benannt.
Security
- Datenabfluss und Lieferkette (ADR-0106):
- Remote-STT und Remote-Glättung verlangen HTTPS. Unverschlüsseltes HTTP geht nur noch an diesen Mac selbst. Ein Whisper-Server im LAN über
http:// braucht jetzt HTTPS oder einen Tunnel.
- Den Verlauf im Klartext gibt die externe API nur noch mit Token heraus, auch im Modus „Ohne Token”.
- Der lokale llama-server verlangt je Start einen neuen Schlüssel. Websites erreichen das Modell nicht mehr. Seine Web-Oberfläche ist aus.
- Parakeet prüft die Modelldateien vor jedem Laden, nicht erst danach. Der Download öffnet keine Datei, bevor die Prüfung stimmt. Scheitert das Laden, endet es mit Fehler statt mit einem ungeprüften Neudownload.
- Leitet ein HTTPS-Endpoint auf unverschlüsseltes HTTP um, bricht die Anfrage ab. Audio und Text folgen dem Redirect nicht.
- Updates verlangen einen signierten Feed und prüfen die Signatur vor dem Entpacken.
- Der Release signiert nur Feed-Einträge aus der eigenen Kopie. Weicht der Live-Feed davon ab, bricht der Release ab.
- Server-Fehlermeldungen und Endpoint-Adressen landen bereinigt im Log und im Diagnose-Export.
- Der Hinweis zum API-Key nennt den wirklichen Ablageort: den Anmelde-Schlüsselbund.
- Externe API gehärtet (ADR-0098 Amendment): Vier Lücken vor der Anmeldung sind geschlossen.
- Ein Bearer-Wert ab 256 Zeichen beendete die App. Jetzt antwortet die API 401.
- Gefälschte IPv6-Adressen wie
fe80::ffff:7f00:1 gelten nicht mehr als lokal.
- Die API weist fremde
Host- und Origin-Header mit 403 ab. Das schließt DNS-Rebinding im Modus „Ohne Token”. Im LAN-Modus ohne Token funktionieren nur IP-Adressen, .local-Namen und einteilige Rechnernamen. Mit Token bleiben auch interne Namen wie mac.fritz.box nutzbar.
- Offene Verbindungen sind begrenzt und haben Fristen. Das gilt auch für Live-Streams, deren Client nicht liest.
- Ein Wechsel von Modus oder Anmeldung trennt offene Verbindungen sofort.
Fixed
- Parakeet ließ sich frisch nicht installieren: Seit dem 19.08.2026 scheiterte der Download an der Hash-Prüfung. Grund: Der Anbieter hat eine Metadatei geändert, die die App nicht liest. Sie zählt nicht mehr zur Prüfung.
- Audio-Lebenszyklus (ADR-0104): Aufnahme und Hotkey blockieren sich nicht mehr gegenseitig.
- Alle Engine-Operationen laufen auf einer eigenen Queue. Ein Re-Press am Ende des Tail-Drains verliert kein Diktat mehr.
- Der Hotkey-Tap läuft auf einem eigenen Thread. Eine belegte App bremst die Tastatur des Systems nicht mehr.
recorder.start blockiert den Main-Thread nicht mehr. Pille und Start-Ton kommen, sobald die Engine läuft.
- Fällt die Aufnahme aus, startet sie auf einer frischen Engine neu, höchstens dreimal. Danach läuft das bisher Gesprochene durch die Pipeline, und die Pille meldet den Ausfall.
- Ein fest gewähltes Mikrofon mit anderer Sample-Rate als das Standardgerät lieferte keinen Ton, obwohl die Pille lief.
- Verwurf in der Pille sichtbar (ADR-0103 Amendment): Nach einem rettbaren Verwurf zeigt die Pille 3 s „Verworfen – im Verlauf wiederholbar“. Grund: Das Banner erscheint nur im Hauptfenster.
- Verworfene Diktate sind rettbar (ADR-0103 Amendment): Ein falscher Verwurf ist nicht mehr endgültig.
- Das Audio der letzten drei verworfenen Läufe bleibt im Arbeitsspeicher. Es verschwindet beim Beenden und landet nie auf der Platte.
- „Erneut transkribieren“ steht im Banner und im Verlauf. Der Text erscheint im Ergebnis-Fenster. Die App fügt ihn nicht ein und lässt die Zwischenablage in Ruhe.
- Kurze Diktate in langen Pausen überstehen den Phantom-Filter.
- Eine hängende Transkription blockiert folgende Diktate nicht mehr. Jeder Lauf hat eine Frist, eine hängende Engine wird ersetzt.
- Kein stiller Diktatverlust (ADR-0103): Vier Ursachen sind behoben.
- Lange Pausen verwerfen ein Diktat nicht mehr. 6 s Sprache in 120 s Aufnahme kommen durch.
- Überlappende Diktate überholen sich nicht mehr. Der Text erscheint in der Reihenfolge, in der du gesprochen hast.
- Verworfene und verlorene Diktate stehen im Verlauf, mit Grund. Das gilt für Stille, VAD, Transkriptionsfehler, fehlendes Audio und den Sicherheitsfilter.
- Ein gescheiterter Whisper-Reset führt nicht mehr zum Absturz.
- Hotkey ausfallsicher (ADR-0102): Drei Ausfälle des Hotkeys sind behoben.
- Ein verlorener Release lässt das Mikrofon nicht mehr offen. Die App gleicht den Hotkey alle 5 s mit dem echten Tastenstand ab.
- Auch der Hold-Modus hat jetzt ein Maximum von 5 min.
- Scheitert der Neuaufbau des Event-Taps, versucht die App es weiter und zeigt einen Hinweis. Vorher blieb der Hotkey still tot.
- Eine hängende Ziel-App blockiert den Hotkey nur noch 0,25 s statt bis zu 6 s.
- 8-s-Budget gilt für die ganze Glättung (ADR-0097 Amendment 2): Auswahl des Backends, Prompt-Bau, Glättung und Anker-Retry teilen sich jetzt eine Frist.
- Qwen-Kaltstart blockiert kein Folgediktat (ADR-0097 Amendment 2): Das Modell lädt außerhalb des Backends. Das Laden überlebt das Timeout, das nächste Diktat nutzt den fertigen Kontext.
- Timeout bricht auch den Prompt-Decode ab (ADR-0097 Amendment 2): Ein Abbruch erscheint nicht mehr als „Text zu lang”. Der nächste Lauf ist sauber.
- Qwen-Anker gibt den RAM frei (ADR-0097 Amendment 2): Er bleibt nur noch während eines Ausfalls geladen.
- Orphan-Bereinigung trifft nur den eigenen Helper (ADR-0097 Amendment 2): Prozesse, die den Pfad nur nennen, und andere Installationen bleiben unberührt.
- Glättung hängt nicht mehr am Backend (ADR-0097 Amendment): Das 8-s-Timeout greift jetzt auch bei Qwen. Die Decode-Schleife bricht beim Timeout ab.
- Gemma-Helper heilt sich selbst (ADR-0097 Amendment): Ein Respawn überlebt das Timeout. Das Diktat wartet nicht auf den Boot und fügt den Layer-2-Text ein.
- Ein einzelner Backend-Fehler beendet den Helper nicht mehr.
- Der Crash-Zähler überlebt das Routing auf Qwen.
- Ein Boot-Crash fällt sofort auf und zählt einmal.
- Externe API meldete fälschlich „Port belegt”: Wurde die API kurz nach dem Start neu gestartet, hielt sie ihren eigenen, noch schließenden Listener für einen fremden Dienst und schaltete sich ab. Der Stopp wartet jetzt, bis der Port wirklich frei ist.
[0.1.13] - 2026-11-06
Added
- Geschützte Begriffe im Verlauf sichtbar (ADR-0044): Der Verlauf zeigt jetzt, welche geschützten Begriffe die LLM-Glättung aus dem Text entfernt hätte. Zwei Fälle werden unterschieden: Die Prüfschicht hat den Wegwisch abgefangen und den Begriff wieder eingesetzt, oder er ist wirklich verloren gegangen. Das Feld war seit Schema V8 ein leerer Platzhalter.
Fixed
- Gemma 4 ließ sich nicht mehr neu installieren: Die Datei bei Hugging Face hatte sich seit dem 09.07.2026 geändert. Der Download endete deshalb nach 12,7 GB mit einem Prüfsummenfehler. Die Adresse zeigt jetzt auf den Stand, der zur hinterlegten Prüfsumme passt. Vorhandene Installationen sind nicht betroffen.
- Chromium-Browser bekamen beim Einfügen zu wenig Zeit: Brave, Chrome, Edge und ihre installierten Web-Apps liefen mit dem kurzen Restore-Wait von 250 ms. Liest der Browser die Zwischenablage später, kommt das Diktat nicht an. Sie laufen jetzt wie Electron-Apps mit 700 ms. Das Inject-Log nennt zusätzlich Ziel-App, Art des Zwischenablage-Inhalts und das Ende der Sequenz.
- Die Engine-Auswahl nannte für Whisper die falsche Geschwindigkeit: Dort stand seit dem 19.04.2026 „~1× Echtzeit”, gemessen sind es rund 15 (RTF 0,067). Parakeet stand mit ~170 statt 167 daneben, und zusammen ließen die beiden Angaben Parakeet 170-mal schneller aussehen als Whisper statt elfmal. Die Technik-Seite zeigte aus derselben Konstante die ganze Zeit den richtigen Wert. Beide Etiketten werden jetzt aus
approxRTF gerechnet statt von Hand geschrieben, LocalSTTEngineTests hält die Verbindung fest.
- Wörterbuch-Vorschläge blieben nach dem Annehmen stehen: Wer einen Vorschlag annahm, dabei aber eine der angebotenen Fehl-Erkennungen bewusst wegließ, bekam denselben Vorschlag erneut. Die weggelassenen Varianten gelten jetzt als behandelt. Taucht dieselbe Verhör-Variante später neu auf, wird sie wieder vorgeschlagen.
- Hauptmenü nach dem Ruhezustand: Eine über Nacht laufende Instanz zeigte nach Sleep/Wake wieder das allgemeine Menü, ohne „Bearbeiten” (⌘C, ⌘V und ⌘A piepten nur) und ohne „Nach Updates suchen …“. Das Menü wird jetzt fortlaufend verteidigt statt einmalig gesetzt.
Security
- CSV-Export gab Klartext heraus, auch im redigierten Modus:
GET /api/v1/history?format=csv schrieb den Diktattext bedingungslos, während JSON und Markdown den Datenschutzmodus beachteten. In der Kombination aus unverschlüsseltem LAN-Zugang und abgeschalteter Authentifizierung stand er damit ohne Anmeldung im Netz. Die Klartext-Spalte hängt jetzt am selben Schalter wie die beiden anderen Formate.
- Redigierter Export enthielt Wörterbuchbegriffe: Die Zusatzangaben eines Bereichs-Exports führten die Begriffe des Nutzers mit. Sie fallen jetzt weg, die reinen Konfigurationsangaben bleiben.
- Sprachmodell-Bundle strikt gegen den gepinnten Hash: Der Parakeet-Download hatte einen Rückfallpfad, der ein unbekanntes Bundle beim ersten Mal akzeptierte. Jeder Download wird jetzt hart gegen die hinterlegte Prüfsumme geprüft, wie beim Sprachaktivitäts-Modell auch.
[0.1.12] - 2026-07-01
Fixed
- Spracherkennung ließ sich auf neuen Installationen nicht einrichten: Bei einer Neuinstallation brach der Download des Parakeet-Sprachmodells mit „Integritätsprüfung fehlgeschlagen” ab. Ursache war eine veraltete Prüfsumme nach einem Update der Transkriptions-Bibliothek. Bestehende Installationen waren nicht betroffen.
- Hotkey nach dem Ruhezustand: Der Push-to-Talk-Hotkey wird nach dem Aufwachen des Macs wieder zuverlässig erkannt.
[0.1.11] - 2026-06-20
Added
- Zwei-Toggle-Update-Modell (ADR-0010): Auto-Suche und Auto-Installation von Updates sind jetzt getrennt schaltbar, und die Einstellungen zeigen „Update verfügbar” direkt an, sobald der Feed eine neue Version meldet.
Changed
- Lokales LLM: RAM-abhängige Kontextgröße: Die Kontextfenster-Größe des lokalen Qwen3-Modells wird jetzt am physischen Arbeitsspeicher ausgerichtet, statt fix gewählt zu werden — größerer Kontext auf Maschinen mit genug RAM, sparsamer auf kleinen.
Fixed
- Texteinfügung in nicht-aktivierende Overlays: Driftet der Fokus in ein Overlay-Panel, das das Fenster nicht aktiviert (z. B. ChatGPT-Desktop), wird der Text jetzt zuverlässig ins tatsächlich fokussierte Ziel eingefügt — über einen HID-Tap statt eines Abbruchs.
- Diktat-Idle-Reset im Aufnahme-Fehlerpfad: Schlägt der Start der Aufnahme fehl, wird der Idle-Reset jetzt korrekt armiert, statt die Zustandsmaschine hängen zu lassen.
- Update-Feed: Negative-Cache: Die Appcast-Validierung nach dem Veröffentlichen nutzt jetzt Backoff gegen einen kurzlebigen Negative-Cache, der frische Releases sonst zu früh als ungültig meldete.
[0.1.10] - 2026-06-15
Added
- Automatische Updates über Sparkle 2 (ADR-0010): Mac-Diktat prüft selbst auf neue Versionen gegen den signierten Update-Feed unter
mac-diktat.de und kann sie auf Wunsch installieren. Der Appcast ist EdDSA-signiert; der echte Public Key liegt in der Info.plist. Dies ist die erste Sparkle-fähige Version — der Auto-Update-Pfad greift ab v0.1.10 aufwärts.
Changed
- Egress-API: Zugriffs- und Authentifizierungsmodell (ADR-0098): Erreichbarkeit und Zugriffsschutz sind jetzt getrennt einstellbar. Drei Zugriffsmodi — „Nur dieser Mac” (Loopback, empfohlen), „Tailscale” (folgt) und „Lokales Netzwerk unverschlüsselt” (Expertenmodus) — plus eine unabhängige Schutz-Wahl (Bearer-Token erforderlich / Ohne Token). Die Statuskarte zeigt den effektiven statt des gewünschten Zustands. Der vollständige Forensik-Export (
history?privacy=full) ist über die tatsächliche Client-IP am Socket abgesichert, nicht über den fälschbaren Host-Header. Der wirkungslose TLS-Schalter wurde entfernt; verschlüsselter Transport kommt im Tailscale-Modus von Tailscale.
Fixed
- Layer-3-Resilienz (llama-server) (ADR-0097): Ein Crash-Loop des lokalen LLM-Servers ist jetzt in der UI sichtbar und wird mit automatischem Qwen-Routing, Liveness-Prüfung, Mid-Diktat-Fallback gegen den Anker und einer GGUF-Integritätsprüfung abgefangen — statt stiller Ausfälle.
- Foundation-Models-Content-Refusal: Eine Inhalts-Ablehnung der Apple-Foundation-Models (macOS 27) wird jetzt als
safetyBlocked klassifiziert und sauber behandelt statt als harter Fehler zu enden.
- Modell-Download-Resume bei Range-ignorierenden Servern: Wenn beim Fortsetzen eines Downloads (
Range: bytes=<offset>-) der Server den Range-Header ignoriert und mit 200 OK plus vollem Body (statt 206) antwortet, wurde der Vollbody an den Teilstand angehängt → korrupte .tmp, die der Post-Download-SHA verwarf und im nächsten Lauf komplett neu lud. Der StreamingDelegate (geteilt von Whisper- und Layer-3-Downloader) erkennt den 200-auf-Range-Fall jetzt, verwirft den Teilstand und schreibt den Body von vorne — ein einziger sauberer Download statt Doppel-Transfer.
[0.1.9] - 2026-06-13
Sammelrelease der Stabilitäts- und Layer-Offensive (Phasen A–C) seit v0.1.8.
Added
- Apple-Speech-Engine als Layer-1-STT-Alternative (ADR-0077): vollwertige Transkriptions-Engine auf Basis von Apple SpeechAnalyzer mit eigenen Logs und Unit-Tests, neben Parakeet wählbar.
- Phantom-Token-Suppressor (ADR-0089, Phase B): Layer-2-Stage, die wiederkehrende Halluzinations-Fragmente unterdrückt.
- Audio-Energie- und VAD-Forensik (ADR-0089, Phase A): HistoryEntry-Schema v11 speichert Energie- und VAD-Kennzahlen pro Diktat für die spätere Failure-Analyse.
- Pausierbarer Layer-3-Modell-Download: ein Abbruch behält den Range-Resume-Teilstand, der Download setzt beim nächsten Start fort statt neu zu laden.
- Egress-API Auto-Restart mit Backoff nach einem Listener-Ausfall — die Forensik-Schnittstelle kommt nach einem Fehler selbsttätig zurück.
- llama-server Crash-Watchdog mit Crash-Loop-Schutz: ein abgestürzter Layer-3-Server wird neu gestartet, eine Absturzschleife wird erkannt und gebremst.
- Adress-Komma-Stage im Layer-2-Chain sowie ein importierbares Coding-/Obsidian-Wörterbuch.
Changed
- Distribution auf arm64-only umgestellt: keine Universal-Binary mehr (Intel-Unterstützung bewusst fallen gelassen).
- FluidAudio von 0.13.6 auf 0.14.7 angehoben.
- Stabilitätsoffensive (C2/C3):
PostProcessor.swift in 15 Step-Dateien aufgeteilt, Boot-Logik in dedizierte Supervisoren extrahiert (Smoothing, StatusBarHealth, STTEngineSwap) — interne Umstrukturierung ohne Verhaltensänderung, durch Golden- und Smoke-Tests abgesichert.
- Migration-Stashes lock-geschützt statt
nonisolated(unsafe).
Fixed
- TextInjector-Warte-Fenster bei App-Shutdown abbrechbar — kein Hängen mehr beim Beenden während eines laufenden Inject.
- Egress-History-Export läuft async statt über
DispatchQueue.main.sync (vermeidet Main-Thread-Blockade).
- Voice-Command: „folgender Punkt” wird als Nomen geschützt statt als Befehl interpretiert.
- Layer-2-Joiner: „rela” wird als Layer-Homophon behandelt.
- Settings: die Auswahl „Apple Intelligence” markiert wieder die zugehörige Radio-Zeile.
[0.1.8] - 2026-05-25
Fixed
- Apple-SpeechAnalyzer-STT meldete „Apple Sprachmodell nicht installiert” trotz vorhandenem Modell (ADR-0077, Amendment V): Die Verfügbarkeitsprüfung hing an
AssetInventory.status(forModules:) == .installed. Unter macOS 26 verlangt dieser Status eine aktive, system-weite Locale-Allokation (AssetInventory.allocate) — ein bloß auf Disk vorhandenes Asset meldet nur .supported. Die App hielt diese Allokation nie selbst; nachdem das System die (geliehene) Reservierung wieder einzog, kippte der Status zurück und es folgten roter Menübar-Punkt, Hotkey-Fehlerton und ein „Sprachmodell laden”, das in einer 3-ms-Phantom-Download-Schleife lief. Behoben: Verfügbarkeit prüft jetzt SpeechTranscriber.installedLocales, und die App reserviert die Locale selbst via AssetInventory.allocate(locale:) beim Laden und best-effort vor jeder Session. Erklärt das Muster „lief stundenlang, nach dem letzten Diktat plötzlich tot”.
[0.1.7] - 2026-05-24
Added
- Wörterbuch-Vorschläge aus der Korrektur-Historie (ADR-0088): eine Mining-Engine wertet abgelehnte/korrigierte Diktate aus und schlägt neue Lexikon-Einträge vor. Eigene Vorschläge-Sammelseite mit Annehmen/Ignorieren, ein Decision-Sidecar merkt sich Entscheidungen. Entdeckbarkeit über Banner und Sidebar-Badge sowie einen Inline-Nudge im CorrectionSheet. Mehrwort-Einträge decken Einzel-Token-Vorschläge mit ab; bei Real-Wort-Aliasen wird die Annahme bewusst bestätigt, „Ignorieren” ist ein direkter Button.
- Zweistufiges Silence-Gate mit optionalem Silero-VAD (ADR-0087): nach dem RMS-Gate kann optional ein hash-gepinntes Silero-VAD-Modell Sprache von Geräte-Rauschen trennen. Eigene Settings-Section mit Toggle und bewusstem Modell-Download; der RMS-Schwellwert
0.85 bleibt der robuste Default.
- Real-Wort-Linter für
soundsLike-Aliase (ADR-0079): warnt, wenn ein Lexikon-Alias ein echtes deutsches oder englisches Wort ist (Kollisionsschutz, z. B. „die” ↔︎ „Tahoe”), inkl. Duplikat-Warnung, Acknowledge-Button und Audit-Aktionen. Per-Eintrag unterdrückbar (suppressRealWordWarning, Lexikon-Schema v7). Die Casing-Erkennung berücksichtigt großgeschriebene deutsche Substantive.
- Fidelity-Direktive für
style=original (ADR-0085): core.minimal erhält eine Treue-Direktive, die bei wörtlicher Glättung den Inhalt unverändert lässt.
- Egress: Pre-Bind-Port-Probe + Konflikt-Diagnose (ADR-0066): der Port wird vor dem Bind geprüft, Konflikte werden mit Diagnose gemeldet statt mit Crash.
- Akronym-Allow-Liste erweitert (ADR-0069 Amendment): zusätzlich
LLM und API.
Changed
- Bearbeiten-Menü zurück: das AppKit-Hauptmenü wird nach der SwiftUI-Initialisierung installiert; die Editing-Shortcuts (⌘C/⌘V/⌘A/⌘Z) funktionieren menüunabhängig auch im
.accessory-Modus und im Menüleisten-Panel — kein System-Beep mehr in Textfeldern.
- Tonalität im Quick-Panel gesperrt, wenn das Backend sie ignoriert: Capability-Gating im Menüleisten-Panel (Apple FM bzw. Layer 3 aus).
- Zielabhängiger Restore-Wait beim Pasteboard-Inject: native Apps 250 ms, langsame Electron-Apps 700 ms (
PasteTargetProfile) — gegen Paste-Races.
- Tail-Drain gegen verschlucktes Schlusswort: Drain-Fenster auf gemessene 300 ms kalibriert.
- Layer-N-Joiner gegen Lexikon-Asymmetrie (ADR-0082).
Fixed
- Few-Shot-Token-Bleed im Layer-3-Prompt behoben (ADR-0080): Beispiel-Substantive leakten in Fragmente.
- Subset-Truncation-Sanity gegen Layer-3-Verstümmelung (ADR-0081).
- Anti-Instruktions-Direktive im Layer-3-Prompt (ADR-0083): Imperative im Diktat werden als Text wiedergegeben, nicht ausgeführt.
- Klammer-Pair-Tracking gegen unpaarierte Schließzeichen (ADR-0084).
- Layer 3 überspringt leeren/whitespace-only Layer-2-Text vor dem Backend-Call.
- Length-Gate-Bypass nur bei Zahlworten, nicht bei Ziffern.
core.numberSequence im .minimalWithLexicon-Default aktiviert.
- Fixmodus-Banner präzisiert: unterscheidet die Layer-2-Wörterbuch- Ersetzung vom Layer-3-Prompt-Einfluss; das Wörterbuch wirkt auch im Fixmodus weiter.
- llama-server-Cleanup auch bei ⌘Q (Repo-Review).
- Concurrency-Races und History-UI-Refresh bereinigt (Repo-Review).
- Drei zurückgestellte strukturelle Performance-Funde sowie Render- und Hotpath-Optimierungen aus dem Repo-Review adressiert.
Intern
- Repo-Review-Nachtrag (ADR-0066 Review):
AudioConstants zentralisiert, toter Code entfernt, Doku-Drift bereinigt.
- STT-Kandidaten-Benchmark (ADR-0086): korpus-agnostisches Phase-0–3-Harness (Runner, Kurz-/Diktat-Scorer); Parakeet TDT v3 bleibt Layer-1-Default. FM-Guided-Generation und STT-
contextualStrings als Re-Bench-Hebel ergänzt.
- Bench-Treue gehärtet: FM-Bench-Prompt und Snapshot-Fixtures waren von Production gedriftet; Bench-CLI-Symlinks nach App-Umzug repariert.
[0.1.6] - 2026-05-22
⚠️ Breaking
- Mindest-macOS auf 26 angehoben (ADR-0074 Amendment, ADR-0077). v0.1.5 lief noch ab macOS 14/15; das Live-Streaming über Apples
SpeechAnalyzer und die vollständig SwiftUI-native Fenster-/Menüleisten-Architektur setzen macOS 26 voraus. LSMinimumSystemVersion und das Package-Deployment- Target stehen jetzt auf 26.0.
Added
- Live-Vorschau beim Diktieren (ADR-0077): Apples
SpeechAnalyzer/SpeechTranscriber (macOS 26) ist als wählbare Final-STT-Engine verfügbar und liefert während des Sprechens partielle Transkripte. Diese erscheinen in einer Topbar-Live-Pille (Waveform
- Text-Vorschau, ab Aufnahmestart groß) und parallel über den neuen Egress-Endpoint
GET /api/v1/stream als Server-Sent-Events. Beide Senken sind getrennt schaltbar (zwei Toggles + Capability-Gating), die Pille zusätzlich per Menüleisten-Quick-Toggle (app-session-lokal). Die Drosselung (8–10 Hz) und das Tail-Window sitzen quellseitig im LiveStreamingSupervisor; ein additiver Live-Chunk-Tap im AudioRecorder speist den Partial-Bus, ohne den Final-Pfad zu stören.
- Forensik-Endpoint
GET /api/v1/history (ADR-0062 Amendment): vollständiger Verlaufs-Export hinter demselben Bearer-Token-Gate wie /transcripts. privacy=full (Roh-/Layer-Daten) ist zusätzlich auf Loopback-Bind beschränkt — bei LAN-Bind liefert der Endpoint 403.
- Layer-2
AcronymCaseNormalizer (ADR-0069): Akronyme aus einer Allow-Liste (GUI, KI, RTT, ADR …) werden korrekt großgeschrieben. Dazu sttEngine im Kurz-Export (ADR-0071).
- Menüleisten-Quick-Settings: STT-/LLM-Picker mit Disabled-Logik direkt im Panel; Lexikon-Quick-Add zeigt die Ziel-Library und erlaubt deren Auswahl. Panel-Health komplett (Modell + Status-Punkt + RAM).
- Liquid-Glass-Material (macOS 26) auf den prominenten Dashboard-Cards und den Wörterbücher-Statistik-Tiles.
- App-Version in der Sidebar-Fußzeile und im Über-Menü.
Changed
- Menüleiste komplett SwiftUI-nativ (ADR-0075):
MenuBarExtra(.window) ersetzt das bisherige NSStatusItem; eine echte WindowGroup-Scene ist jetzt Fenster-Owner. Der App-Start läuft über SwiftUI @main mit zweistufigem (split-timing) Boot. Dock-Aktivierung und Dock-Icon-Reflektion sind in eigene Supervisor extrahiert.
- Reaktivität auf das Observation-Framework migriert (ADR-0078): sämtliche Models, Stores, Controller und UI-Bindings von Combine/
ObservableObject auf @Observable umgestellt (neun Phasen). Der frühere ReactiveLabel-Workaround für verschachtelte Observables entfällt.
- Full-Height-Sidebar + Unified-Toolbar (ADR-0072): separate Icon-Rail entfernt.
- LLM-Glättungs-Picker aus den Quick-Settings entfernt (lebt jetzt nur noch in den Einstellungen).
- Egress:
NWConnection-Teardown deterministisch gemacht.
- Menüleisten-Icon auf 24 pt vergrößert.
Fixed
- Apple-Speech-Datenverlust bei mehreren Sätzen behoben.
- Single-Instance-Guard: keine Doppel-Instanz und kein Doppel-Inject mehr beim Start.
- Sauberes Beenden:
SIGINT/SIGTERM laufen über DispatchSource statt klassischer signal()-Handler — kein Crash mehr beim Shutdown.
- Layer-3-Skip ist im Verlauf sichtbar; die Layer-3-Glättung fließt jetzt in die Volltextsuche ein.
- Dock-Icon-Ausblenden funktioniert zuverlässig.
- Layer-2-Diktat-Direktiven: Spell-Mode-Recovery bei Parakeet-Kollaps + Trigger-Leak-Schutz (ADR-0070), komma-toleranter Spell-Trigger, Unpaired-Quote-Recovery + STT-Anchoring (ADR-0054 F),
als/wie-Determiner-Anker (ADR-0065).
- W-Fragen-Answer-Slip: Passthrough-Anker + Interrogativ-Preservation (ADR-0068 A1).
- Diverse SwiftUI-Boot-Korrekturen (Scene-Delegate nicht überschreiben, redundanten manuellen Sidebar-Toggle entfernt) und drei vorbestehende Compiler-Warnungen bereinigt.
Removed
NSStatusItem-basierte Menüleiste (ersetzt durch MenuBarExtra).
[0.1.5] - 2026-05-17
Added
- Externe Egress-API für Transkripte (ADR-0062, ADR-0066): lokaler HTTP-Server auf
127.0.0.1 mit drei /api/v1-Endpoints — GET /health (öffentlich), GET /transcripts?since=<seq> (Polling-Resync) und GET /events (Server-Sent-Events-Stream finaler Transkripte). Bearer-Token-Auth (32 Byte aus SecRandomCopyBytes, base64url, im Keychain mit kSecAttrAccessibleWhenUnlockedThisDeviceOnly), optionales LAN-Opt-in mit TLS-Cert-Store-Stub, konfigurierbarer Port (Default 8765), automatische Port-Konflikt-Recovery beim Boot (Toggle-Rücksprung + Banner). Schließt Issue #1. Settings-UI „Externe API” mit Live-Status, AppLog-Kategorie egress-api (ohne Token-/Transkript-Inhalt), neues Entitlement com.apple.security.network.server. Lifecycle-Trennung über EgressAPISupervisor.
- Layer-2 Voice-Command-Pass V1.0 → V1.3 (ADR-0065
- 6 Amendments): deutsche Diktat-Direktiven wie „in Klammern X sein/setzen” werden vor Layer-3 erkannt und in Marker-Form auf den Token-Stream gehoben. V1.1 marker-frei + Komma-konsumierend + Suppressor-Bypass, V1.2 Marker immer erhalten + Pattern 4, V1.3 Layer-2 schluckt Marker, Layer-3-Modul
core.bracketDirective ergänzt als adaptiver Schutz gegen Marker-Drop.
- E-Mail-Formatter & Verkettungs-Recovery (ADR-0063): Layer-2 erkennt E-Mail-Diktate, fixt STT-Substitutionen („dott”/„dort” → „.”), Inline-Punkt-Pattern (
<local> at <domain>.<tld>), Vorname-Nachname-Verkettung ohne <at>, plus EmailTLDRepetitionSquash gegen Parakeet-Decoder-Loops auf der letzten TLD. Stages für Build-37-Live-Diktate scharfgestellt.
- Adaptive Status-Icons v4 (ADR-0064): Asset-Tausch (
AppIcon-active, AppIcon-warning, AppIcon-error) statt Laufzeit-Komposition für die Menübar; SF-Symbol-Tinting-Wege waren auf macOS unzuverlässig. Build-Skript synct AppIcon-warning, CLAUDE-Asset-Sync-Regel ergänzt.
- HistoryEntry Schema v9 → v10: Egress-API
sequenceNumber als prozess-übergreifender UInt64-Counter (UserDefaults egressApi.lastSeq), vergeben in HistoryStore.append(_:) — Restart-stabil, deterministische Ordnung auch bei gleichem Millisekunden-Timestamp.
- Pasteboard-Privacy-Marker (ADR-0059): setzt verstecktes Marker-Item beim Inject, Body-Sanitizer entfernt Concealed-Strings vor History-Persistenz.
- Forensik-Copy-Confirm für die JSON-Detailstufen
.medium und .short in der History-Row.
- Lexikon-Rename via Settings-UI statt manueller JSON-Bearbeitung; Kontextmenü statt Pencil-Icon in der Eintragszeile.
- Dateless-Ordinal-Datum-Erkennung im PostProcessor: „zehnte siebte” → „10.07.”, toleriert STT-Pausen-Komma.
Changed
- Layer-3-Modul
core.bracketDirective wird adaptiv eingebunden, sobald Klammer-Direktiven im Stream erkannt werden — verhindert Marker-Drop bei aggressivem Refactoring im Smoothing.
- Passthrough-Few-Shot im Qwen-Default um Refactoring-Beispiele erweitert (
010e112); reduziert Halluzinations-Risiko bei passthroughIfClean-Pfad.
- Antwort-Partikel-Liste im Sanity-Check um Klar/Sicher/Natürlich und Varianten erweitert.
- Layer-2 E-Mail-Stages auf Build-37-Live-Diktate scharfgestellt (Pattern-Reihenfolge + Trigger-Schwellen).
- AppDependencies verliert die
init-basierte Lifecycle-Domäne; Orchestrator, Pipeline, MainViewModel und MainWindowController bauen sich ohne AppDependencies-Konstruktor auf (ADR-0061, Phase B).
Fixed
- Voice-Commands — Multi-Punkt → Ellipsis-Squash + RepetitionSoft-Allowlist, Determiner-Schutz für alle Punctuation-Direktiven, Komma-Asymmetrie zu Punkt geschlossen, Präpositions-Schutz + sein-Disambiguierung, Punkt mit Determiner-Anker auch mitten im Satz schützen, Punkt vor Ziffer als Ordnungsverweis skippen, Pair-Only-Quotes, STT-Drift-Aliase, typografischer Closer.
- Hotkey-Watchdog — Sleep/Wake-Reinstall via Probe-Trigger verifiziert (P1.7, DEBUG-only
MAC_DIKTAT_WATCHDOG_TEST=1); tapEnable(true) reicht nicht, kompletter CFMachPort-Neuaufbau notwendig.
- Egress-API — self-EADDRINUSE durch Single-Listener-Bind beseitigt, async Listener-Failure abgefangen, Port-Konfig in Settings immer editierbar.
- Egress-Settings-UI — Info-Tooltips als Click-Popover statt Hover-
.help (NSHostingView filtert Mouse-Tracking; bestätigt durch 11 fehlgeschlagene Tracking-Versuche am 2026-05-17), .focusable(false) killte NSHelpManager-Tracking, LAN-Switch im Switch-Flucht korrekt platziert.
- DatelessOrdinalDate toleriert STT-Pausen-Komma zwischen Ordinalen.
- HistoryStore — graceful Fail statt
preconditionFailure bei doppeltem Container-Fail; verlorenes Diktat ist besser als Crash.
- HistoryStoreTests auf Schema V10 nachgezogen (ADR-0062-Drift).
- AppLog
try?-Pfad (Tranchen 1–3) durch do/catch mit Fault-Log ersetzt; History-Crypto und Boot-I/O dokumentieren Fehlerursachen.
- History-Search debounced gegen AES-GCM-Thrashing bei Backspace-Tipperei.
Refactor & Architektur
AppSettings-Aggregator-Split (ADR-0057): Sub-Structs für Hotkey, UI, AudioInject, Logging, Layer2, STT, Layer3 (P3.1 T1–T7) — Settings-Datei nicht mehr Monolith.
- HistoryRow Subview-Extraktion (ADR-0058): Tier-1-Sub-Views, Layer-Labels, Layer-AttributedString-Builder, Comparison-Block, Comment+Correction-Block, Forensic Footer, MetaLine, LayerStack (P3.3 T1–T5).
- Layer-3-Settings-Subviews (P3.4): Style-Cards, Download-Banners, Banner-Shell, Feature-Toggles, Backend-Row + Popovers, Remote-API-Felder, Experten-Modus — gemeinsamer
SettingsBannerShell (P3.6 T1), BackendChoiceRow und RemoteAPIFieldsBlock konsolidieren STT-/Layer-3-Picker.
- Modulstruktur (ADR-0056):
Sources/MacDiktat/ in Subordner — Logging/Crypto/Hotkey/AudioStack/ Benchmark (Tranche 1), Models/Transcription/Injection/Lexicon (Tranche 2), UI-Subtree mit Subkategorien (Tranche 3), Bootstrap/Settings/Dictation/Layer3/History (Tranche 4).
- AppDependencies Phasen-Typisierung Phase B (ADR-0061).
- Try-Audit Tranchen 1–3: History-Crypto, Persistence (fetch/purge), Reset/Bootstrap-I/O —
try? durch do/catch + Fault-Log abgelöst.
- KeychainQueryBuilder als Single Source of Truth.
- Smoothing-Magic-Numbers für Sanity-Limits und Import-Toast zentralisiert.
AppLogErrorSanitizer (ADR-0053)
emit(error:)-Overload — Fehler werden geloggt, Diktat-Inhalt bleibt draußen.
Tests
- DictationResultPipeline E2E test-init + 5 Happy/Error-Pfade.
- DictationOrchestrator-Glue-Tests (P1.4).
- Backend-Fallback-Chain-Integration (FM → Qwen → Plain).
- History-Crypto v1 → v2 Key-Rotation, Keychain-Pfad.
- Lexicon Cologne-Min-Code ≥ 3 als direkte Pin-Tests (ADR-0049).
- EgressAPIServer / Supervisor / HealthProbe / TLSCertStore — neue Suite für ADR-0062.
Security
- TOFU strukturell geschlossen (P0.1):
HashSpec.sha256 ist nicht mehr optional. Mismatch beim Download wirft, kein „wird beim ersten Lauf gelernt” mehr — adressiert die alte Lehre aus feedback_security_audit_routine.
- Pasteboard-Concealed-Marker + Body-Sanitizer + Qwen-Hash-Gate (
c7129a3).
- Pinning-Hashes von
String? auf String (non-nil) gehoben.
- ADR-0055 — Gemma-4 Single-Source Risiko-Akzeptanz dokumentiert und am
Layer3/GemmaURLSet referenziert.
Release-Infrastruktur
sync-to-code-repo.sh für Grafik-Sync (Vault → Code-Repo) mit Drift-Check, eingebaut in /gh-hygiene.
- AppIcon-warning im Build-Skript automatisch mitgeführt; CLAUDE.md ergänzt um Asset-Sync-Regel.
[0.1.4] - 2026-05-14
Added
- Adaptiver Layer-3-Systemprompt (ADR-0048):
buildAdaptive(...) generiert aus Layer-2-Signalen (Lexikon-Hits, Anti-Halluzinations-Stufen) einen spezifischen Prompt mit Protected-Terms-Sektion, Anti-Halluzinations-Klausel und Filler-Strip-Strict. Ein Settings-Toggle steuert den Pfad. rawTranscriptForContext gibt Layer 3 zusätzlichen Kontext. Forensik (D6) wird pro Eintrag persistiert.
- Layer-2 deutsche Referenz-Datenbanken Phase 1+2A–D (ADR-0050): Bundesland-Vollnamen-Normalisierung, BNetzA-Vorwahlen-Mapping, OpenGeoDB-PLZ-Lookup und Cities-Gazetteer mit Umlaut-Rückmapping. Vier deterministische Layer-2-Pässe ohne LLM-Aufruf.
- Lexikon-Relevanz-Filter (ADR-0049): Hybrid Levenshtein + Kölner Phonetik mit Mindest-Code-Länge ≥ 3 (verhindert Kurz-Code-Kollisionen wie „die” ↔︎ „Tahoe”) und Bypass für Lexikon-Begriffe ≤ 4 Zeichen.
- Schattenglättung Auto-Off bei Remote-Backend mit Toggle-Layout-Fix für die Settings-Karte.
- History-UI Forensik: JSON-Kopier-Menü mit drei Detailstufen pro Eintrag, Layer-3-Skip vs. Verworfen visuell unterschieden, hellblauer Accent für AI-Glättungs-Blöcke, URLs werden im Verlauf erkennbar und klickbar gerendert.
- Diagnose-Bundle-Export unter „Settings → Debug-Logs”; verpackt redigierte Settings, Logs und Inventur-Bericht für Tester-Bug-Reports.
- AppLog v2 mit Schema v2 und allen Kategorien am File-Sink.
- Voice-Commands: geschweifte, eckige und spitze Klammern plus Comparators (
≤, ≥, ≠, <, >).
- Layer-3-Sanity Tier-Doktrin Phase B Schritt 1 (ADR-0052, Status
proposed/partial): erste Stufe live, restliche Phasen folgen — bewusst als Teil-Implementierung markiert.
Changed
- Length-Gate-Bypass bei effektivem adaptivem Pfad (ADR-0051): Layer 3 wird nicht mehr übersprungen, wenn
Layer2Signals.isEffective aktiv ist (Lexikon-Hits, adaptive Regeln). Adressiert Cluster G aus dem Diktat-Export 2026-05-14.
- Tier-1-Bypass wirkt jetzt über alle Sanity-Lanes (Lossy, Number-Dictation), nicht nur den Default-Pfad.
- Lossy-Sanity bypassed Number-Dictation bei ≥ 3-stelligem Output (verhindert Verwerfen von Zahlen-Diktaten).
- Length-Gate-Bypass bei Zahl-/Ziffern-Diktaten zusätzlich zum adaptiven Pfad.
- TrailingPunctuationSuppressor läuft auch über Layer-3-Output, nicht nur über die Roh-Transkription.
exportSingleEntryJSON akzeptiert injizierbares Datum (Round-Trip-Tests deterministisch).
- D2-v2 Schutzliste ist additiv statt Lexikon-Ersatz.
- Passthrough-Few-Shot bekommt Antwort-Slip-Gegenbeispiele.
core.numberSequence-Modul im Smoothing-Prompt schützt Ziffer-Sequenzen gegen Layer-3-Zerlegung.
Fixed
- VoiceCommandReplacer schützt „Punkt” als Nomen am Satzende und respektiert Adjektiv-Ketten zwischen Determiner und „Punkt”.
- Audio-Engine macht defensiver
reset() vor jedem start(); State-Leak nach Fehlerpfad geschlossen.
- RepetitionSoftFilter reduziert 3+ Duplikate auf 1 Vorkommen (Text statt nur Signal); Trailing-Punctuation wird vor Vergleich gestrippt („Ich, ich, ich” → „Ich”).
number-norm Telefon-Trigger verliert keine Ziffern mehr bei Komma-Sequenzen.
- D3-Anti-Halluzinations-Klausel des adaptiven Prompts feuert jetzt real, nicht nur theoretisch.
- URL-Komprimierung im Layer-2-/Layer-3-Pfad whitelistet die Schemata und vermeidet Lowercase auf Pfadkomponenten.
- AppLog-Tests verwenden die korrekten v2-Schema-Feldnamen (
logger / level / message).
Release-Infrastruktur
- Bench-CLI: Variant-D Adaptive-Pfad in
run-glaettung und _fm_bridge; prompt-adaptive-Subkommando ergänzt.
- Bench-Daten: hand-annotierte Layer-2-Signale für Variant-D-Bench (Qwen3-4B Baseline-Rerun + Adaptive-Lauf 2026-05-14, Ampel grün).
- Bench-CLI Build-Reparatur: Module-Catalog-Symlinks und Swift-5-Mode für die Wiedernutzbarkeit.
[0.1.3] - 2026-05-13
Added
- Shadow-Layer-3 in der Historie (ADR-0033 Amendment): Wenn Layer 3 wegen Längenfilter oder Stil-Skip nicht greift, läuft im Hintergrund trotzdem ein Schatten-Smoothing und wird im Vergleichsblock inklusive Diff-Caption angezeigt. Vergleich bleibt deaktivierbar.
- HistoryEntry Schema v9 mit Sammel-Slots für künftige Forensik-Felder und Build-Reproduktion (Commit-SHA, App-Version, ggf. Modell-Hash) pro Eintrag — Voraussetzung für vergleichbare Bug-Reports.
- Per-Eintrag-Lexikon-Toggle + Bundle-Import-Sheet (ADR-0045): Schema v6 mit
isEnabled pro Eintrag, portables JSON-Format (Single + Bundle), Importer mit Merge-Vorschau, Outcome-Callback und transparentem Disabled-State. Ersetzt den alten Plain-Array-Export.
- Voice-Commands: Satzzeichen-, Klammer- und Zitat-Block-Befehle (
„Punkt", „Komma", „Klammer auf", „Zitat" etc.), inkl. Coalescing mit STT-Auto-Punctuation.
- Verlauf-UI vollständig: Einzel-Löschung, Filter-Bar mit Layer-2-Toggle und Reset-All, Audio-Device-Anzeige pro Eintrag, Rename inline.
- Wörterbuch-Doppel-Aufräum-UI mit Merge-Vorschau (Aliase, Tags, Schutz-Flags via Union — keine destruktive Delete-UI).
- Lexikon-Timestamps (
createdAt / updatedAt) pro Eintrag, lexicon.json Schema v5.
- Inject-Decision-Telemetrie für Layer-3-Sanity-Tuning.
- Debug-Build-Badge am Dashboard-Header (sichtbar nur in Debug-Build).
- Stil-Karten zeigen Schloss-Icon, wenn ein Toggle technisch nicht greift, statt widersprüchlich klickbarem Toggle.
Changed
- NumberNormalizer läuft vor
SentenceCaseAfterBreak, damit „erstens” korrekt großgeschrieben wird, wenn es als Listenanfang nach Punkt steht.
- Wörterbuch-Aktionen als In-Body-Action-Row statt nested NavigationStack-Toolbar (macOS-Bug mit innerer Toolbar im SplitView-Detail).
- Wörterbuch-Übersichts-Buttons sind stil-paritätisch zum Detail-Editor.
- RAM-Priorisierung-Toggle wird bei aktivem Apple-Intelligence-Backend ausgeblendet (keine Wirkung, war verwirrend).
- Distribution-Builds sind jetzt verbindlich Universal (arm64 + x86_64). v0.1.1 war versehentlich arm64-only und ließ sich auf Intel-Empfänger-Macs nicht öffnen. Der
REQUIRE_UNIVERSAL-Check ist nur in der Release-Pipeline aktiv, lokale Debug-Builds bleiben single-arch.
Fixed
- Skip-Banner verspricht keinen Layer-3-Output mehr, wenn der Vergleichs- block leer wäre.
- Decomposer kennt den
.minimalWithLexicon-Pfad und reproduziert die Forensik-Karten korrekt für ältere Einträge.
- AX-Restart-Pfad ist ehrlich: die App sagt jetzt klar, dass nach Re-Sign der CDHash neu ist und macOS die Accessibility-Permission verwirft — inklusive
tccutil reset-Hinweis.
- Voice-Commands schlucken doppelte Satzzeichen, wenn STT bereits automatisch interpunktiert hat.
Release-Infrastruktur
scripts/package-dmg.sh erzeugt signiertes + notarisiertes Universal-DMG mit gestapelter App, Drag-to-Applications-Layout und SHA-256-Sidecar.
scripts/publish-release.sh publiziert Tag + DMG-Assets als GitHub-Release.
LICENSE ergänzt (proprietär, mit Open-Source-Acknowledgments).
[0.1.1] - 2026-05-09
Added
- Layer-3 First-Launch-Onboarding (ADR-0040): frische Installationen sehen ein Auswahl-Sheet (Apple Intelligence / Qwen 3-4B mit Direkt-Download / Aus). Existing User werden via Migration übersprungen.
- Prompt-Module-Aktivierungs-Store + Persistierung mit User-Extension- Textfeldern pro Stil-Karte (Phase 1–3 ADR-0040).
- SmoothingPromptStyle-Enum + Caps-Erweiterung + Experten-Override (ADR-0039): minimal vs. structured wird pro Backend differenziert. Apple-FM-Default bleibt minimal, Qwen-Default rollt zurück auf structured (Praxis schlägt Lab-Bench).
- Lexikon in Layer 2 (ADR-0041 Begleit-Fix): deterministischer
LexiconReplacer aus term + soundsLike, damit geschützte Begriffe auch im Layer-3-Fallback wirken.
- Lexikon-Banner für Asymmetrie-Sichtbarkeit (Pre-Check-Action statt silent fallback).
- Multi-Wörterbuch-Datenmodell + UI (Übersicht, Detail-Editor, Cap-Greying) mit
lexicon.json v2→v3-Migration und Schema v4 (ehemalige Built-ins als editierbare User-Libs).
- HistoryEntry Schema v7→v8 (ADR-0044):
lexiconHitsCipher + LexiconSnapshot-JSON-Store pro Diktat (Wörterbuch-Stand + Trefferbilanz forensisch ablegbar).
- Layer-3-Sanity statt Verwerf-Guardrail (ADR-0041): Persistieren immer, Inject-Sanity nur als Halluzinations-Notbremse, UI macht den Skip transparent. Edit-Distance-Guardrails verwerfen keine Outputs mehr.
- Self-Inject via NSTextInputClient statt Pasteboard-Cmd+V für In-App-Felder. Pasteboard-Inject mit Serialisierung + Sentinels + 150 ms Fixed-Wait (kein Pasteboard-Scrub mehr — PB ist User-Eigentum).
- Compare-Sheet im Verlauf: dual-Apple-FM-Vergleich, prompt-trust chain, einheitliches Forensik-Layout, klickbare Info-Icons als Popover.
- Layer-2-Stage-Counts auf Technik-Seite.
- Post-Processing-Hardening (H4–H15): Token-Overlap-Sanity, Spell-Mode, Euro/PIN-Sequenz, Datum-Casus, Number-Anchor-Concat, CyrillicCleanup als Roh-Filter, Length-Gate + Token-Loss-Sanity.
Changed
- Sampling-Defaults Qwen3-4B (ADR-0042) und Context auf 4096 mit Pre-Decode-Token-Guard.
- Pasteboard-Restore-Limit von 50 KB auf 1 MB angehoben (Memory-Tradeoff für längere Diktate akzeptiert).
- SplitView-Layout stabilisiert (pin host bounds, drop scrollview frame workarounds).
Fixed
- Pasteboard-Secret-Leak geschlossen (Layer 1), Self-Inject-Bypass via AX (Layer 2 — später durch NSTextInputClient ersetzt, siehe oben).
- SIGABRT-Shutdown-Backtrace für FIXME-RELEASE-Diagnose vor
_exit(0).
- Empty-Forensik-Pfade (stt-empty / postproc-empty) werden persistiert statt verworfen.
[0.1.0] - 2026-05-02
Added
- Modell-Download-Onboarding (ADR-0013): First-Run-Sheet für Whisper Large v3 und Parakeet TDT 0.6B v3, Resume-fähiger HTTP-Download mit SHA-256-Verifikation, atomare Installation über
.tmp + Replace, .verified-Marker pro Engine-Ordner. App startet bei fehlendem Modell nicht mehr mit _exit(1), sondern mit einer MissingModelEngine und öffnet das Download-Sheet bei User-Intent.
- Modelle-Sektion in den Einstellungen: geladen/fehlt-Badges pro Engine, Disk-Größe, „Modell entfernen” mit Confirm-Dialog und Live-Rebuild der aktiven Engine.
- Offline-Dialog mit „Andere Engine wählen”: scrollt per
SettingsScrollTarget zur STT-Backend-Sektion (statt stummer Fehlerseite).
- Parakeet TDT 0.6B v3 als lokale STT-Zweitoption (ADR-0012), Engine-Umschaltung zur Laufzeit, asynchroner Swap mit Stale-Guard, damit Settings-UI während des ~1 s WhisperCpp-Reloads responsiv bleibt.
- Remote-STT über OpenAI-kompatible REST-APIs (ADR-0011), Keychain-gebundene API-Keys, Fallback auf lokale Engine bei Remote-Fehlern.
- Layer 3 — LLM-Glättung mit Apple FoundationModels als Auto-Default (ADR-0018) auf macOS 26 mit Apple Intelligence, Qwen3-4B-Instruct-2507 als Fallback-Opt-in.
- Hotkey-Konfigurator mit Live-Visualisierung und kollisionssicherer Validierung (ADR-0007).
- Historie mit 30-Tage-Retention und Copy-to-Clipboard pro Eintrag (ADR-0006).
- Rating-UI in der Historie (ADR-0033): 3-Stufen-Thumbs (-1/nil/+1), CorrectionSheet-Erweiterung, Favorit auf Eintrag-Ebene (
isFavorite), Filter „nur Favoriten”.
- HistoryEntry v2 mit AES-GCM-Verschlüsselung sensibler Felder (ADR-0020), Schlüssel Keychain-gebunden via
HistoryCryptoProvider.
- Hardened Runtime mit Audio-Input-Entitlement und Developer-ID-Notarisierung. Notary-Gate dry-run bestanden 2026-04-23.
Fixed
- FluidAudio-Cache-Pfad-Drift: Parakeet-Ordnername auf den von FluidAudio erwarteten kanonischen Wert
parakeet-tdt-0.6b-v3 ausgerichtet. FluidAudios AsrModels.download(to:) schreibt nach parentDir(to:) + folderName, nicht nach dem übergebenen to:-Pfad — ein abweichender Ordnername erzeugte einen Sibling-Orphan, verfälschte Disk-Größe und ließ „Modell entfernen” unvollständig räumen. Idempotente Legacy-Layout-Migration (Whisper-Root-.bin und Parakeet-Sibling) kickt beim Boot direkt nach Paths.ensureDirectories(). Siehe ADR-0013 Nachtrag 2026-04-19.
- Doppelter „Abbrechen”-Button im Parakeet-Download-Sheet entfernt: bei Engines ohne Pause-Support wird der Pausieren-Button gar nicht mehr gerendert, statt sein Label auf „Abbrechen” umzumappen.
- Engine-Status-Badges kontextuell: aktive Engine + fehlendes Modell → rot (plus zarter
red.opacity(0.06)-Card-Tint), inaktive Engine + fehlend → grau, geladen → grün, Disk-Größe → blau. Gilt einheitlich in Picker, Modelle-Sektion und Technik-Panel.