# SQLite-Persistenz Der vollständige Graph bleibt für Retrieval, Visualisierung und AI-THINK im Arbeitsspeicher. Dauerhaft gespeichert wird er nicht mehr als JSON-Gesamtsnapshot, sondern inkrementell in: ```text BRAIN_DATA_DIR/graph.db ``` Als Treiber wird `modernc.org/sqlite` verwendet. Die Anwendung bleibt damit ohne CGO baubar. ## Datenmodell Die SQLite-Datenbank enthält: - `nodes` – Nodes einschließlich Kategorien, Keywords und Metadaten; - `edges` – Beziehungen einschließlich Evidence und Confidence; - `vectors` – Embeddings als little-endian `float32`-BLOBs; - `graph_meta` – Schema- und Graphversion. Die Vektoren benötigen exakt vier Byte pro Dimension. Sie werden im Arbeitsspeicher ebenfalls als `float32` gehalten und nur an bestehenden API-Grenzen vorübergehend nach `float64` konvertiert. ## Schreibmodell ```env BRAIN_PERSIST_INTERVAL=5m ``` Ein Flush läuft sequenziell: 1. ausstehende AI-THINK-, Metadaten-, Runtime- und Cache-Dateien werden nach Pfad sortiert und atomar ersetzt; 2. anschließend schreibt eine SQLite-Transaktion ausschließlich geänderte oder gelöschte Node-, Edge- und Vector-Zeilen; 3. ein passiver WAL-Checkpoint hält die WAL-Datei begrenzt; 4. bei SIGTERM oder SIGINT wird ein finaler Flush und ein `TRUNCATE`-Checkpoint versucht. Mehrere Änderungen derselben Wissensdatei werden in der Dateiqueue dedupliziert. Ein unveränderter KB-Scan markiert keine Graphzeilen als schreibbedürftig und behält vorhandene Embeddings. ## SQLite-Einstellungen Die Datenbank läuft mit: ```text journal_mode=WAL synchronous=NORMAL foreign_keys=ON busy_timeout=5000 wal_autocheckpoint=0 temp_store=MEMORY ``` Der Graph-Store verwendet absichtlich eine einzelne `database/sql`-Verbindung. In-Memory-Lesezugriffe werden weiterhin über den Store parallel bedient; nur die gebündelte Persistenz ist serialisiert. ## Durability-Fenster Neue In-Memory-Erkenntnisse sind sofort sichtbar. Bei einem harten Stromausfall können jedoch die Änderungen seit dem letzten Flush fehlen. Ein regulärer Container-Shutdown löst einen finalen Flush aus. Manueller Flush: ```bash curl -fsS -X POST http://localhost:8090/api/flush ``` ## Portabler Export Die laufende Datenbank sollte nicht zusammen mit ihren `-wal`- und `-shm`-Dateien kopiert werden. Der Export-Endpunkt verwendet `VACUUM INTO` und erzeugt eine kompakte, konsistente Einzeldatei: ```bash curl -fsS \ -H "Authorization: Bearer $BRAIN_API_KEY" \ http://localhost:8090/api/state/export \ -o graph.db ``` Ohne API-Key entfällt der Header. Import auf einem anderen System mit identischer KB-Basis: ```bash docker compose stop brain # Vorhandene DB und mögliche Sidecars entfernen. docker compose run --rm --no-deps -T --entrypoint sh brain -c ' rm -f /app/data/graph.db /app/data/graph.db-wal /app/data/graph.db-shm cat > /app/data/graph.db ' < graph.db docker compose up -d brain ``` Beim nächsten Scan bleiben Vektoren für unveränderte Dokument-IDs und identische Embedding-Inhalte erhalten. Das in `graph_meta` gespeicherte Embedding-Modell wird beim Start geprüft. Sobald Ollama erreichbar ist, wird zusätzlich der Modelldigest aus dem Pool gespeichert und verglichen. Ändern sich Modellname oder Digest, werden vorhandene Vektoren automatisch verworfen und selektiv neu gelernt. Neue oder veränderte Beiträge werden ebenfalls nur einzeln neu eingebettet. ## Vollständiger Reset Da diese Staging-Version keine Migration aus `graph-state.json` benötigt, genügt: ```bash docker compose stop brain docker compose run --rm --no-deps --entrypoint sh brain -c ' rm -f /app/data/graph.db /app/data/graph.db-wal /app/data/graph.db-shm ' docker compose up -d brain ``` Eine eventuell noch vorhandene `graph-state.json` wird ignoriert. `runtime-settings.json`, GLPI-Cache, Artikelmetadaten und Staging-Drafts werden durch diesen Reset nicht gelöscht. ## Status ```bash curl -fsS http://localhost:8090/api/status | jq '.graph_storage, .persistence' ``` `graph_storage` zeigt unter anderem DB-/WAL-Größe, binäre Vector-Bytes, persistierte Graphversion und ausstehende Row-Änderungen. ## Persistente Recherchebelege Akzeptierte Volltextquellen werden nicht in die Graph-Metadaten eingebettet, sondern prüfsummengeschützt unter folgendem Pfad gespeichert: ```text BRAIN_DATA_DIR/research-evidence/.json ``` `graph.db` enthält den Forschungs-Node, seine kurze Zusammenfassung, die Verknüpfungen und den relativen Evidenzpfad. Für eine vollständige Übertragung des selbst erlernten externen Wissens müssen daher neben `graph.db` auch `research-evidence/`, `article-metadata/` und die erzeugten Staging-Artikel kopiert werden. Fehlt eine Evidenzdatei, bleibt der Graph-Node sichtbar; der Volltext wird jedoch nicht automatisch als bereits gelernter Beleg wiederverwendet. Für einen vollständig frischen Lernstart ohne Wiederverwendung alter Webbelege müssen bei gestopptem Brain zusätzlich `BRAIN_DATA_DIR/research-evidence/` und gegebenenfalls `BRAIN_DATA_DIR/article-metadata/` entfernt beziehungsweise archiviert werden. Nur `graph.db` zu löschen lässt die Evidenzdateien als harmlose, aber nicht mehr verknüpfte Dateien zurück.