# Devlog Entwicklungstagebuch mit Zeiterfassung. Jeder Arbeitsabschnitt bekommt einen Eintrag: wann, wie lange, was entstanden ist, und was dabei schiefging. Die aufgewendete Zeit wandert nach jedem Abschnitt in die Spalte „tatsächlich" der [Aufwandsschätzung](AUFWANDSSCHAETZUNG.md). ## Zeitübersicht | Phase | Sitzungszeit | Sitzungen | abgeschlossen | |---|---:|---:|---| | Phase 0 — Fundament | 1:00 h | 1 | 03.09.2026 | | Phase 1 — Stammdaten | 1:15 h | 1 | 03.09.2026 | | Phase 1 — Nachtrag Geräteformular | 0:50 h | 1 | 03.09.2026 | | Phase 2 — Wartung und Prüfung | 2:25 h | 1 | 03.09.2026 | | Phase 3 — Einsätze und Übungen | 2:10 h | 1 | 03.09.2026 | | Phase 4 — Kiosk-PWA im Gerätehaus | 3:00 h | 1 | 03.09.2026 | | Phase 5 — Atemschutz nach FwDV 7 | 2:40 h | 1 | 03.09.2026 | | Phase 6 — Kartenmodule | 2:50 h | 1 | 04.09.2026 | | Phase 7 — Benachrichtigungen und Termine | 3:10 h | 1 | 04.09.2026 | | Phase 8 — Lokale KI | 3:40 h | 1 | 04.09.2026 | | **Summe** | **23:00 h** | **10** | | --- ## 2026-09-04 · Phase 8 — Lokale KI **07:30 – 11:10 · 3:40 h · Version 0.9.0** ### Was entstanden ist Ein Wiki, das man befragen kann, ein Diktat, ein Berichtsassistent, eine Belegerfassung — und zwei Protokolle, die belegen, was davon eine Maschine getan hat. | Bereich | Dateien | |---|---| | Rechnen | `lib/ki/zerlegen.ts`, `beleg-lesen.ts`, `anweisungen.ts`, `wiki.ts`, `vorgang.ts` | | Kanäle | `lib/integrations/llm.ts` (um Einbettungen und Bilder erweitert), `whisper.ts` | | Server | `server/routers/ki/wiki.ts`, `assistent.ts` | | Oberfläche | `app/(app)/wiki/`, `belege/`, `ki-protokoll/`, `protokoll/`; `components/ki/` | | Hintergrund | `worker/ki.ts`, zwei neue Auftragsarten | | Betrieb | `docker/postgres/Dockerfile` (PostGIS **und** pgvector), Ollama und faster-whisper im Profil `ki` | | Tests | 73 Unit, 14 E2E je Browser | ### Entscheidungen **Nichts Maschinelles gelangt ungeprüft in einen Nachweis.** Das ist die Regel aus Phase-8.md, und sie bestimmt den ganzen Aufbau: jede KI-Ausgabe ist zuerst ein eigener Datensatz und nicht ein Feld im Zieldokument. Es gibt keine Funktion, die eine Ausgabe erzeugt und gleich übernimmt — wer das umgehen will, muss Code schreiben, und das fällt in einer Durchsicht auf. Die Datenbank hält gegen: Eingabe, Ausgabe, Modell und Art sind nach dem Anlegen unveränderlich, gelöscht wird nicht, und über einen Vorschlag wird genau einmal entschieden. Eine Absicht im Code ist eine Absicht; ein Trigger ist eine Zusicherung. **Kein Rückfall auf einen Anbieter.** Fehlt der eigene Endpunkt, fehlt die Funktion. Ein Einsatzbericht spricht über Menschen in ihrer schlechtesten Stunde — solche Texte gehören nirgendwo anders hin als ins Gerätehaus. Und ein Rückfall, der „nur im Notfall" greift, ist genau der Fall, in dem niemand hinsieht. **Ohne Modell bleibt alles andere benutzbar.** Das war der größte Einzelposten der Phase und steht in keiner Aufwandsschätzung. Vier Hinweise an vier Stellen, eine zweite Suche, die immer funktioniert, und vierzehn E2E-Tests, die genau diesen Zustand absichern — der Testlauf hat keinen Ollama daneben, und das ist Absicht. **Drei Modelle statt einem.** Text, Einbettungen und Bilder sind einzeln konfigurierbar, weil ein Rechner ohne Grafikkarte das Einbettungsmodell noch flott schafft, das Textmodell zäh und das Vision-Modell praktisch nicht. Eine Wehr kann so ihr Wiki durchsuchbar machen, ohne Berichte schreiben zu lassen. **Zerlegt wird an den Überschriften, nicht nach Zeichenzahl.** Weil die Fundstelle später unter der Antwort steht, und eine Fundstelle soll ein Kapitel sein. Dazu kommt die Überschriftenkette in den Einbettungstext: ein Abschnitt über „Rückzugsdruck" ohne das Wort „Atemschutz" darüber findet sich sonst nicht, wenn jemand nach Atemschutz fragt. **Markdown wird ohne HTML gerendert.** Der Text kommt von Anwendern. Jeder Weg über `dangerouslySetInnerHTML` wäre ein Weg für ein `