Files
pyramid/PROGRESS.md
T
Bernd Steckmeister e8ab626c92 docs: Push-Regression vermutlich identische Ursache wie Random-Logout
getEventByPushNotification() ruft ensureNotSoftLoggedOut() auf, das ohne
Refresh-Token (siehe 9dc83f7) denselben destruktiven Auto-Logout auslösen
kann wie beim normalen Sync — nur eben aus dem Hintergrund-Isolat, mit
Zugriff auf dieselbe DB. Der bestehende Fix deckt vermutlich beide
Symptome ab. ROADMAP abgehakt, UNGETESTET (Pi) bis Praxistest am PC.
2026-07-03 09:56:02 +02:00

169 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Pyramid Arbeitsprotokoll
Neueste Einträge OBEN. Jede Claude-Session schreibt hier nach jedem abgeschlossenen
Schritt (und beim Abbruch mitten im Schritt den Zwischenstand). Format:
```
## JJJJ-MM-TT Kurztitel
**Erledigt:** was fertig ist (mit Commit-Hash)
**Offen/Nächster Schritt:** der konkrete nächste Handgriff
**Stolperfallen:** was schiefging und wie es gelöst wurde (damit es nie zweimal passiert)
**Fragen an Bernd:** (optional) gesammelte Richtungsfragen, die nicht blockieren
```
---
## 2026-07-03 M1: Push-Regression vermutlich dieselbe Ursache wie Random-Logout
**Erledigt:** Vor dem Blick in den Push-Code die Vermutung geprüft, ob die
Push-Entschlüsselungs-Regression und der Uta-Random-Logout-Bug (siehe Eintrag
weiter unten) zusammenhängen Ergebnis: **sehr wahrscheinlich ja, exakt
dieselbe Ursache.**
- `client.getEventByPushNotification(...)` (aufgerufen in `_bgDecryptAndShow`,
`background_push.dart:84`) ruft als ALLERERSTES `ensureNotSoftLoggedOut()`
auf (matrix-Paket `client.dart:1878`). Diese Funktion prüft, ob der
Access-Token in < 1 Minute abläuft, und löst dann `_handleSoftLogout()` aus
**dieselbe Funktion**, die ohne Refresh-Token (unser Zustand vor Commit
9dc83f7) sofort einen echten `client.logout()` auslöst (siehe Eintrag unten).
- Der Hintergrund-Client aus `_buildClient()` liest **dieselbe** `pyramid.sqlite`
wie der Haupt-Client. Ein `logout()`/`clear()` aus dem Hintergrund-Isolat
würde also die komplette Session (inkl. Krypto-Schlüssel) für die GESAMTE
App zerstören nicht nur für den einen Push. Das erklärt, warum das Problem
als dauerhafte Regression erscheint ("seit dem letzten Update nie wieder"):
Nach dem ersten Auto-Logout-Ereignis (ausgelöst beim Sync ODER beim
Entschlüsseln eines Pushs) sind die Schlüssel weg, jede folgende
Entschlüsselung schlägt fehl → `BgEngine` zeigt nur noch den
„Neue Nachricht"-Platzhalter (Fallback nach 6 s), nie mehr den echten Text.
- Der bereits committete Fix (`refreshToken: true` beim Login, 9dc83f7) behebt
damit vermutlich BEIDE Symptome gleichzeitig: der Refresh-Token liegt in der
gemeinsamen DB, also kann auch der Hintergrund-Client ihn lesen und einen
drohenden Soft-Logout durch stillen Refresh abwenden, statt die Session zu
zerstören.
**Offen/Nächster Schritt:** Gehört zum selben Praxistest wie der
Random-Logout-Punkt oben zusätzlich beobachten, ob nach einer Weile
(mehrere Stunden/Tage) echte Push-Inhalte statt Platzhalter ankommen. Schlägt
das fehl, liegt eine zweite, unabhängige Ursache vor (dann `docs/NOTIFICATIONS.md`
+ Memory „Pyramid Push" erneut konsultieren, insbesondere die 3 dort gelisteten
Fallstricke der Hintergrund-Entschlüsselung).
**Stolperfallen:** Diese Verbindung wurde rein durch Lesen des matrix-SDK-
Quellcodes hergeleitet (`~/.pub-cache/hosted/pub.dev/matrix-6.2.0/lib/src/client.dart`),
nicht durch Beobachtung auf einem echten Gerät bewusst als Vermutung
markiert, bis der PC-Praxistest sie bestätigt.
---
## 2026-07-03 M1: Uta-Random-Logout Ursache gefunden + Fix (UNGETESTET/Pi)
**Erledigt:**
- Alle Logout-Auslöser im Code kartiert:
- 3 bewusste Nutzer-Logout-Buttons in `settings_modal.dart` (alle hinter
Bestätigungsdialog) kein Kandidat für "random"
- Der eigentliche Verdächtige: `matrix`-Paket (v6.2.0) `Client._innerSync()`
behandelt `M_UNKNOWN_TOKEN` vom `/sync`-Endpunkt so: bei `soft_logout: true`
`_handleSoftLogout()` → versucht `refreshAccessToken()` → **das SDK
hatte nie einen Refresh-Token angefordert** (`client.login(...)` in
`login_notifier.dart` rief ohne `refreshToken: true` auf) → `refreshAccessToken()`
wirft sofort "No refresh token available" → Catch-Block ruft `await logout()`
auf: ein **echter, destruktiver Logout**, ausgelöst rein durch einen normalen
Soft-Logout (z. B. abgelaufenes Access-Token), ganz ohne Nutzerinteraktion.
Quelle: `~/.pub-cache/hosted/pub.dev/matrix-6.2.0/lib/src/client.dart:2374-2384`
und `:2496-2509`.
- **Logging (Commit 63e4919):** neue `lib/core/auth_log.dart` schreibt jeden
Login-Status-Wechsel (`client.onLoginStateChanged`) sowie SDK-Warnungen/-Fehler
(`Logs().onLog`) in `auth_log.txt` im App-Support-Verzeichnis übersteht
App-Neustart. Zusätzlich loggen alle 3 Nutzer-Logout-Buttons sich selbst, damit
sich künftig unterscheiden lässt: Nutzer-Logout vs. SDK-Auto-Logout. Reine
Zusatzfunktion, keine Verhaltensänderung.
- **Fix (Commit 9dc83f7):** `client.login(...)` fordert jetzt `refreshToken: true`
an. Damit kann das SDK einen Soft-Logout künftig durch stillen Token-Refresh
überstehen, statt die Sitzung zu zerstören. Unterstützt der Server keine
Refresh-Tokens, bleibt das Verhalten exakt wie vorher (`response.refreshToken`
ist dann `null`) der Fix kann also nichts verschlimmern.
**Offen/Nächster Schritt:**
1. **Praxistest auf dem PC (zwingend vor Haken in ROADMAP!):** Login → Nachrichten
senden/lesen → Logout → erneuter Login → alte verschlüsselte Nachrichten noch
lesbar? Dabei prüfen, ob `auth_log.txt` (App-Support-Verzeichnis) die
Login-Status-Wechsel sauber mitschreibt.
2. Danach: den nächsten Punkt in M1 angehen (Push-Entschlüsselungs-Regression).
3. **Wichtig für Bernd/Uta:** Der Fix wirkt nur für NEUE Logins. Utas bereits
bestehende Sitzung bekommt erst nach einem einmaligen manuellen Neu-Login
einen Refresh-Token und ist bis dahin weiterhin anfällig. Sobald der PC-Test
grün ist, sollte Uta sich einmal aus- und wieder einloggen.
**Stolperfallen:**
- Konnte auf dem Pi nicht mit echtem Login/Logout getestet werden (kein GUI,
kein Matrix-Testaccount zur Hand) Fix beruht auf genauem Lesen des
matrix-SDK-Quellcodes, nicht auf Beobachtung im Betrieb. Deshalb zwingend
vor dem nächsten Haken in ROADMAP am PC nachprüfen.
- `chat_provider.dart:42` nutzt weiterhin das deprecated `Timeline.onUpdate`
(Re-Entschlüsseln nach Schlüssel-Empfang) hängt mit demselben Sync-Bereich
zusammen, aber bewusst nicht angefasst, um nicht zwei riskante Änderungen im
selben Bereich gleichzeitig ungetestet zu committen.
---
## 2026-07-03 M0 abgeschlossen: Ordnung, flutter analyze sauber, README
**Erledigt:**
- Liegen gebliebene Deprecation-Fixes aus einer abgebrochenen Session committet
(`withOpacity``withValues`, `activeColor``activeThumbColor`, `cacheExtent`
`ScrollCacheExtent`, `PublicRoomsChunk``PublishedRoomsChunk`) Commit 057ac1e
- Restliche `flutter analyze`-Hinweise behoben Commit 401bd6a:
- `document_viewer.dart`: `Matrix4.translate/scale``translateByDouble`/
`scaleByDouble` (PDF-Zoom, gleiches Verhalten)
- `rooms_panel.dart`: `onReorder``onReorderItem` (Index-Korrektur jetzt intern,
manuelles `newIdx--` entfernt); `implementation_imports`-Hinweis kommentiert
(SpaceChild wird vom `matrix`-Paket nicht öffentlich exportiert, kein Fix möglich)
- `voip_manager.dart`: `getSources()`-Override kommentiert (Pflicht-Override der
abstrakten `MediaDevices`-Klasse, die die Methode selbst deprecated hat)
- `settings_modal.dart`: zwei `BuildContext`-nach-`await`-Stellen mit
`context.mounted` abgesichert (Geräte umbenennen, Passwortabfrage bei Massenlogout)
- **Bewusst NICHT gefixt:** `chat_provider.dart:42` (`Timeline.onUpdate` deprecated,
Ersatz wäre `client.onSync` + Raum-Filter). Hängt am E2EE-Redecrypt-Pfad
(Re-Entschlüsseln nach Schlüssel-Empfang) laut CLAUDE.md heiliger Bereich,
Umbau nur mit dediziertem Login→Nachrichten→Logout→Login-Test, nicht nebenbei.
- `lib/features/calls/` (Leiche) geprüft: existiert nicht mehr, nur `lib/features/call/`
mit den echten Dateien Punkt war bereits erledigt, nur nicht abgehakt.
- README.md durch echte Projektbeschreibung ersetzt (Funktionsumfang, Build, Struktur) Commit 74d38fd
- ROADMAP.md: M0 komplett abgehakt.
**Offen/Nächster Schritt:** M1, erster Punkt Uta-Random-Logout-Bug untersuchen
(Logging an allen Logout-Pfaden einbauen, dann Ursache finden). Direkt danach die
Push-Entschlüsselungs-Regression (`docs/NOTIFICATIONS.md` + Memory „Pyramid Push"
vorher lesen).
**Stolperfallen:**
- Kein `test/`-Ordner vorhanden → `flutter test` läuft ins Leere, keine automatisierte
Absicherung. `flutter analyze` lief sauber (0 Fehler/Warnungen), aber die Lint-Fixes
in `document_viewer.dart` (PDF-Zoom) und `rooms_panel.dart` (Drag-Reorder der
Raumliste) sind **UNGETESTET** in echter UI nächster Windows-Lauf sollte kurz
PDF-Zoom und Raum-Umsortieren per Drag prüfen.
- Der `ignore:`-Kommentar für einen deprecated-Aufruf muss auf der Zeile *unmittelbar*
über der betroffenen Codezeile stehen, nicht nur "in der Nähe" sonst wirkt er nicht
(bei `voip_manager.dart` erst falsch über `@override` gesetzt, dann korrigiert).
---
## 2026-07-03 Arbeitsstruktur angelegt + Vollbackup (Setup, noch kein Code)
**Erledigt:**
- Vollbackup inkl. Git-Historie: `MatrixPi\backups\pyramid-kopie_backup_2026-07-03.tar.gz` (510 MB)
- `CLAUDE.md` (Arbeitsregeln), `ROADMAP.md` (M0M7 nach Bernds Prioritäten), dieses Protokoll
- Klargestellt: `C:\Users\nordm\pyramid - Kopie` ist das EINZIGE aktuelle Repo;
`C:\Users\nordm\pyramid` und `MatrixPi\pyramid` sind veraltete April-Stände (Commit c9af913)
**Offen/Nächster Schritt:** M0, Punkt 2 die ~140 uncommitteten Dateien mit `git status`
sichten und in thematische Commits aufteilen (diese drei neuen Dateien mit committen),
dann `git push origin master`.
**Stolperfallen:**
- Letzter Commit ist vom 2026-04-28 (d706ace), gearbeitet wurde aber bis mindestens
2026-06-12 → zwischen Commits und Realität liegen 6 Wochen. Genau deshalb: ab jetzt
kleine Commits nach jedem Schritt.
- Git-Remote (Gitea auf dem Pi) enthält Zugangsdaten in der URL funktioniert, aber
nur erreichbar, wenn der Pi läuft (unterwegs: WireGuard nötig).