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.
9.8 KiB
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 ALLERERSTESensureNotSoftLoggedOut()auf (matrix-Paketclient.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 Commit9dc83f7) sofort einen echtenclient.logout()auslöst (siehe Eintrag unten).- Der Hintergrund-Client aus
_buildClient()liest dieselbepyramid.sqlitewie der Haupt-Client. Einlogout()/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 →BgEnginezeigt nur noch den „Neue Nachricht"-Platzhalter (Fallback nach 6 s), nie mehr den echten Text. - Der bereits committete Fix (
refreshToken: truebeim 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()behandeltM_UNKNOWN_TOKENvom/sync-Endpunkt so: beisoft_logout: true→_handleSoftLogout()→ versuchtrefreshAccessToken()→ das SDK hatte nie einen Refresh-Token angefordert (client.login(...)inlogin_notifier.dartrief ohnerefreshToken: trueauf) →refreshAccessToken()wirft sofort "No refresh token available" → Catch-Block ruftawait 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-2384und:2496-2509.
- 3 bewusste Nutzer-Logout-Buttons in
- Logging (Commit
63e4919): neuelib/core/auth_log.dartschreibt jeden Login-Status-Wechsel (client.onLoginStateChanged) sowie SDK-Warnungen/-Fehler (Logs().onLog) inauth_log.txtim 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 jetztrefreshToken: truean. 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.refreshTokenist dannnull) – der Fix kann also nichts verschlimmern.
Offen/Nächster Schritt:
- 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. - Danach: den nächsten Punkt in M1 angehen (Push-Entschlüsselungs-Regression).
- 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:42nutzt weiterhin das deprecatedTimeline.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) – Commit057ac1e - Restliche
flutter analyze-Hinweise behoben – Commit401bd6a:document_viewer.dart:Matrix4.translate/scale→translateByDouble/scaleByDouble(PDF-Zoom, gleiches Verhalten)rooms_panel.dart:onReorder→onReorderItem(Index-Korrektur jetzt intern, manuellesnewIdx--entfernt);implementation_imports-Hinweis kommentiert (SpaceChild wird vommatrix-Paket nicht öffentlich exportiert, kein Fix möglich)voip_manager.dart:getSources()-Override kommentiert (Pflicht-Override der abstraktenMediaDevices-Klasse, die die Methode selbst deprecated hat)settings_modal.dart: zweiBuildContext-nach-await-Stellen mitcontext.mountedabgesichert (Geräte umbenennen, Passwortabfrage bei Massenlogout)- Bewusst NICHT gefixt:
chat_provider.dart:42(Timeline.onUpdatedeprecated, Ersatz wäreclient.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, nurlib/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 testläuft ins Leere, keine automatisierte Absicherung.flutter analyzelief sauber (0 Fehler/Warnungen), aber die Lint-Fixes indocument_viewer.dart(PDF-Zoom) undrooms_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 (beivoip_manager.darterst falsch über@overridegesetzt, 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(M0–M7 nach Bernds Prioritäten), dieses Protokoll- Klargestellt:
C:\Users\nordm\pyramid - Kopieist das EINZIGE aktuelle Repo;C:\Users\nordm\pyramidundMatrixPi\pyramidsind veraltete April-Stände (Commitc9af913)
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).