Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
266 lines
20 KiB
Markdown
266 lines
20 KiB
Markdown
# 08 — Changelog
|
||
|
||
Chronik der Entwicklungsschritte. **Regel: jede zukünftige Änderung bekommt hier einen Eintrag** (Datum,
|
||
Was, Warum, betroffene Dateien/Backups).
|
||
|
||
## 2026-07-17 — GUI: Blasen-Oeffnung zeigt exakt auf den Sprecher
|
||
|
||
Bei mehreren Sprechern je Tischkante (5-/6-Sitz-Layouts) zeigte der Schwanz nur auf die Kantenmitte.
|
||
Jetzt wird die Sitz-x-Position in Blasen-Koordinaten umgerechnet (CSS-Variable --ax, BUBBLE_W in
|
||
main.js synchron zur CSS-Breite) — die Oeffnung wandert entlang der Ober-/Unterkante exakt zum
|
||
Sprechenden; bottomleft/bottomright-Sonderklassen entfallen. Bundle `index-FKbNFs-A.js`.
|
||
|
||
## 2026-07-17 — GUI: Tisch-Blase fix, Oeffnung wandert zum Sprecher
|
||
|
||
Feinschliff nach User-Feedback: Die Sprechblase liegt wieder FEST auf dem Tisch (54 % Breite),
|
||
nur ihr Schwanz/die Oeffnung springt per arrow-Klasse zum jeweils Sprechenden; Rand-/Namensfarbe
|
||
wechseln weich mit (border-color-Transition). Wort-Highlight, internes Mitscrollen und Klick-Seek
|
||
bleiben. Bundle `index-CpZJOt3u.js`.
|
||
|
||
## 2026-07-17 — GUI: Sprechblase am Sprecher mit Wort-Highlight + Mitscrollen
|
||
|
||
Tisch-Ansicht verfeinert: Die Blase haengt jetzt klassisch am MUND des Sprechers (dynamisch zwischen
|
||
Sitz und Tischmitte positioniert, Schwanz zeigt zum Kopf) statt zentral auf dem Tisch. Inhalt = der
|
||
komplette Redebeitrag als einzelne Wort-Spans: aktives Wort wird synchron zum Audio gehighlightet
|
||
(wie im Transkript), die Blase scrollt intern mit (innere .tb-scroll-Huelle, damit der Pfeil nicht
|
||
mitscrollt), Klick auf ein Wort springt im Audio dorthin. Bundle `index-BK0gpRp9.js`.
|
||
|
||
## 2026-07-17 — GUI: Konferenztisch-Ansicht (Umschalter neben "Analyse neu")
|
||
|
||
Neuer Umschalt-Button (Icon: drei Personen am Tisch <-> Textblatt) in der Status-Zeile: ersetzt das
|
||
Transkript rechts durch eine animierte Szene — Sprecher als Figuren in ihren Spurfarben um einen
|
||
abgerundeten Tisch, Sprechblase AUF dem Tisch (Rand/Name in Sprecherfarbe, Pfeil zeigt zum Sprecher,
|
||
Text = aktueller Redebeitrag), alle anderen Personen drehen die Pupillen zum Sprechenden, dessen Mund
|
||
animiert beim Reden (reduced-motion respektiert). Sitzordnungen fuer 1-6 Teilnehmer vordefiniert.
|
||
Wahl bleibt in localStorage['aime-side-view']. Bundle `index-DXTNo40e.js`.
|
||
|
||
## 2026-07-17 — GUI: Aufnahmen-Tab nutzt die volle Fensterbreite
|
||
|
||
`#app.wide` war auf 1180 px gedeckelt — auf breiten Monitoren blieb rechts/links viel Leerraum und
|
||
die Zusammenfassung wurde unnötig schmal/lang. Deckel entfernt (max-width: none, Padding 28 px);
|
||
die Liste bleibt 340 px fix, das Detail bekommt den Rest. Bundle `index-RpsXFTh8.js`.
|
||
|
||
## 2026-07-17 — GUI: Live-Text-Box entfernt
|
||
|
||
Die Box rechts neben den Sprecher-Spuren (aktueller Redebeitrag) flog auf User-Wunsch raus —
|
||
redundant zum mitscrollenden Transkript daneben. Spuren nutzen jetzt die volle Breite.
|
||
Bundle `index-BiCA5LX5.js`.
|
||
|
||
## 2026-07-17 — GUI: Sprecher-Verlauf als Vollbreiten-Streifen unter dem Player
|
||
|
||
Der Sprecher-Verlauf (Spuren + Live-Text) sitzt jetzt fix unter der Audio-Laufleiste und zieht sich
|
||
ueber BEIDE Spalten (oberhalb von Zusammenfassung und Transkript); aus den Drag&Drop-Modulen entfernt.
|
||
Lanes ~2/3, Live-Box ~1/3 Breite. Bundle `index-COpkdtd3.js`.
|
||
|
||
## 2026-07-17 — GUI: Transkript als eigene Scroll-Spalte
|
||
|
||
Transkript (+ Dialog) aus den Drag&Drop-Modulen herausgelöst: eigene, sticky Spalte rechts neben
|
||
Zusammenfassung/Verlauf/ToDos/Sprecher, Höhe auf Viewport begrenzt, scrollt INTERN durch und folgt
|
||
dem aktiven Wort im Panel (statt die Seite zu ziehen). Unter 1100 px stapeln die Spalten
|
||
(Transkript max. 60 vh). Bundle `index-DQmY8pnQ.js`.
|
||
|
||
## 2026-07-17 — GUI: Sprecher-Verlauf-Visualisierung + Drag&Drop-Module
|
||
|
||
Detail-Ansicht ist jetzt modular: fester Kopf (Titel, Player, Status), darunter Blöcke
|
||
**Zusammenfassung / Sprecher-Verlauf / ToDos / Sprecher / Transkript** — jeder Block hat einen
|
||
Grip-Header (⠿) und lässt sich per Drag & Drop umsortieren; die Reihenfolge liegt in
|
||
`localStorage['aime-detail-order']` und gilt für alle Aufnahmen.
|
||
|
||
**Sprecher-Verlauf** (neu): pro Sprecher eine farbige Spur (sp0–sp3) übereinander mit
|
||
Redeabschnitts-Blöcken (Wörter mit ≤ 1,2 s Lücke zusammengefasst), Kupfer-Playhead wandert beim
|
||
Abspielen mit, die Spur des gerade Sprechenden leuchtet (Label fett, Punkt pulsiert; respektiert
|
||
`prefers-reduced-motion`), Klick in die Spuren springt an die Stelle. Rechts daneben die **Live-Box**:
|
||
zeigt Sprecher + Text des aktuellen Redebeitrags. Per Playwright-Screenshots verifiziert
|
||
(beide Themes, Playback mit aktiver Spur). Bundle `index-WaE171bv.js`.
|
||
|
||
## 2026-07-17 — GUI: „Weggezogen"-Bug gefixt + Redesign mit Dark/Light-Switch (`.bak-theme`)
|
||
|
||
- **Bug:** lief beim ausgewählten Eintrag eine Analyse, feuerte ein 5-s-Timer `openRecording(alteId)` als
|
||
**stale closure** — auch nachdem der Nutzer längst eine andere Aufnahme hörte → riss ihn zurück und
|
||
stoppte den Player. Fix: Poll bricht bei Auswahl-/Tab-Wechsel ab, prüft während der Analyse NUR den
|
||
Status (kein DOM-Rebuild) und baut das Detail genau EINMAL neu, wenn die Ergebnisse da sind — inkl.
|
||
Wiederherstellung von Player-Position und Play-Zustand.
|
||
- **Redesign:** Themes über CSS-Variablen (`data-theme` auf `<html>`, vor First-Paint aus localStorage/
|
||
OS-Einstellung, Toggle ☀️/🌙 im Header). Dunkel = neutrales Anthrazit, Hell = warmes Papier; Akzent =
|
||
Kupfer (#e8804c/#c05f2d — Rot bleibt der Aufnahme vorbehalten), Wortmarke mit Wellenform-Glyph,
|
||
Pill-Tabs, weichere Karten, sichtbarer Tastatur-Fokus, `prefers-reduced-motion` respektiert.
|
||
Sprecherfarben (sp0–sp3) als Variablen mit hell/dunkel abgestimmten Werten.
|
||
- Bundle `index-C2xK4eql.js` / `index-ClT74fBX.css`. Dateien: `web/index.html`, `web/src/main.js`,
|
||
`web/src/style.css` (Backups `.bak-theme`).
|
||
|
||
## 2026-07-17 — Hall auf der Gegenseite + verschmolzene Sprecher: Mikro→Mix jetzt GEGATET (`.bak-gatedmix`)
|
||
|
||
User: Gegenseite klingt „wie in einem schallenden Raum", Diarization macht aus zwei entfernten Personen
|
||
eine. **Diagnose per Cepstral-Analyse** auf #71: Gegenseiten-Segment hat einen felsenstabilen Peak bei
|
||
**79–80 ms** (22/26 Frames) = deterministische verzögerte Kopie; User-Segment sauber. Ursache: der direkte
|
||
`cr_mic2mix`-Loopback (immer offen) legte die Gegenseite doppelt in den Mix — digital (`cr_pc2mix`) UND als
|
||
Kopfhörermuschel-Bleed durchs Mikro (~80 ms Latenz). Der Hall verschmiert zusätzlich die TitaNet-Embeddings
|
||
→ zwei Remote-Stimmen (gleicher Kanal + gleicher „Raum") rücken über die 0,5-Kosinus-Schwelle zusammen.
|
||
|
||
- **Fix** (`aime-usb-audio-setup.sh`): direkter `cr_mic2mix`-Loopback ENTFERNT; stattdessen
|
||
`pw-link micgate.out → callmix` — dieselbe Gate-Auskopplung wie beim Teams-Selbstecho-/iPhone-Uplink-Fix.
|
||
In Sprechpausen des Nutzers ist das Mikro komplett aus der Aufnahme. Fallback ohne Gate = alter Loopback.
|
||
- Verifiziert strukturell (`pw-link -l`: callmix ← cr_pc2mix + micgate.out, kein HSMIC-Direktpfad) und
|
||
funktional (4 s callrec_mix bei Stille = RMS 0/Peak 0). **Echter Call steht noch aus.**
|
||
- **Nebenbei entdeckt:** OOM-Ereignis 17:47 (die fünf 60-s-READY-Timeout-Retries beim ersten Qwen3-Start
|
||
luden je 5,3 GB, NPU-Speicher der gekillten Loads wurde nicht schnell genug frei) riss mariadb, callrec
|
||
UND pipewire weg — Audio-Topologie war seitdem TOT. Mit dem 180-s-Timeout (Changelog unten) behoben;
|
||
Topologie neu aufgebaut. Lehre: nach OOM immer `pw-link -l` prüfen.
|
||
|
||
## 2026-07-16 — Glossar: Einträge bearbeitbar (`.bak-gedit`)
|
||
|
||
User-Wunsch: gespeicherte Glossar-Begriffe nachträglich ändern. Neu: `PUT /api/glossary/:id`
|
||
(`db.updateGlossary`), GUI-Stift-Button je Eintrag lädt Begriff+Soundalikes ins Formular
|
||
(Titel „… bearbeiten", Speichern/Abbrechen), Update statt Neuanlage. Bundle `index-NRK6cGUI.js`.
|
||
API-verifiziert (POST→PUT→DELETE). Dateien: `server.js`, `db.js`, `web/src/main.js`.
|
||
|
||
## 2026-07-16 — rkllm vor Diar/Identify freigeben (TitaNet-OOM) + #71 validiert
|
||
|
||
- **Bug:** residenter rkllm (5,9 GB) ließ den TitaNet-spk-embed-Helper OOM-sterben („spk beendet" pro
|
||
Cluster) → Konsolidierung bekam NULL Centroids → #71 bekam still **48 Roh-Sprecher**. Fix (`server.js`):
|
||
`llm.stopServer()` am Anfang von `rediarize()` UND `analyzeRecording()` (Reload ~96 s, egal bei 15-min-Analysen).
|
||
- **#71 E2E danach:** Diar 48 → **2 Sprecher** (5 schwache gefoldet), Qwen3-Whole-Pass auf 31,3k Zeichen →
|
||
„Steuergestaltung für wachsendes Unternehmen" mit konkreten Zahlen (30 MA, 3 Mio Umsatz, 15-20 %-Ziel,
|
||
Kick-off Hamburg, Termin 23.) — alter Titel war generisch, alte Sprecherzahl 28.
|
||
- **OFFEN:** `identify … spk beendet` schlägt auch MIT freiem RAM fehl → Voice-Auto-Naming (Voiceprints)
|
||
aktuell tot; Teilnehmer erscheinen als „Sprecher N". Separater Bug, noch zu untersuchen (spk.js/Helper).
|
||
|
||
## 2026-07-16 — ✅ LLM → **Qwen3-4B-Instruct-2507** (Nacht; Gemma-Rollback vorhanden)
|
||
|
||
Auf User-Wunsch Qwen3-4B selbst konvertiert und im A/B gegen Gemma getestet — **3/3 Prompts klar besser**,
|
||
produktiv geschaltet und E2E validiert.
|
||
|
||
- **Konvertierung:** wiederverwendetes Kit (`rkllm-convert:1.3.0`-Docker neu gebaut), HF `Qwen/Qwen3-4B-Instruct-2507`
|
||
(7,6 GB bf16) → `w8a8_g128`/grq, max_context 16384, auf RTX 3090 in ~35 min → 5,3 GB `.rkllm`, pscp aufs Board.
|
||
- **A/B (gleiche Prompts wie Gemma-Tests):** Chunk 1 (Com4Tec-Story) in 140 s mit ALLEN Nuancen (50 %-Kappa,
|
||
kein Body Leasing, Perinko/Icon); Auto-Chunk 91 s inkl. Detail-Korrektur „Michael Wagner, nicht Fabienne";
|
||
**Whole-Pass 21,8k Zeichen in 691 s fehlerfrei gewichtet** — exakt der Fall, in dem Gemma englisch schwafelte
|
||
bzw. nur das Ende zusammenfasste. Qwen3 = ChatML-Template statt Gemma-Turns (`rkllm_server.cpp`).
|
||
- **Produktiv-Swap:** Drop-in `RKLLM_MODEL=qwen3-4b-w8a8g128-16k.rkllm`, prod `rkllm_server` mit ChatML neu
|
||
gebaut (Rollback: `.bak-gemmatmpl` + Drop-in zurückstellen), `WHOLE_MAX_CHARS` 20 000 → **32 000** (bis ~35-min-
|
||
Aufnahmen Single-Pass; Sektions-Konglomerat bleibt für längere). **GOTCHA:** Qwen3 lädt ~96 s → llm.js
|
||
READY-Timeout 60 s → 180 s (sonst Endlos-Retry-Schleife, real passiert).
|
||
- **E2E validiert:** #70 Whole-Pass 15,4 min → „Neue Kontakte und Stellenangebote", Auto raus, Comfort Tech/
|
||
Adem Marlock/Nico-Profil-Todo konkret; #68 Kurzclip (analyzeSingle+ChatML) 22,2 min inkl. Queue → sauber.
|
||
- Damit ist die 4B-Synthese-Decke aus dem Sektions-Konglomerat-Eintrag (unten) für ≤ 32k Zeichen GESCHLOSSEN;
|
||
das Konglomerat bleibt als >32k-Pfad und Fallback.
|
||
|
||
## 2026-07-16 — A/B-Test Qwen2.5-3B vs Gemma-3-4B im neuen Chunk-Pfad: Gemma bleibt
|
||
|
||
Auf User-Wunsch das noch vorhandene `qwen2.5-3b.rkllm` gegen die neuen 4,2k-Chunk-Prompts getestet
|
||
(Test-Binary mit ctx 4096 in /tmp, direkt übers Stdin-Protokoll — kein App-Umbau). Ergebnis: **3 von 3
|
||
Outputs unbrauchbar** (Feldbeschreibungs-Echo ohne Inhalt; Abbruch nach ~100 Zeichen mitten im Satz;
|
||
Struktur-Müll mit der Feldbeschreibung als JSON-Key) — Gemma lieferte im selben Job 8/8 verwertbare
|
||
Sektionen. Dazu prinzipiell: Qwen2.5 hat fix 4096 Kontext → der validierte Whole-Pass (≤ 20k Zeichen)
|
||
wäre unmöglich. Testartefakte entfernt. Offene Alternative (ungetestet, ~½ Tag): Qwen3-4B neu konvertieren.
|
||
|
||
## 2026-07-16 — Sektions-Konglomerat statt LLM-Reduce (Abend, `.bak-sectionsum`)
|
||
|
||
Auftrag: Lang-Transkript-Summary (> 20k Zeichen) inhaltlich retten. Prompt-Lab auf #70 mit temporärem
|
||
`/api/debug/ask`-Endpoint (nach Abschluss wieder entfernt), ~15 Reduce-/Chunk-Varianten in je ~2 min
|
||
statt 9-min-Vollanalysen.
|
||
|
||
- **Befund 1: Chunk-Größe ist der Fidelity-Hebel.** 8k-Chunks → generisches namenloses Blabla; 4k-Chunks →
|
||
geerdete Summaries mit echten Eigennamen (Com4Tec, René, Tobi+Niklas, 20 Bewerbungen). `CHUNK_CHARS` 8000 → **4200**.
|
||
- **Befund 2: Cross-Section-Synthese unmöglich auf Gemma-3-4B.** Jede LLM-Reduce-Variante (Gewichtungsregeln,
|
||
Abschnitts-Labels, Themen-Tabellen) → Regeln ignoriert, Namen durch Rollen ersetzt, Dubletten, Loops.
|
||
**LLM-Reduce abgeschafft.**
|
||
- **Neue `analyzeLong`-Pipeline** (`llm.js`): 4,2k-Chunks sequenziell mit **Rolling Context** (1-Satz-
|
||
Kurzfassungen der Vorgänger → erkennt geänderte Entscheidungen: „jetzt X, vorher Y") + **eigennamen-
|
||
Extraktionsfeld**; Echo-Guard (Feldbeschreibungs-Echo ist INHALTS-abhängig reproduzierbar → bis 3 Versuche
|
||
mit variiertem Prompt: ohne Kontext, ohne Hint) + Feld-Salvage per Regex + Prosa-Rettung (≥ 60 Zeichen);
|
||
**Titel-Mikro-Call** ohne letzten Abschnitt (Smalltalk-Filter); **Konglomerat baut Code**: „Gesprächsverlauf
|
||
in n Teilen — genannte Namen: …" + „Teil i/n: …" chronologisch. Kap. 05 (Mermaid + Marotten aktualisiert).
|
||
- **E2E #70 (3 Läufe):** Titel ohne Auto-Smalltalk ✅, alle Abschnitte mit echten Namen ✅, Auto nur noch in
|
||
Teil 7 ✅, 12-14 min für 26-min-Aufnahme. Restgrenze: Abschnitts-Summaries variieren pro Lauf in Schärfe
|
||
(Sampling), keine thematische Verdichtung ÜBER Abschnitte (4B-Decke). ≤ 20k Zeichen weiter Whole-Pass.
|
||
|
||
## 2026-07-16 — #70-Debug: Phantom-Sprecher, Summary-Fehlgewichtung, Thermal-Leck (Nachmittag)
|
||
|
||
Auslöser: Aufnahme #70 (26 min, 4 Personen) — 7 Sprecher erkannt, Titel/Summary aus Randthemen
|
||
(Auto-Smalltalk der letzten 3 min statt Recruiting-Hauptteil). 9 Analyse-Iterationen auf #70.
|
||
|
||
- **Diarization Stufe 3 „Weak-Fold"** (`diar.js`, `.bak-weakfold`): finale Sprecher < `DIAR_MIN_TOTAL_SEC`
|
||
(20 s, Segment-Zeiten!) werden in den akustisch nächsten starken Sprecher gefaltet — ein einzelner
|
||
≥ 3-s-Streu-Cluster konnte vorher einen Phantom-Anchor eröffnen (#70: 3 Phantome mit 2,5–4,8 s).
|
||
10 s reichte NICHT (9,2-s-Phantom kam durch). **Verifiziert: #70 konstant 50 Roh-Cluster → exakt 4.** Kap. 04.
|
||
- **Whole-Pass-Grenze = Modellgrenze bewiesen** (Runden 2–5): rkllm-Runtime-Kontext 8192 → **12288**
|
||
(`rkllm_server.cpp`, `.bak-ctx12k`, Rebuild) und `WHOLE_MAX_CHARS` testweise 32k → Gemma-3-4B kippt
|
||
> ~6k Input-Token reproduzierbar: englisches Geplauder statt Analyse, Recency-Bias (fasst nur das
|
||
Gesprächsende zusammen), JSON-Zerfall (typografische Quotes, Wiederholungsschleifen). `WHOLE_MAX_CHARS`
|
||
zurück auf **20 000** (dort validiert gut); ctx 12288 bleibt (Headroom). Kap. 05 neuer Abschnitt.
|
||
- **Robustheit `llm.js`** (`.bak-ctx12k`): End-Instruktion nach dem Transkript (ohne Platzhalter-Skelett —
|
||
Gemma kopiert `...` wörtlich!); JSON-Repair-Call (repariert kaputten Output OHNE das große Transkript);
|
||
Sanity-Check (Zusammenfassung ≥ 20 Zeichen) → sonst Chunk-Fallback statt Hard-Error; `extractJson()`
|
||
repariert typografische Anführungszeichen + trailing commas; **1 Retry pro Chunk** (Parse = Sampling-
|
||
Münzwurf: 3/3 ok vs 1/3 im nächsten Lauf; Retry live bestätigt); Reduce-Input mit „Abschnitt i von n"-
|
||
Labels + Gewichtungsregeln (Hauptthema = mehrere Abschnitte; Nur-letzter-Abschnitt = Smalltalk).
|
||
- **Regression bestätigt: Chunk-Prompt MUSS minimal bleiben** — eine zusätzliche Anweisungszeile
|
||
(Namen/Firmen/Zusagen) kippte 2/3 Chunks in Prosa (Runde 6). Zurückgebaut.
|
||
- **Thermal-Leck geschlossen** (`server.js`, `.bak-anacap`): `analyzeRecording()` lief als einziger
|
||
schwerer Pfad OHNE A76-Takt-Cap → 95–97 °C bei langer Gemma-Generierung (lüfterlos!). Jetzt Cap wie
|
||
`transcribeWav`/`rediarize`. Kap. 03/05.
|
||
- **Ehrliches Ergebnis #70:** Sprecher exakt 4 ✅, Analyse crashfrei in ~9 min ✅, Summary führt jetzt mit
|
||
Recruiting, ABER Auto-Smalltalk bleibt in Titel/Kernpunkten und konkrete Namen (Com4Tec, Kandidaten)
|
||
fehlen — **Qualitätsdecke des 4B-Modells im Chunk-Pfad (> 20k Zeichen)**. Aufnahmen ≤ ~23 min laufen
|
||
über den validierten Whole-Pass.
|
||
|
||
## 2026-07-16
|
||
- **Codebase ins Repo aufgenommen:** `app/` = Spiegel von `/opt/callrec` (Backend, Frontend-Quellen, Inferenz-Python, Skripte, `rkllm_server.cpp`), `system/` = systemd-Units + WirePlumber/PipeWire-Drop-ins + sudoers. Modelle/Binaries/Aufnahmen bewusst außen vor (`.gitignore`).
|
||
- **Projekt umbenannt in „Aime“** (vormals CallRec, wie der BT-Name des Boards): Gitea-Repo → `sascha/Aime`,
|
||
Web-GUI-Titel/Header → „Aime“ (Bundle `index-CuWeUh1j.js`, Backups `index.html.bak-aime`/`main.js.bak-aime`),
|
||
Doku rebranded. Technische Bezeichner auf dem Board bleiben `callrec*` (Stabilität).
|
||
- **Doku-Repo angelegt** (dieses Repo). Ab jetzt verbindliche Ablage inkl. Diagrammen.
|
||
|
||
## 2026-07-15/16 — Strukturierte Analyse + Teilnehmer-Fix (`.bak-structsum`)
|
||
- Teilnehmer kommen aus der **Diarization** statt vom LLM (das listete alle *erwähnten* Namen → 11 statt 3 bei #69).
|
||
- Summary strukturiert: Überblick + „Kernpunkte“ + „Entscheidungen“ als Bullets (`composeSummary`, CSS `pre-line`).
|
||
- Chunk-Salvage-JSON-Leak gefixt; Reduce-Input gekappt + Retry; `cleanList` filtert `null`/`[object Object]`/Objekt-Todos.
|
||
- Referenz #69 (71,6 min): Analyse ~20 min, Ergebnis sauber. Bundle `index-B2dSaBty.js`.
|
||
|
||
## 2026-07-15 — LLM-Wechsel auf Gemma-3-4B + Marker-Fix
|
||
- Qwen2.5-3B → **Gemma-3-4B-it** (`gemma3-4b-w8a8g128-16k.rkllm`, grouped w8a8; plain w8a8 kaputt, w4a16 nicht unterstützt).
|
||
- rkllm-Runtime 1.2.1 → **1.3.0**. `analyzeWhole` (≤ 20k Zeichen) ersetzt Map-Reduce im Mittelbereich.
|
||
- Qualität ≈ Gemini, ~3× langsamer. Wort-Highlight-Marker lief ~1 Wort voraus → SYNC_MS=250 (`index-CLero27-.js`).
|
||
|
||
## 2026-07-14 — Kurzclip-Beschleunigung + Analyse-Timer
|
||
- Clips ≤ 30 s über warmen CPU-Whisper-Daemon ohne rkllm-Swap: 10-s-Clip 120 s → **53 s** (`.bak-shortdaemon`).
|
||
- GUI zeigt Analysezeit live (`analysis_ms`/`analysis_started_at`, `.bak-anatimer`).
|
||
|
||
## 2026-07-13 — Diarization stabil + NPU-Meilenstein 2 + iPhone-Repair
|
||
- **Greedy-Anchor-Merge** ersetzt Union-Find: derselbe Call ergab vorher 2/3/7 Sprecher, jetzt konstant 27→3 (`.bak-anchor`).
|
||
- **Meilenstein 2:** Whisper-turbo-Encoder auf NPU produktiv — RTF 1,51 → 0,61, Temp 90 °C → 59 °C; batched (batch=8) → RTF 0,389.
|
||
- iPhone neu gekoppelt, `Trusted=yes` gesetzt (fehlte → keine HFP-Nodes → #58 ohne Gegenseite).
|
||
|
||
## 2026-07-09 — Meilenstein-1-Snapshot, Auto-Diarization, Glossar, Whisper-Kalibrierung
|
||
- Snapshot `/opt/callrec/milestones/m1-20260709/` (Rollback-Punkt).
|
||
- Auto-Diarization: 2-stufige Konsolidierung (17→2 verifiziert), `reanalyze` re-diarisiert immer (0=auto / >0=gepinnt).
|
||
- **Glossar Phase 1:** deterministische Ganzwort-Ersetzung + LLM-Hinweis, GUI-Tab, „Aime“ geseedet.
|
||
- Whisper-Kalibrierung: medium beam1 optimal (11,3 % WER vs large-v3); `--initial-prompt` mit Termliste = Echo-Loop (tabu).
|
||
- 46-min-E2E über Nacht sauber (Long-Rec-Fixes produktionsvalidiert).
|
||
|
||
## 2026-07-08 — Echo-Fix, Thermal-Crashes, Whisper medium, Sprecher-Lernen, Long-Rec-Analyse
|
||
- **Selbst-Echo der Gegenseite gelöst:** LADSPA-Noise-Gate `micgate` im Mikro→PC-Pfad (Thr −45 dB, Mic-HW niedrig); AEC verworfen. Reboot-verifiziert.
|
||
- **Thermal-Schutzabschaltungen gefixt:** A76-Cap 1,6 GHz über die ganze `transcribeWav` (Whisper+Diar), SIGSTOP-Guard >90 °C; crash-sicheres asynchrones Speichern (`stopAndSave` persistiert vor Transkription); `/retranscribe` für hängende Zeilen.
|
||
- Whisper small → **medium** (Hörfehler).
|
||
- **Sprecher-Umbenennen + Stimm-Lernen** (Voiceprint-Zentroide) + Leertaste Play/Pause.
|
||
- Lange Aufnahmen (> 20 min) analysierbar: Chunked Map-Reduce gegen 4096-Token-Limit; Diar-Timeout skaliert mit Dauer; Lösch-Confirm.
|
||
|
||
## 2026-07-07 — MEILENSTEIN 1: USB-Headset-Pfad komplett
|
||
- Logi H390 ersetzt toten ES8323-Mikrofonpfad; callmix + 4 Loopbacks + `callrec_mix`-Remap; Volume-Bridge; Inline-Tasten.
|
||
- Kaltstart-verifiziert. Clip-sicheres Gain-Staging (PC→Mix 60 %) — Übersteuerung hatte Diarization zerstört (14 Sprecher, #41).
|
||
- Re-Diarization mit fester Sprecherzahl (`numSpeakers`), #41 14→2 verifiziert.
|
||
- LLM-Fixes: Phantom-Todo (Prompt-Beispiel-Echo) entfernt, KV-Cache-Clear, leere Todos → `[]`.
|
||
|
||
## 2026-07-06
|
||
- ES8323-3,5mm-Mikro als defekt diagnostiziert (Verstärkung fest −42,14 dB) → Entscheidung für USB-Headset.
|
||
|
||
## 2026-07-05 — „Helikopter“-Debugging (Referenz)
|
||
- ES8323 S16-Modus = Treiberbug (S24 nutzen); PipeWire/alsaloop-Capture des ES8323 injizierte ~13 Klicks/s,
|
||
arecord nicht; Windows-Shared-Mode-AGC = separates 20-Hz-Pumpen (exklusiv sauber).
|
||
- Sauberer Fallback damals: dual native-clock arecord. Durch Headset-Pfad obsolet.
|
||
|
||
## Früher
|
||
- iPhone-BT-HFP-Pfad aufgebaut (Rollen-Drop-in, frischer Pair, Echo-Fix Uplink←micgate, Route-Watcher) — Details Kap. 06.
|
||
- BT-Buds No-Bonding-Quirk: LinkKey manuell persistiert (Referenz, Dongle entfernt).
|