Compare commits

...

4 Commits

Author SHA1 Message Date
Bernd Steckmeister 87ff15d760 chore: CHANGES.md Hook-Log nachführen
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 17:52:32 +02:00
Bernd Steckmeister 16561bbdeb docs: SQLCipher-Migrationsplan + konsolidierter PC-Testplan (M1-Vorbereitung)
Die zwei obersten offenen ROADMAP-Punkte sind PC-only in der Umsetzung,
aber jetzt maximal vorbereitet: docs/SQLCIPHER_MIGRATION.md (gegen beide
DB-Öffnungsstellen und matrix-6.2.0 verifiziert, inkl. Push-Isolate-Falle
und Migration-Race) und docs/PC_TESTPLAN.md (alle UNGETESTET(Pi)-Punkte
aus 7 verstreuten PROGRESS-Einträgen an einer Stelle).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 17:50:58 +02:00
Bernd Steckmeister 87b29b5912 docs: Fable-5-Review abgeschlossen und protokolliert (M0-Punkt abgehakt)
Review-Protokoll in PROGRESS.md nachgeholt (die Vorsession hatte f9979e4
und 891f348 gepusht, wurde aber vor dem Protokollieren abgebrochen) und
den Review zu Ende geführt: (a) Splits unabhängig per Zeilen-Multiset
verifiziert, (b) Soft-Logout-Guard gegen SDK-Quelle gegenverifiziert,
(c) Lint-Fixes äquivalent (onReorderItem gegen Flutter-SDK geprüft),
(d) ROADMAP-Haken stimmen mit dem Code überein. Nebenbefund: docs/
PROGRESS.md als Archiv markiert (Verwechslungsgefahr mit dem echten
Protokoll im Root).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 17:46:55 +02:00
Bernd Steckmeister 73420fe245 chore: Autopilot auf eigenes Claude-Profil (~/.claude-pyramid) + Review-Prompt
Bernds lokale Umstellung committen (Push = Backup): CLAUDE_CONFIG_DIR
zeigt auf das Pyramid-eigene Profil, Prompt um den Fable-5-Review-Pass
erweitert. *.bak in .gitignore (autopilot.sh.bak bleibt lokal).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 17:46:55 +02:00
8 changed files with 391 additions and 17 deletions
+1
View File
@@ -45,3 +45,4 @@ app.*.map.json
/android/app/release
autopilot.log
.claude/worktrees/
*.bak
+12
View File
@@ -1187,3 +1187,15 @@
2026-07-03 14:41 [Edit] /home/steggi/pyramid/lib/core/background_push.dart
2026-07-03 14:41 [Edit] /home/steggi/pyramid/lib/core/background_push.dart
2026-07-03 14:41 [Edit] /home/steggi/pyramid/lib/features/auth/login_notifier.dart
2026-07-03 17:45 [Edit] /home/steggi/pyramid/docs/PROGRESS.md
2026-07-03 17:46 [Edit] /home/steggi/pyramid/PROGRESS.md
2026-07-03 17:46 [Edit] /home/steggi/pyramid/ROADMAP.md
2026-07-03 17:49 [Write] /home/steggi/pyramid/docs/SQLCIPHER_MIGRATION.md
2026-07-03 17:49 [Edit] /home/steggi/pyramid/docs/SQLCIPHER_MIGRATION.md
2026-07-03 17:50 [Write] /home/steggi/pyramid/docs/PC_TESTPLAN.md
2026-07-03 17:50 [Edit] /home/steggi/pyramid/PROGRESS.md
2026-07-03 17:50 [Edit] /home/steggi/pyramid/ROADMAP.md
2026-07-03 17:50 [Edit] /home/steggi/pyramid/ROADMAP.md
2026-07-03 17:51 [Write] /home/steggi/.claude-pyramid/projects/-home-steggi-pyramid/memory/pyramid_push.md
2026-07-03 17:52 [Write] /home/steggi/.claude-pyramid/projects/-home-steggi-pyramid/memory/pyramid-arbeitsstand.md
2026-07-03 17:52 [Write] /home/steggi/.claude-pyramid/projects/-home-steggi-pyramid/memory/MEMORY.md
+125
View File
@@ -13,6 +13,131 @@ Schritt (und beim Abbruch mitten im Schritt den Zwischenstand). Format:
---
## 2026-07-03 M1-Vorbereitung: SQLCipher-Migrationsplan + konsolidierter PC-Testplan
**Erledigt:** Nach Abschluss des Fable-5-Reviews (Abschnitt darunter) die zwei
obersten offenen ROADMAP-Punkte (SQLCipher, Härtetest) so weit gebracht, wie es
auf dem Pi ohne GUI/Testgerät sicher geht beide bleiben offen, aber der
nächste PC-Termin kann jetzt direkt loslegen statt zu planen:
- `docs/SQLCIPHER_MIGRATION.md`: vollständiger Umsetzungsplan, gegen den echten
Code geschrieben (beide DB-Öffnungsstellen, Factory-Wahl pro Plattform).
Kernpunkte: gemeinsame DB-Fassade `app_database.dart` (zahlt aufs
M2-Storage-Modul ein), Android via `databaseFactoryFfi` +
`openCipherOnAndroid`, im Push-Isolate zwingend `databaseFactoryFfiNoIsolate`
(dieselbe Isolate-Falle, an der schon `NativeImplementationsIsolate`
scheiterte), Schlüssel im Android Keystore (`flutter_secure_storage`, schon
Abhängigkeit), Migration per `sqlcipher_export` in NEUE Datei mit
Backup/Verifikation/atomarem Tausch kein Fehlerpfad darf die Klartext-DB
beschädigen. Marker-Datei gegen das Migration/Push-Race. Phase 1 nur
Android (sqlcipher_flutter_libs liefert keine Windows-Binaries).
Tabellenname für die Verifikation gegen matrix-6.2.0 geprüft
(`box_inbound_group_session`).
- `docs/PC_TESTPLAN.md`: ALLE aufgelaufenen UNGETESTET(Pi)-Punkte aus den
bisherigen PROGRESS-Einträgen an einer Stelle konsolidiert (Härtetest/
Krypto-Kreislauf zuerst, dann die 6 Split-Bereiche, Reorder-Off-by-One-Check,
PDF-Zoom, Push-Beobachtung, „Uta einmal neu einloggen"). Bisher waren die
über 7 Einträge verstreut Gefahr, dass der PC-Lauf etwas übersieht.
**Offen/Nächster Schritt:** Unverändert: PC-Termin (jetzt mit fertigem
Testplan + Migrationsplan) oder Bernds Antworten (Call-Pilot, SQLCipher-
Priorität). Auf dem Pi ist damit alles abgearbeitet, was ohne GUI/Entscheidung
sicher geht inklusive des kompletten Qualitäts-Reviews.
**Stolperfallen:** Keine neuen reine Dokumentation, kein Code angefasst.
---
## Fable-5-Review (Qualitäts-Review aller Autopilot-Commits 25ed765..HEAD)
Bernds Auftrag (ROADMAP M0): alle bisherigen Sonnet-5-Commits kritisch und in
der Tiefe nachprüfen. Jeder Punkt hier wird abgehakt, sobald er geprüft ist
**bereits abgehakte Punkte in künftigen Sessions NICHT erneut prüfen.**
Hinweis zur Historie: Eine frühere Fable-5-Session hatte den Review begonnen
und zwei Fix-Commits gepusht (f9979e4, 891f348), wurde aber VOR dem
Protokollieren abgebrochen dieser Abschnitt holt das Protokoll nach und
schließt den Review ab.
- [x] **(a) Die 6 Gott-Datei-Aufteilungen fachlich geprüft Ergebnis: korrekt,
1 Befund bereits gefixt (f9979e4).** Unabhängige Nachprüfung (nicht nur den
alten Blockvergleich wiederholt): eigener Zeilen-Multiset-Vergleich
(Code-Zeilen ohne Kommentare/Imports/part-Direktiven) Original vor dem Split
vs. heutiger Stand für alle 6 Bibliotheken → **keine Code-Zeile verloren,
keine hinzugekommen** (settings_modal 5055, message_group 2409, rooms_panel
2308, space_admin_dialog 2079, chat_view 1813, document_viewer 1543 Zeilen,
jeweils exakt identisch). Alle `part`-Direktiven == Dateien auf Platte,
alle Part-Dateien mit korrektem `part of`. Befund der Vorsession bestätigt:
Beim Split gingen 24 **Erklärkommentar-Blöcke** verloren (u. a. die
Selbst-Aussperr-Warnung über `updatePowerLevelsSafely`, HTML-Subset-Doku,
PDF-Cache-Doku) mit f9979e4 an den richtigen Klassen wiederhergestellt
(Stichprobe geprüft: sitzt korrekt). `flutter analyze`: unverändert 1
bekannter Hinweis (`chat_provider.dart:42`).
- [x] **(b) Uta-Logout-/Push-Fix (63e4919, 9dc83f7) gegen das matrix-SDK 6.2.0
verifiziert Analyse war richtig, aber unvollständig; Lücke mit 891f348
geschlossen (Vorsession), heute vollständig gegenverifiziert:**
- SDK-Quelle bestätigt (client.dart:2374 ff.): Ohne eigenen `onSoftLogout`-
Handler eskaliert JEDER fehlgeschlagene Token-Refresh (auch bloße
Netzwerkfehler) zu `logout()` + `clear()` → Session inkl. Krypto-Schlüssel
weg. Mit `refreshToken: true` (9dc83f7) wären Refreshes Routine geworden
das Restrisiko wäre also GESTIEGEN. Der Guard (`soft_logout_guard.dart`,
891f348) ist die notwendige zweite Hälfte des Fixes.
- Guard-Code geprüft: wirft nie (alle Pfade gefangen; `AuthLog.write` fängt
intern selbst alles wichtig, sonst würde ein Logging-Fehler im
catch-Pfad doch wieder `logout()` auslösen). SDK ruft bei nicht-werfendem
Handler nachweislich nie `logout()` auf.
- „Retry heilt das Token-Rotations-Race mit dem Push-Isolate"-Behauptung
gegen SDK-Quelle geprüft: stimmt `refreshAccessToken()` liest den
Refresh-Token bei jedem Aufruf frisch per `database.getClient()` aus der
geteilten DB.
- Beide `Client(`-Konstruktionen der App (matrix_client.dart,
background_push.dart) haben den Guard keine ungeschützte übrig.
- `isLoggedInProvider`-Änderung (softLoggedOut ≠ ausgeloggt) korrekt:
verhindert Login-Screen-Flackern bei Routine-Refresh; echtes `loggedOut`
führt weiterhin zum Login-Screen.
- **Dokumentiertes Restrisiko (kein Fix möglich/nötig):** Ein hartes
`M_UNKNOWN_TOKEN` OHNE `soft_logout`-Flag führt im SDK weiterhin direkt zu
`clear()`. Das ist ein echter serverseitiger Session-Widerruf (z. B.
Admin-Logout) lokal nicht abwendbar; Schlüssel kommen dann übers
Key-Backup zurück. Kein stiller Fehlerpfad, sondern legitimer Server-Befehl.
- [x] **(c) analyze-/Lint-Fixes (9dc1175, 133a8ac, 99f10c5, 2395db5, 057ac1e,
401bd6a) auf Verhaltensänderungen geprüft alle äquivalent, 1 Kleinigkeit
gefunden (bewusst belassen):**
- `onReorder``onReorderItem` (401bd6a): gegen Flutter-SDK-Quelle
verifiziert der neue Callback korrigiert den Index intern, das entfernte
manuelle `newIdx--` ist korrekt; einzige Aufrufstelle migriert. Kein
Off-by-One beim Raum-Umsortieren.
- `Matrix4.translate/scale``translateByDouble/scaleByDouble` (PDF-Zoom):
mathematisch äquivalent (uniforme Skalierung, w=1).
- `withOpacity``withValues`, `activeColor``activeThumbColor`,
`cacheExtent``scrollCacheExtent`, `PublicRoomsChunk``PublishedRoomsChunk`,
print→debugPrint, `__``_`-Parameter, Curly-Braces: reine Renames/Syntax.
- Toter Code (9dc1175): entfernte Funktionen (`_showNotif`, `_fetchTitle`,
`_get`, `_applyNoiseSuppression`, `destructive`-Param, `_saved`-Feld) per
grep bestätigt nirgends referenziert.
- **Kleinigkeit:** In `mini_call_widget.dart` wurde das ungenutzte
`_hovered`-Feld nicht gelöscht, sondern verdrahtet (Hover-Farbe auf
Call-Buttons) streng genommen eine Mini-Verhaltensänderung in einem
Lint-Commit. Offensichtlich die ursprünglich gemeinte Funktion des Feldes,
rein kosmetisch, kein Risiko → belassen, hier nur dokumentiert.
- [x] **(d) Abgehakte ROADMAP-Punkte gegen Code gegengeprüft alle stimmen:**
`isKeyBackupMissing`-Warnung sitzt nach dem Settings-Split weiterhin in
beiden Logout-Pfaden (settings_about.dart, settings_shared.dart);
`refreshToken: true` in login_notifier.dart:84; Bootstrap-Flows
(`askUnlockSsss`, `_triggerBootstrap`) vorhanden; `features/calls/`-Leiche
existiert nicht; `docs/M2_MODULE_SCHNITT.md` vorhanden; `flutter analyze`
sauber (1 bekannter Hinweis). Nebenbefund gefixt: `docs/PROGRESS.md` war ein
eingefrorener Alt-Stand (2026-06-04) mit Verwechslungsgefahr zum echten
Protokoll im Root → Archiv-Banner eingefügt.
**Fazit:** Die Sonnet-5-Arbeit war handwerklich sauber; die zwei echten Lücken
(verlorene Kommentare, fehlender Soft-Logout-Guard) hatte die abgebrochene
Fable-5-Vorsession bereits gefixt beide Fixes heute unabhängig verifiziert.
Alles weiterhin UNGETESTET (Pi) im Sinne von „nicht in echter UI gesehen";
der ausstehende PC-Praxistest (siehe Einträge unten) bleibt Pflicht.
---
## 2026-07-03 M2: Gott-Datei `document_viewer.dart` aufgeteilt (5 Dateien)
**Erledigt:** Vor dem Weiterarbeiten wie immer Arbeitszyklus durchlaufen
+16 -12
View File
@@ -15,16 +15,16 @@ Punkte abhaken (`[x]`), wenn erledigt UND in `PROGRESS.md` protokolliert.
- [x] `lib/features/call/` vs. `lib/features/calls/` (leer?) klären Leiche entfernen
(geprüft: `calls/` existiert nicht mehr, nur `call/` mit den echten Dateien)
- [x] README.md durch echte Projektbeschreibung ersetzt (74d38fd)
- [ ] **Fable-5-Qualitäts-Review aller bisherigen Autopilot-Commits (Bernds Wunsch, VOR allem anderen):**
Sämtliche Commits vom 2026-07-03 (25ed765..HEAD, gemacht von Sonnet 5) kritisch
und in der Tiefe nachprüfen nicht nur formal: (a) die 6 Gott-Datei-Aufteilungen
stichprobenartig fachlich lesen (stimmen `part of`-Bezüge, Sichtbarkeiten,
keine verlorenen Blöcke über den automatisierten Blockvergleich hinaus),
(b) den Uta-Logout-/Push-Fix (63e4919, 9dc83f7) fachlich gegen das matrix-SDK
verifizieren (ist die Ursachen-Analyse schlüssig? Nebenwirkungen?),
(c) die analyze-/Lint-Fixes auf versehentliche Verhaltensänderungen prüfen,
(d) abgehakte ROADMAP-Punkte gegen PROGRESS.md und den Code gegenprüfen.
Befunde direkt fixen, alles in PROGRESS.md protokollieren.
- [x] **Fable-5-Qualitäts-Review aller bisherigen Autopilot-Commits (Bernds Wunsch, VOR allem anderen):**
ERLEDIGT siehe Abschnitt „Fable-5-Review" oben in PROGRESS.md.
(a) alle 6 Gott-Datei-Aufteilungen unabhängig verifiziert (Zeilen-Multiset,
part-Bezüge): korrekt, verlorene Erklärkommentare waren mit f9979e4 schon
wiederhergestellt; (b) Uta-Logout-/Push-Fix gegen matrix-SDK 6.2.0
verifiziert: Analyse richtig, Lücke (SDK eskaliert Refresh-Fehler zu
logout()+clear()) war mit 891f348 (onSoftLogout-Guard) geschlossen, Guard
heute gegenverifiziert; (c) Lint-Fixes verhaltensäquivalent (onReorderItem
gegen Flutter-SDK geprüft, kein Off-by-One); (d) abgehakte Punkte stimmen
mit dem Code überein. Alles weiterhin UNGETESTET (Pi) → PC-Praxistest bleibt.
- [x] **Uta-Random-Logout untersuchen:** UNGETESTET (Pi) Ursache im matrix-SDK
gefunden + Fix committet (63e4919, 9dc83f7), siehe PROGRESS.md 2026-07-03.
@@ -49,7 +49,9 @@ Punkte abhaken (`[x]`), wenn erledigt UND in `PROGRESS.md` protokolliert.
auf der Platte. Bewusst NICHT blind auf dem Pi gefixt: eine Umstellung auf
SQLCipher braucht eine Migration für bereits bestehende Klartext-DBs
(Utas Gerät!) ohne Testgerät hier zu riskant für „Kein Datenverlust".
Siehe PROGRESS.md 2026-07-03 + Frage an Bernd.
Siehe PROGRESS.md 2026-07-03 + Frage an Bernd. **Umsetzungsplan liegt
fertig in `docs/SQLCIPHER_MIGRATION.md`** (2026-07-03, gegen Code und
SDK verifiziert) PC-Termin kann direkt damit starten.
- [x] Key-Backup einrichten-Flow: bereits vorhanden (`bootstrap_dialog.dart`,
wird automatisch getriggert wenn Cross-Signing fehlt, `app_shell.dart`)
- [x] Key-Backup wiederherstellen-Flow: bereits vorhanden (`bootstrap_dialog.dart`,
@@ -59,7 +61,9 @@ Punkte abhaken (`[x]`), wenn erledigt UND in `PROGRESS.md` protokolliert.
(`_SessionsSection` in `settings_modal.dart` Liste, Umbenennen, Verifizieren
per SAS/QR, Abmelden, Massen-Abmeldung mit Passwort-Reauth)
- [ ] Härtetest dokumentieren: Login → Nachrichten → Logout → Login neu → alles noch lesbar
(gehört zum ausstehenden PC-Praxistest der beiden Bugfixes oben)
(gehört zum ausstehenden PC-Praxistest der beiden Bugfixes oben;
kompletter Ablauf inkl. aller aufgelaufenen UNGETESTET-Punkte steht
jetzt in `docs/PC_TESTPLAN.md` dort abarbeiten und abhaken)
## M2 Das große Refactoring (erst nach M0/M1!)
+5 -3
View File
@@ -9,6 +9,10 @@
cd "$(dirname "$0")"
export PATH="$HOME/.local/bin:$HOME/flutter/bin:$PATH"
# Pyramid laeuft auf eigenem Claude-Konto (Profil ~/.claude-pyramid),
# das Standard-Profil ~/.claude bleibt fuer die Webseiten-Arbeit.
export CLAUDE_CONFIG_DIR="$HOME/.claude-pyramid"
# --- Matrix-Statusberichte (Raum "🔺 Pyramid Autopilot", Token vom Gatus-Bot) ---
MATRIX_URL="http://127.0.0.1:6167"
MATRIX_ROOM="!sYfOwD4Dw4jBDTlNmL:steggi-matrix.work"
@@ -24,9 +28,7 @@ notify_matrix() {
-d "$body" > /dev/null || true
}
PROMPT="Lies CLAUDE.md und arbeite ROADMAP.md Punkt für Punkt weiter ab. \
Halte dich strikt an den Arbeitszyklus (PROGRESS.md pflegen, kleine Commits + Push). \
Arbeite so viele Punkte ab wie möglich."
PROMPT="Lies CLAUDE.md. Arbeite in dieser Reihenfolge: (1) Review-Pass: Gehe die in ROADMAP.md/PROGRESS.md als erledigt markierten Punkte durch, prüfe den zugehörigen Code kritisch und überarbeite/verbessere ihn, wo nötig. Führe in PROGRESS.md einen Abschnitt 'Fable-5-Review' und hake dort jeden geprüften Punkt ab, damit bereits reviewte Punkte nicht erneut geprüft werden. (2) Wenn alle erledigten Punkte reviewt sind, arbeite ROADMAP.md Punkt für Punkt weiter ab. Halte dich strikt an den Arbeitszyklus (PROGRESS.md pflegen, kleine Commits + Push). Arbeite so viel ab wie möglich."
while true; do
if [ -f PAUSE ]; then
+103
View File
@@ -0,0 +1,103 @@
# PC-Testplan alle aufgelaufenen UNGETESTET(Pi)-Punkte
Stand: 2026-07-03. Alle Pi-Sessions seit dem 2026-07-03 konnten nur
`flutter analyze` + automatisierte Textvergleiche fahren (kein GUI auf dem Pi).
Dieser Plan konsolidiert JEDEN ausstehenden Praxistest aus PROGRESS.md an einer
Stelle. Beim nächsten Windows-Lauf von oben nach unten abarbeiten, Ergebnis je
Punkt hier eintragen (✅/❌ + Datum), Befunde als eigene PROGRESS-Einträge.
Schnellster Weg: `flutter run -d windows`.
## 1. Härtetest Login/Krypto (M1 PFLICHT, zuerst!)
Deckt die Fixes 63e4919, 9dc83f7, 891f348 ab (Uta-Random-Logout + Guard).
- [ ] Login mit Test-Account → Nachrichten in verschlüsseltem Raum senden/lesen
- [ ] `auth_log.txt` (App-Support-Verzeichnis) prüfen: LoginState-Wechsel
werden mitgeschrieben, keine unerwarteten Warnungen
- [ ] Logout (Warnung bei fehlendem Key-Backup erscheint? b5762ea)
- [ ] Erneuter Login → **alte verschlüsselte Nachrichten noch lesbar?**
- [ ] Mehrere Stunden laufen lassen: kein Random-Logout, kein
Login-Screen-Flackern (isLoggedInProvider-Änderung), `auth_log.txt`
zeigt ggf. „Soft-Logout durch Token-Refresh abgewendet"
- [ ] Ergebnis als „Härtetest"-Eintrag in PROGRESS.md dokumentieren
(= ROADMAP-M1-Punkt „Härtetest dokumentieren" abhaken)
- [ ] Android: nach Neu-Login beobachten, ob Push-Inhalte wieder echt
entschlüsselt ankommen (statt „Neue Nachricht"-Platzhalter). Falls nicht:
zweite Ursache, siehe `docs/NOTIFICATIONS.md` + Memory „Pyramid Push"
- [ ] Danach Uta: einmal aus- und wieder einloggen (erst dann hat ihre
Session einen Refresh-Token!)
## 2. Settings-Split (5d77238, 12 Teildateien)
Alle Reiter öffnen und benutzen: Profil, Benachrichtigungen, Erscheinungsbild,
Voice, Tastaturkürzel, Privatsphäre, Sessions, Verschlüsselung, Account, Über.
- [ ] Verschlüsselung (HEILIG): Recovery-Key anzeigen, Megolm-Export UND
-Import (Passphrase), SAS/QR-Verifizierung starten
- [ ] Sessions: Gerät umbenennen, Einzel-Logout, Massen-Logout-Dialog
(Passwort-Reauth) nur bis zur Abfrage
- [ ] Account: Passwort-ändern-Dialog öffnen, Account-löschen-Dialog öffnen
(NICHT bestätigen)
- [ ] Logout-Warnungs-Text bei fehlendem Backup sichtbar (settings_about/shared)
## 3. Chat-Timeline-Split (5bf45a9) + tote-Code-Bereinigung (6400fb6)
Einen Chat mit allen Nachrichtentypen durchgehen:
- [ ] Text mit Link-Vorschau, Bild, Video, Audio, Datei-Anhang
- [ ] Download-/Entschlüsselungs-Fehlerpfade in `message_media.dart` gezielt
ansehen (am wenigsten geprüfter Teil)
- [ ] Reaktionen setzen/entfernen, Hover-Aktionsleiste, Antworten/Zitat
- [ ] Datums-Trenner, „Neue Nachrichten"-Divider
- [ ] Gescheiterte Nachricht: bleibt mit Retry/Löschen stehen, Retry geht
- [ ] Zeitanzeige bei aufeinanderfolgenden Nachrichten + Hover-Uhrzeit bei
Fortsetzungsnachrichten (`_formatMessageTime`-Zusammenführung)
## 4. Raumlisten-Split (a863fa3) + Reorder-Fix (401bd6a)
- [ ] Space wechseln, Raum beitreten/verlassen
- [ ] **Drag&Drop-Umsortieren: landet der Raum EXAKT an der Zielposition?**
(onReorder→onReorderItem, Index-Korrektur jetzt im Framework Off-by-One
wäre hier sichtbar; nach oben UND nach unten ziehen testen)
- [ ] Voice-Channel-Teilnehmerliste in der Raumliste
- [ ] Einladung annehmen/ablehnen, Ungelesen-Badge, DM-Avatare
## 5. Space-Admin-Split (0c7d359)
An einem TEST-Space, nicht an Utas echtem:
- [ ] Übersicht: Sichtbarkeit umschalten, Banner ändern (Danger-Zone nur ansehen)
- [ ] Mitglieder: einladen, Rolle ändern (Selbst-Aussperr-Schutz
`updatePowerLevelsSafely` greift?), kicken
- [ ] Berechtigungen ändern, Kanäle: erstellen + bestehenden Raum hinzufügen
## 6. Chat-View-Split (31e4001)
- [ ] Chat-Header (normal + DM mit ausklappendem Header/Presence)
- [ ] Tippanzeige, Offline-/Reconnect-Banner (Netz kurz trennen)
- [ ] Datei per Drag&Drop in den Chat ziehen (Overlay + Senden)
## 7. Dokument-Viewer-Split (daf4cf3) + Matrix4-Fix (401bd6a)
- [ ] PDF inline im Chat, Vollbild-Viewer: **Zoom per Buttons/Strg+Mausrad**
(translateByDouble/scaleByDouble-Umbau zoomt es zentriert wie vorher?),
Seiten-Navigation, Thumbnail-Leiste, Speichern-Button
- [ ] Text/Markdown/SVG-Vorschau, Office-Text-Extraktion
- [ ] ZIP/TAR-Archiv-Browser, PSD-Thumbnail
- [ ] Bild im Chat öffnen (Fallback-Pfade)
## 8. Kleinkram aus den Lint-Commits
- [ ] Mini-Call-Widget: Buttons zeigen jetzt Hover-Farbe (9dc1175, gewollt)
sieht das ok aus?
- [ ] Anhang-Dialog + Raum-erstellen-Dialog: Switches (activeThumbColor) sehen
aus wie vorher
- [ ] Voice-Channel beitreten/verlassen (Kernflow laut CLAUDE.md, von den
Splits nicht berührt, aber Pflicht nach jedem Refactoring)
## Danach
- [ ] Alle ✅ hier eintragen, PROGRESS.md-Eintrag „PC-Praxistest" schreiben,
erst DANN neue riskante Punkte anfangen (Call-Fassade, SQLCipher
siehe `docs/SQLCIPHER_MIGRATION.md`)
+4 -2
View File
@@ -1,6 +1,8 @@
# Pyramid Fortschritt & offene Punkte
# Pyramid Fortschritt & offene Punkte (ARCHIV, Stand 2026-06-04)
Stand: 2026-06-04
> **ACHTUNG:** Dies ist ein eingefrorener Alt-Stand von vor der neuen
> Arbeitsstruktur. Das aktuelle Arbeitsprotokoll liegt im Projekt-Root:
> `PROGRESS.md`. Diese Datei nur als historische Referenz lesen, nie pflegen.
## Erledigt
+125
View File
@@ -0,0 +1,125 @@
# SQLCipher-Migration der `pyramid.sqlite` Umsetzungsplan (PC-Termin)
Stand: 2026-07-03, geschrieben auf dem Pi (Plan gegen den echten Code verifiziert,
Umsetzung braucht PC + Android-Testgerät). Gehört zum offenen M1-Punkt
„Sichere Speicherung von Access-Token & Krypto-DB".
## Für Bernd in einfach
Die Datenbank der App (Nachrichten, Zugangs-Token, Verschlüsselungs-Schlüssel)
liegt heute **unverschlüsselt** auf dem Gerät geschützt nur durch die
Android-App-Sandbox. Ein Angreifer bräuchte Root oder physischen Zugriff mit
Entwickler-Tools, um sie zu lesen. Dieser Plan verschlüsselt die Datei selbst.
Der riskante Teil ist nicht die Verschlüsselung, sondern die **einmalige
Umwandlung bestehender Installationen** (Utas Handy!) deshalb: erst am PC
mit Testdaten, dann eigenes Gerät, dann erst Release.
**Offene Entscheidung (Frage in PROGRESS.md):** Priorität vor/nach M2?
## Ist-Zustand (verifiziert im Code)
| Stelle | Datei | Factory heute |
|---|---|---|
| Haupt-App Android/iOS | `lib/core/matrix_client.dart:24` | `sqflite_native.databaseFactory` (System-SQLite, **kann kein SQLCipher**) |
| Haupt-App Desktop | `lib/core/matrix_client.dart:27` | `databaseFactoryFfi` (gebündeltes sqlite3) |
| Push-Isolate (nur Android) | `lib/core/background_push.dart` `_buildClient()` | `sqflite_native.databaseFactory` |
- `sqlcipher_flutter_libs ^0.6.8` ist bereits in `pubspec.yaml`, wird nirgends benutzt.
- `flutter_secure_storage ^10` ist bereits da (→ Schlüsselablage im Android Keystore).
- Beide Prozesse öffnen **dieselbe Datei** (`pyramid.sqlite`, WAL-Modus,
`busy_timeout 5000`).
## Zielarchitektur
1. **Ein gemeinsamer DB-Öffner** `lib/core/app_database.dart` (neues Storage-Modul
im Sinne von M2): kapselt Factory-Wahl, PRAGMAs, Schlüsselbeschaffung und
Migration. `matrix_client.dart` und `background_push.dart` rufen NUR noch
diese Fassade damit verschwindet auch die heutige Code-Duplikation der
PRAGMA-Blöcke.
2. **Android:** nicht mehr `sqflite_native`, sondern `databaseFactoryFfi` mit
SQLCipher-Lib:
```dart
import 'package:sqlite3/open.dart';
import 'package:sqlcipher_flutter_libs/sqlcipher_flutter_libs.dart';
open.overrideFor(OperatingSystem.android, openCipherOnAndroid);
```
**Achtung Push-Isolate:** `databaseFactoryFfi` spawnt ein eigenes Isolate
im Firebase-Background-Isolate ist das genau die Fallenklasse, an der schon
`NativeImplementationsIsolate` scheiterte (Kommentar in
`background_push.dart`). Dort deshalb `databaseFactoryFfiNoIsolate` benutzen.
3. **Schlüssel:** 32 Byte kryptografisch zufällig (`Random.secure()`), hex-kodiert
in `flutter_secure_storage` unter `db_cipher_key`. Beide Prozesse lesen
denselben Eintrag. Schlüssel wird bei ERSTER Nutzung erzeugt; existiert schon
eine verschlüsselte DB, aber kein Schlüssel im Storage → harter Fehler mit
Klartext-Meldung, NIEMALS still neue DB anlegen (Datenverlust-Regel!).
4. **Öffnen:** `PRAGMA key = "x'<hex>'"` als allererstes Statement
(`OpenDatabaseOptions(onConfigure: ...)`), danach wie bisher WAL + busy_timeout.
5. **Windows/Linux-Desktop:** `sqlcipher_flutter_libs` liefert dort KEINE
Binaries. Phase 1 = nur Android verschlüsseln (dort liegt das echte Risiko,
dort sind die echten Nutzer); Desktop bleibt vorerst Klartext, klar im Code
kommentiert. Desktop-SQLCipher später als eigener Punkt (eigene DLL bündeln).
## Migration bestehender Klartext-DBs (der heikle Teil)
Reihenfolge beim App-Start, VOR `MatrixSdkDatabase.init`, VOR jedem Push-Zugriff:
1. Erkennung: Datei beginnt mit `SQLite format 3\0` → Klartext → Migration nötig.
(Verschlüsselte SQLCipher-Dateien haben keinen lesbaren Header.)
2. WAL eindampfen: Klartext-DB kurz normal öffnen,
`PRAGMA wal_checkpoint(TRUNCATE)`, schließen sonst verlieren wir Daten,
die noch in `pyramid.sqlite-wal` liegen.
3. **Backup:** `pyramid.sqlite``pyramid.sqlite.premigration` kopieren
(Bytes, nicht rename). Bleibt bis zum verifizierten Erfolg liegen.
4. Export in NEUE Datei (Original bleibt unangetastet):
```sql
ATTACH DATABASE 'pyramid.enc.sqlite' AS enc KEY "x'<hex>'";
SELECT sqlcipher_export('enc');
DETACH DATABASE enc;
```
(läuft über die SQLCipher-FFI-Verbindung auf der Klartext-DB)
5. Verifikation: `pyramid.enc.sqlite` mit Schlüssel öffnen,
`PRAGMA integrity_check` == ok UND Zeilenzahl einer Kerntabelle
(z. B. `box_inbound_group_session`, Name gegen matrix-6.2.0
`matrix_sdk_database.dart:139` verifiziert) identisch mit Original. Schlägt IRGENDWAS
fehl → `pyramid.enc.sqlite` löschen, App startet normal mit Klartext-DB
weiter, Fehler in `auth_log.txt`. **Kein Zustand darf die Klartext-DB
beschädigt zurücklassen.**
6. Tausch: Original + `-wal`/`-shm` löschen, `pyramid.enc.sqlite`
`pyramid.sqlite` (rename, gleiche Partition = atomar).
7. `.premigration`-Backup erst nach N erfolgreichen Tagen / manuell löschen
(Entscheidung Bernd: sonst liegt weiter eine Klartext-Kopie herum
Kompromiss: nach 7 Tagen beim Start automatisch löschen).
### Race mit dem Push-Isolate
Kommt ein FCM-Push, während die Haupt-App migriert, würde das Isolate die DB
mittendrin öffnen. Lösung: Marker-Datei `pyramid.sqlite.migrating` vor Schritt 2
anlegen, nach Schritt 6 löschen; `_buildClient()` im Push-Pfad bricht bei
vorhandenem Marker sofort ab (Notification zeigt dann einmalig den
„Neue Nachricht"-Platzhalter akzeptabel). Zusätzlich erkennt das Isolate
selbst Klartext vs. verschlüsselt am Datei-Header und wählt PRAGMA key
entsprechend es migriert aber NIE selbst.
## Testplan (PC-Termin, in dieser Reihenfolge)
1. Windows-Build mit Test-Account: Migration Klartext→SQLCipher durchlaufen
lassen (Desktop kriegt fürs TESTEN die FFI-SQLCipher-Variante per lokalem
Override, auch wenn Phase 1 sie im Release nicht aktiviert).
2. Kernflow danach: Login erhalten? Alte verschlüsselte Nachrichten lesbar?
Logout → Neu-Login → immer noch lesbar? (`docs/PC_TESTPLAN.md` Abschnitt 1)
3. Fehlerpfade erzwingen: Migration mit vollem Datenträger / Kill mitten in
Schritt 4 → App muss mit unversehrter Klartext-DB weiterlaufen.
4. Android-Testgerät (eigenes, NICHT Uta): frische Installation (Neuanlage
verschlüsselt), dann Update-Szenario (bestehende Klartext-DB migriert),
dann Push-Test (Isolate liest verschlüsselte DB; secure_storage-Zugriff
aus dem Background-Isolate explizit verifizieren bekanntes Risiko).
5. Erst wenn 14 grün: Release, Uta informieren (ihr Gerät migriert beim
ersten Start automatisch; vorher ihr Key-Backup verifizieren!).
## Bewusst NICHT im Scope
- `auth_log.txt`, `SharedPreferences`, Media-Cache bleiben Klartext (keine
Geheimnisse bzw. nur Cache; einzeln bewerten, falls Bernd es wünscht).
- Passphrase-basierter Schlüssel (Nutzer-Eingabe): bewusst nein Schlüssel
liegt im Keystore, gleiche Vertrauensstufe wie der Rest der App-Daten,
aber Datei-Exfiltration allein reicht dann nicht mehr.