Ein Wiki, das man befragen kann, ein Diktat, ein Berichtsassistent, eine Belegerfassung — und zwei Protokolle, die belegen, was davon eine Maschine getan hat.
Version 0.9.0
Die Regel, die alles bestimmt
Nichts, was ein Modell erzeugt, gelangt ungeprüft in einen Nachweis.
Daraus folgt der ganze Aufbau: jede KI-Ausgabe ist zuerst ein eigener Datensatz und nicht ein Feld im Zieldokument. Sie ist gekennzeichnet, steht daneben statt mittendrin, und braucht zwei gleich große Knöpfe, bevor etwas mit ihr geschieht. „Übernehmen" ist nicht der Standardweg und sieht auch nicht so aus.
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, falls doch: Eingabe, Ausgabe, Modell und Art sind nach dem Anlegen unveränderlich (Trigger), gelöscht werden kann ein Vorgang nicht (REVOKE DELETE), und über einen Vorschlag wird genau einmal entschieden. Ohne das ließe sich in einem Jahr nicht mehr sagen, welcher Satz in einem Einsatzbericht von einem Menschen stammt.
Kein Rückfall auf einen Anbieter
Fehlen die Container, fehlt die Funktion — sie wird nicht durch einen fremden Dienst ersetzt. 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.
Dafür bleibt alles andere ohne Modell vollständig benutzbar. Das war der größte Einzelposten der Phase und steht in keiner Aufwandsschätzung: Wiki lesen und schreiben, Wortsuche, Belege ablegen und von Hand ausfüllen, beide Protokolle. Wo etwas fehlt, steht ein Satz, der sagt was fehlt und wie es ohne geht — statt eines kaputten Knopfes.
Die 14 E2E-Tests dieser Phase laufen ohne Modell. Das ist Absicht: so sieht es bei einer Wehr aus, die FLORIAN aufsetzt, bevor sie über eine Grafikkarte nachdenkt.
Das Wiki
Markdown, selbst gerendert — und zwar ohne HTML: der Text kommt von Anwendern, und jeder Weg über dangerouslySetInnerHTML wäre ein Weg für ein <script> in einer Dienstvorschrift. Der Renderer baut React-Elemente.
Zwei Suchen, und beide werden gebraucht:
Suche
Findet
Braucht ein Modell
Wortsuche
was dasteht — „FwDV 7"
nein
Frage
was gemeint ist — „wie lange hält ein Schlauch" findet „Ablegereife"
ja
Beantwortet wird ausschließlich aus den eigenen Seiten, mit Fundstellen darunter. Steht es nicht drin, sagt FLORIAN das — ohne passende Auszüge wird das Modell gar nicht erst gefragt. Ein Modell, das auf die Frage nach der Prüffrist von Steckleitern eine Zahl nennt, die nirgends steht, wäre gefährlicher als gar keine Antwort.
Zerlegt wird an den Überschriften: eine Fundstelle soll ein Kapitel sein, kein aus der Mitte gerissener Absatz. Die Überschriftenkette geht in den Einbettungstext mit — ein Abschnitt über „Rückzugsdruck" ohne das Wort „Atemschutz" darüber findet sich sonst nicht.
Jede Änderung schreibt die vorherige Fassung weg. Eine Dienstvorschrift, die sich unbemerkt ändert, ist schlimmer als keine — deshalb ist wikiversion für die Anwendungsrolle weder änderbar noch löschbar.
Diktat, Bericht, Beleg
Diktat — der Weg, den es in jeder Wehr schon gibt: jemand spricht auf der Rückfahrt in sein Telefon. Ein Knopf, keine Einstellungen. Die Aufnahme bleibt abgelegt, solange nicht entschieden ist; wer dem Text nicht traut, hört nach. Das Modell darf nichts verbessern: „Hohlstrahlrohr" bleibt „Hohlstrahlrohr".
Berichtsentwurf — Stichpunkte hinein, Fließtext heraus. Was das Modell nicht bekommt, ist ebenso wichtig: Zeitstempel und Einsatznummer stehen schon als Felder im Bericht und stünden sonst zweimal da.
Beleg — Quittung fotografieren, prüfen, gegenzeichnen. Nicht erkannte Felder bleiben leer und gelb hinterlegt statt geraten zu werden. Ein leeres Feld ist eine Aufforderung; ein geratener Betrag ist eine falsche Buchung, die niemand bemerkt.
Zwei Protokolle nebeneinander
Ansicht
Beantwortet
/ki-protokoll
Was hat die Maschine getan?
/protokoll
Was haben Menschen getan?
Die Audit-Log-Ansicht kam mit dazu. Sie stand seit Phase 0 als ausgegrauter Eintrag mit „ab Phase 8" in der Navigation — mit dem KI-Protokoll daneben wäre es schief geworden, wenn die Wehr nachlesen könnte, was die Maschine getan hat, aber nicht, was Menschen getan haben. Der Router dafür existierte seit Phase 0; es fehlte nur die Seite.
Betrieb: neues Postgres-Image
FLORIAN braucht PostGIS und pgvector — es gibt kein offizielles Image mit beidem. Deshalb baut das Projekt eines (docker/postgres/Dockerfile).
Vor dem Migrieren nötig:
docker compose build postgres
docker compose up -d postgres # Datenverzeichnis bleibt unberührt
npm run db:migrate
Drei Modelle statt einem, 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.
Was zu testen ist
Ohne Modelle (so wie es jetzt läuft):
/wiki — die vier Seed-Seiten lesen. Markdown-Tabelle bei „Schläuche pflegen"?
Wortsuche „Rückzugsdruck" — zeigt sie die Textstelle, nicht bloß den Seitennamen?
Seite anlegen, dann bearbeiten und über Verlauf die alte Fassung ansehen.
/belege — steht dort ehrlich, dass kein Vision-Modell da ist und wie es ohne geht?
/ki-protokoll und /protokoll.
Mit Modellen, wenn Sie es ausprobieren wollen (Ollama braucht ein paar GB):
Auf einer Wiki-Seite Jetzt nachziehen — danach im Fragekasten „wie oft werden Schläuche geprüft?"
Auf einem offenen Einsatz: Bericht → Beim Schreiben helfen lassen, Stichpunkte eintippen, Entwurf erstellen. Steht der Entwurf im gestrichelten Rahmen und nicht im Berichtsfeld?
Diktat: der Browser fragt das Mikrofon nur über HTTPS oder auf localhost ab.
Nachweise
npx tsc --noEmit — ohne Ausgabe
npm run test — 495 Tests grün (73 neue, davon 21 gegen eine echte Datenbank samt Vektorsuche über Mandanten hinweg)
npx playwright test — 215 grün, 0 fehlgeschlagen (14 neue; die eine flaky Stelle wurde gleich stabilisiert)
npm run build — 56 Routen
docker compose build postgres — PostGIS 3.5 und pgvector 0.8.6 im selben Image
npm run db:seed — vier Wiki-Seiten mit eigenem Text
Ein Fehler, den der Test gefunden hat
Beim Zerlegen einer Wiki-Seite wurde ein kurzer Abschnitt an den vorherigen gehängt — auch wenn er unter einer anderen Überschrift stand. Unter einer Antwort hätte dann eine Fundstelle gestanden, in der der zitierte Satz gar nicht vorkommt. Genau die Art Fehler, für die es diese Phase am wenigsten verträgt. Zusammengezogen wird jetzt nur innerhalb desselben Kapitels.
Bewusst nicht drin
Bilder im Wiki. Entweder eine Datei in MinIO mit eigener Rechteprüfung beim Ausliefern, oder ein Verweis auf einen fremden Server — und Letzteres verbietet die Grundregel, dass FLORIAN nichts von außen nachlädt. Nachrüstbar, wenn eine Wehr es vermisst.
Streaming der Modellantwort. Sähe moderner aus, ist hier aber falsch: der Text soll gelesen und gegengezeichnet werden, nicht beim Entstehen bewundert. Ein halb geschriebener Entwurf, den jemand vorzeitig übernimmt, wäre genau die Lücke, die diese Phase schließen soll.
Weiterhin offen
Die drei Punkte aus PR #8 stehen unverändert — ich lege keine Issues an:
Die E2E-Suite schreibt in den Demo-Mandanten. Fünfte Phase in Folge.
npm run lint hat keine ESLint-Konfiguration und tut nichts.
React meldet verschachteltes DOM (<p> enthält <div>) auf der Einsatz-Detailseite aus Phase 3.
Dazu neu: die zurückgerollte Migration aus Phase 7 stand noch in _prisma_migrations und ließ prisma migrate dev die Datenbank zurücksetzen wollen. Die Zeile ist entfernt; ein migrate resolve --rolled-back räumt sie nicht weg.
Ein Wiki, das man befragen kann, ein Diktat, ein Berichtsassistent, eine Belegerfassung — und zwei Protokolle, die belegen, was davon eine Maschine getan hat.
**Version 0.9.0**
---
## Die Regel, die alles bestimmt
> **Nichts, was ein Modell erzeugt, gelangt ungeprüft in einen Nachweis.**
Daraus folgt der ganze Aufbau: jede KI-Ausgabe ist zuerst ein **eigener Datensatz** und nicht ein Feld im Zieldokument. Sie ist gekennzeichnet, steht daneben statt mittendrin, und braucht zwei gleich große Knöpfe, bevor etwas mit ihr geschieht. „Übernehmen" ist nicht der Standardweg und sieht auch nicht so aus.
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, falls doch: Eingabe, Ausgabe, Modell und Art sind nach dem Anlegen unveränderlich (Trigger), gelöscht werden kann ein Vorgang nicht (`REVOKE DELETE`), und über einen Vorschlag wird genau einmal entschieden. Ohne das ließe sich in einem Jahr nicht mehr sagen, welcher Satz in einem Einsatzbericht von einem Menschen stammt.
## Kein Rückfall auf einen Anbieter
Fehlen die Container, fehlt die Funktion — sie wird **nicht** durch einen fremden Dienst ersetzt. 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.
**Dafür bleibt alles andere ohne Modell vollständig benutzbar.** Das war der größte Einzelposten der Phase und steht in keiner Aufwandsschätzung: Wiki lesen und schreiben, Wortsuche, Belege ablegen und von Hand ausfüllen, beide Protokolle. Wo etwas fehlt, steht ein Satz, der sagt *was* fehlt und *wie es ohne geht* — statt eines kaputten Knopfes.
Die 14 E2E-Tests dieser Phase laufen **ohne Modell**. Das ist Absicht: so sieht es bei einer Wehr aus, die FLORIAN aufsetzt, bevor sie über eine Grafikkarte nachdenkt.
## Das Wiki
Markdown, selbst gerendert — und zwar **ohne HTML**: der Text kommt von Anwendern, und jeder Weg über `dangerouslySetInnerHTML` wäre ein Weg für ein `<script>` in einer Dienstvorschrift. Der Renderer baut React-Elemente.
**Zwei Suchen, und beide werden gebraucht:**
| Suche | Findet | Braucht ein Modell |
|---|---|---|
| Wortsuche | was dasteht — „FwDV 7" | nein |
| Frage | was gemeint ist — „wie lange hält ein Schlauch" findet „Ablegereife" | ja |
Beantwortet wird **ausschließlich aus den eigenen Seiten**, mit Fundstellen darunter. Steht es nicht drin, sagt FLORIAN das — ohne passende Auszüge wird das Modell gar nicht erst gefragt. Ein Modell, das auf die Frage nach der Prüffrist von Steckleitern eine Zahl nennt, die nirgends steht, wäre gefährlicher als gar keine Antwort.
Zerlegt wird an den **Überschriften**: eine Fundstelle soll ein Kapitel sein, kein aus der Mitte gerissener Absatz. Die Überschriftenkette geht in den Einbettungstext mit — ein Abschnitt über „Rückzugsdruck" ohne das Wort „Atemschutz" darüber findet sich sonst nicht.
Jede Änderung schreibt die vorherige Fassung weg. Eine Dienstvorschrift, die sich unbemerkt ändert, ist schlimmer als keine — deshalb ist `wikiversion` für die Anwendungsrolle weder änderbar noch löschbar.
## Diktat, Bericht, Beleg
**Diktat** — der Weg, den es in jeder Wehr schon gibt: jemand spricht auf der Rückfahrt in sein Telefon. Ein Knopf, keine Einstellungen. Die Aufnahme bleibt abgelegt, solange nicht entschieden ist; wer dem Text nicht traut, hört nach. Das Modell darf **nichts verbessern**: „Hohlstrahlrohr" bleibt „Hohlstrahlrohr".
**Berichtsentwurf** — Stichpunkte hinein, Fließtext heraus. Was das Modell *nicht* bekommt, ist ebenso wichtig: Zeitstempel und Einsatznummer stehen schon als Felder im Bericht und stünden sonst zweimal da.
**Beleg** — Quittung fotografieren, prüfen, gegenzeichnen. Nicht erkannte Felder bleiben **leer und gelb hinterlegt** statt geraten zu werden. Ein leeres Feld ist eine Aufforderung; ein geratener Betrag ist eine falsche Buchung, die niemand bemerkt.
## Zwei Protokolle nebeneinander
| Ansicht | Beantwortet |
|---|---|
| `/ki-protokoll` | Was hat die Maschine getan? |
| `/protokoll` | Was haben Menschen getan? |
Die Audit-Log-Ansicht kam mit dazu. Sie stand seit Phase 0 als ausgegrauter Eintrag mit „ab Phase 8" in der Navigation — mit dem KI-Protokoll daneben wäre es schief geworden, wenn die Wehr nachlesen könnte, was die Maschine getan hat, aber nicht, was Menschen getan haben. Der Router dafür existierte seit Phase 0; es fehlte nur die Seite.
## Betrieb: neues Postgres-Image
FLORIAN braucht **PostGIS und pgvector** — es gibt kein offizielles Image mit beidem. Deshalb baut das Projekt eines (`docker/postgres/Dockerfile`).
**Vor dem Migrieren nötig:**
```bash
docker compose build postgres
docker compose up -d postgres # Datenverzeichnis bleibt unberührt
npm run db:migrate
```
Dann die Modelle:
```bash
docker compose --profile ki up -d
docker compose exec ollama ollama pull qwen2.5:14b # Text
docker compose exec ollama ollama pull nomic-embed-text # Einbettungen
docker compose exec ollama ollama pull llama3.2-vision # Belege (optional)
```
Drei Modelle statt einem, 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.
## Was zu testen ist
**Ohne Modelle** (so wie es jetzt läuft):
1. **`/wiki`** — die vier Seed-Seiten lesen. Markdown-Tabelle bei „Schläuche pflegen"?
2. **Wortsuche** „Rückzugsdruck" — zeigt sie die Textstelle, nicht bloß den Seitennamen?
3. **Seite anlegen**, dann **bearbeiten** und über **Verlauf** die alte Fassung ansehen.
4. **`/belege`** — steht dort ehrlich, dass kein Vision-Modell da ist und wie es ohne geht?
5. **`/ki-protokoll`** und **`/protokoll`**.
**Mit Modellen**, wenn Sie es ausprobieren wollen (Ollama braucht ein paar GB):
6. Auf einer Wiki-Seite **Jetzt nachziehen** — danach im Fragekasten „wie oft werden Schläuche geprüft?"
7. Auf einem offenen Einsatz: **Bericht → Beim Schreiben helfen lassen**, Stichpunkte eintippen, Entwurf erstellen. Steht der Entwurf im gestrichelten Rahmen und **nicht** im Berichtsfeld?
8. Diktat: der Browser fragt das Mikrofon nur über HTTPS oder auf `localhost` ab.
## Nachweise
- `npx tsc --noEmit` — ohne Ausgabe
- `npm run test` — **495 Tests grün** (73 neue, davon 21 gegen eine echte Datenbank samt Vektorsuche über Mandanten hinweg)
- `npx playwright test` — 215 grün, 0 fehlgeschlagen (14 neue; die eine flaky Stelle wurde gleich stabilisiert)
- `npm run build` — 56 Routen
- `docker compose build postgres` — PostGIS 3.5 und pgvector 0.8.6 im selben Image
- `npm run db:seed` — vier Wiki-Seiten mit eigenem Text
## Ein Fehler, den der Test gefunden hat
Beim Zerlegen einer Wiki-Seite wurde ein kurzer Abschnitt an den vorherigen gehängt — auch wenn er unter einer **anderen Überschrift** stand. Unter einer Antwort hätte dann eine Fundstelle gestanden, in der der zitierte Satz gar nicht vorkommt. Genau die Art Fehler, für die es diese Phase am wenigsten verträgt. Zusammengezogen wird jetzt nur innerhalb desselben Kapitels.
## Bewusst nicht drin
**Bilder im Wiki.** Entweder eine Datei in MinIO mit eigener Rechteprüfung beim Ausliefern, oder ein Verweis auf einen fremden Server — und Letzteres verbietet die Grundregel, dass FLORIAN nichts von außen nachlädt. Nachrüstbar, wenn eine Wehr es vermisst.
**Streaming der Modellantwort.** Sähe moderner aus, ist hier aber falsch: der Text soll gelesen und gegengezeichnet werden, nicht beim Entstehen bewundert. Ein halb geschriebener Entwurf, den jemand vorzeitig übernimmt, wäre genau die Lücke, die diese Phase schließen soll.
## Weiterhin offen
Die drei Punkte aus PR #8 stehen unverändert — ich lege keine Issues an:
1. **Die E2E-Suite schreibt in den Demo-Mandanten.** Fünfte Phase in Folge.
2. **`npm run lint` hat keine ESLint-Konfiguration** und tut nichts.
3. **React meldet verschachteltes DOM** (`<p>` enthält `<div>`) auf der Einsatz-Detailseite aus Phase 3.
Dazu neu: die **zurückgerollte Migration aus Phase 7** stand noch in `_prisma_migrations` und ließ `prisma migrate dev` die Datenbank zurücksetzen wollen. Die Zeile ist entfernt; ein `migrate resolve --rolled-back` räumt sie nicht weg.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Wiki mit semantischer Suche ueber pgvector, Diktat ueber faster-whisper,
Berichtsassistent und Belegerfassung — alles gegen selbst betriebene
Modelle. Dazu zwei Protokollansichten: was die Maschine getan hat und was
Menschen getan haben.
Nichts, was ein Modell erzeugt, gelangt ungeprueft in einen Nachweis. Jede
Ausgabe ist zuerst ein eigener Datensatz, gekennzeichnet, mit zwei gleich
grossen Knoepfen davor. Die Datenbank haelt gegen: Eingabe, Ausgabe und
Modell sind unveraenderlich, geloescht wird nicht, entschieden wird einmal.
Kein Rueckfall auf einen Anbieter: fehlen die Container, fehlt die Funktion.
Dafuer bleibt alles andere ohne Modell vollstaendig benutzbar — geprueft von
vierzehn E2E-Tests, die ohne laufendes Modell durchlaufen.
Postgres bringt jetzt PostGIS und pgvector mit (eigenes Image), Ollama und
faster-whisper stehen im Compose-Profil "ki".
73 neue Unit-Tests, 14 neue E2E-Tests, Version 0.9.0.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Ein Wiki, das man befragen kann, ein Diktat, ein Berichtsassistent, eine Belegerfassung — und zwei Protokolle, die belegen, was davon eine Maschine getan hat.
Version 0.9.0
Die Regel, die alles bestimmt
Daraus folgt der ganze Aufbau: jede KI-Ausgabe ist zuerst ein eigener Datensatz und nicht ein Feld im Zieldokument. Sie ist gekennzeichnet, steht daneben statt mittendrin, und braucht zwei gleich große Knöpfe, bevor etwas mit ihr geschieht. „Übernehmen" ist nicht der Standardweg und sieht auch nicht so aus.
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, falls doch: Eingabe, Ausgabe, Modell und Art sind nach dem Anlegen unveränderlich (Trigger), gelöscht werden kann ein Vorgang nicht (
REVOKE DELETE), und über einen Vorschlag wird genau einmal entschieden. Ohne das ließe sich in einem Jahr nicht mehr sagen, welcher Satz in einem Einsatzbericht von einem Menschen stammt.Kein Rückfall auf einen Anbieter
Fehlen die Container, fehlt die Funktion — sie wird nicht durch einen fremden Dienst ersetzt. 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.
Dafür bleibt alles andere ohne Modell vollständig benutzbar. Das war der größte Einzelposten der Phase und steht in keiner Aufwandsschätzung: Wiki lesen und schreiben, Wortsuche, Belege ablegen und von Hand ausfüllen, beide Protokolle. Wo etwas fehlt, steht ein Satz, der sagt was fehlt und wie es ohne geht — statt eines kaputten Knopfes.
Die 14 E2E-Tests dieser Phase laufen ohne Modell. Das ist Absicht: so sieht es bei einer Wehr aus, die FLORIAN aufsetzt, bevor sie über eine Grafikkarte nachdenkt.
Das Wiki
Markdown, selbst gerendert — und zwar ohne HTML: der Text kommt von Anwendern, und jeder Weg über
dangerouslySetInnerHTMLwäre ein Weg für ein<script>in einer Dienstvorschrift. Der Renderer baut React-Elemente.Zwei Suchen, und beide werden gebraucht:
Beantwortet wird ausschließlich aus den eigenen Seiten, mit Fundstellen darunter. Steht es nicht drin, sagt FLORIAN das — ohne passende Auszüge wird das Modell gar nicht erst gefragt. Ein Modell, das auf die Frage nach der Prüffrist von Steckleitern eine Zahl nennt, die nirgends steht, wäre gefährlicher als gar keine Antwort.
Zerlegt wird an den Überschriften: eine Fundstelle soll ein Kapitel sein, kein aus der Mitte gerissener Absatz. Die Überschriftenkette geht in den Einbettungstext mit — ein Abschnitt über „Rückzugsdruck" ohne das Wort „Atemschutz" darüber findet sich sonst nicht.
Jede Änderung schreibt die vorherige Fassung weg. Eine Dienstvorschrift, die sich unbemerkt ändert, ist schlimmer als keine — deshalb ist
wikiversionfür die Anwendungsrolle weder änderbar noch löschbar.Diktat, Bericht, Beleg
Diktat — der Weg, den es in jeder Wehr schon gibt: jemand spricht auf der Rückfahrt in sein Telefon. Ein Knopf, keine Einstellungen. Die Aufnahme bleibt abgelegt, solange nicht entschieden ist; wer dem Text nicht traut, hört nach. Das Modell darf nichts verbessern: „Hohlstrahlrohr" bleibt „Hohlstrahlrohr".
Berichtsentwurf — Stichpunkte hinein, Fließtext heraus. Was das Modell nicht bekommt, ist ebenso wichtig: Zeitstempel und Einsatznummer stehen schon als Felder im Bericht und stünden sonst zweimal da.
Beleg — Quittung fotografieren, prüfen, gegenzeichnen. Nicht erkannte Felder bleiben leer und gelb hinterlegt statt geraten zu werden. Ein leeres Feld ist eine Aufforderung; ein geratener Betrag ist eine falsche Buchung, die niemand bemerkt.
Zwei Protokolle nebeneinander
/ki-protokoll/protokollDie Audit-Log-Ansicht kam mit dazu. Sie stand seit Phase 0 als ausgegrauter Eintrag mit „ab Phase 8" in der Navigation — mit dem KI-Protokoll daneben wäre es schief geworden, wenn die Wehr nachlesen könnte, was die Maschine getan hat, aber nicht, was Menschen getan haben. Der Router dafür existierte seit Phase 0; es fehlte nur die Seite.
Betrieb: neues Postgres-Image
FLORIAN braucht PostGIS und pgvector — es gibt kein offizielles Image mit beidem. Deshalb baut das Projekt eines (
docker/postgres/Dockerfile).Vor dem Migrieren nötig:
Dann die Modelle:
Drei Modelle statt einem, 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.
Was zu testen ist
Ohne Modelle (so wie es jetzt läuft):
/wiki— die vier Seed-Seiten lesen. Markdown-Tabelle bei „Schläuche pflegen"?/belege— steht dort ehrlich, dass kein Vision-Modell da ist und wie es ohne geht?/ki-protokollund/protokoll.Mit Modellen, wenn Sie es ausprobieren wollen (Ollama braucht ein paar GB):
localhostab.Nachweise
npx tsc --noEmit— ohne Ausgabenpm run test— 495 Tests grün (73 neue, davon 21 gegen eine echte Datenbank samt Vektorsuche über Mandanten hinweg)npx playwright test— 215 grün, 0 fehlgeschlagen (14 neue; die eine flaky Stelle wurde gleich stabilisiert)npm run build— 56 Routendocker compose build postgres— PostGIS 3.5 und pgvector 0.8.6 im selben Imagenpm run db:seed— vier Wiki-Seiten mit eigenem TextEin Fehler, den der Test gefunden hat
Beim Zerlegen einer Wiki-Seite wurde ein kurzer Abschnitt an den vorherigen gehängt — auch wenn er unter einer anderen Überschrift stand. Unter einer Antwort hätte dann eine Fundstelle gestanden, in der der zitierte Satz gar nicht vorkommt. Genau die Art Fehler, für die es diese Phase am wenigsten verträgt. Zusammengezogen wird jetzt nur innerhalb desselben Kapitels.
Bewusst nicht drin
Bilder im Wiki. Entweder eine Datei in MinIO mit eigener Rechteprüfung beim Ausliefern, oder ein Verweis auf einen fremden Server — und Letzteres verbietet die Grundregel, dass FLORIAN nichts von außen nachlädt. Nachrüstbar, wenn eine Wehr es vermisst.
Streaming der Modellantwort. Sähe moderner aus, ist hier aber falsch: der Text soll gelesen und gegengezeichnet werden, nicht beim Entstehen bewundert. Ein halb geschriebener Entwurf, den jemand vorzeitig übernimmt, wäre genau die Lücke, die diese Phase schließen soll.
Weiterhin offen
Die drei Punkte aus PR #8 stehen unverändert — ich lege keine Issues an:
npm run linthat keine ESLint-Konfiguration und tut nichts.<p>enthält<div>) auf der Einsatz-Detailseite aus Phase 3.Dazu neu: die zurückgerollte Migration aus Phase 7 stand noch in
_prisma_migrationsund ließprisma migrate devdie Datenbank zurücksetzen wollen. Die Zeile ist entfernt; einmigrate resolve --rolled-backräumt sie nicht weg.🤖 Generated with Claude Code