Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0113vDKdSNtD3Dwcw4QMu9yV
17 KiB
08 — Changelog
Chronik der Entwicklungsschritte. Regel: jede zukünftige Änderung bekommt hier einen Eintrag (Datum, Was, Warum, betroffene Dateien/Backups).
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 .
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-themeauf<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-motionrespektiert. 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): direktercr_mic2mix-Loopback ENTFERNT; stattdessenpw-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 -lprü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 vonrediarize()UNDanalyzeRecording()(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 beendetschlä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), HFQwen/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, prodrkllm_servermit ChatML neu gebaut (Rollback:.bak-gemmatmpl+ Drop-in zurückstellen),WHOLE_MAX_CHARS20 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_CHARS8000 → 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) undWHOLE_MAX_CHARStestweise 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_CHARSzurü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 wietranscribeWav/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“ (Bundleindex-CuWeUh1j.js, Backupsindex.html.bak-aime/main.js.bak-aime), Doku rebranded. Technische Bezeichner auf dem Board bleibencallrec*(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, CSSpre-line). - Chunk-Salvage-JSON-Leak gefixt; Reduce-Input gekappt + Retry;
cleanListfiltertnull/[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=yesgesetzt (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),
reanalyzere-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-promptmit 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
micgateim 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 (stopAndSavepersistiert vor Transkription);/retranscribefü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).