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

9.8 KiB
Raw Blame History

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 (withOpacitywithValues, activeColoractiveThumbColor, cacheExtentScrollCacheExtent, PublicRoomsChunkPublishedRoomsChunk) Commit 057ac1e
  • Restliche flutter analyze-Hinweise behoben Commit 401bd6a:
    • document_viewer.dart: Matrix4.translate/scaletranslateByDouble/ scaleByDouble (PDF-Zoom, gleiches Verhalten)
    • rooms_panel.dart: onReorderonReorderItem (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).