# Protokoll — Diagnose „@apo kann nicht telefonieren" (2026-08-11) Rohes Verlaufsprotokoll der Fehlersuche, als Quelle zum AAR [docs/aar/2026-08-11-apo-calls-profile-zeile.md](../../aar/2026-08-11-apo-calls-profile-zeile.md). Der AAR verdichtet zu Befund und Lehre; dieses Protokoll hält die tatsächliche Reihenfolge fest — **inklusive der Irrwege**, weil die Frage „wie konnte sich die Diagnose so lange verlaufen?" nur am ungekürzten Weg zu beantworten ist. ## Ausgangslage `@apo` konnte sich anmelden und schreiben, aber kein Call kam zustande. Dem vorausgegangen war ein längerer Vorgang mit mehreren manuellen Eingriffen an `@apo`s Konto, die das Problem nicht gelöst hatten — darunter ein selbst ausgedachter, in die MAS-Produktions-DB geschriebener `sub`-Wert und das Beenden aller Sitzungen. Diese Eingriffe waren real schädlich und haben Vertrauen und Zeit gekostet; sie sind der Grund, warum der Nutzer auf strukturiertem Vorgehen bestand. ## Die vier Irrwege (jeder an einer Messung gescheitert) 1. **Fehlende Cross-Signing-Verifikation.** Entkräftet: `sorb`/`clark` haben ebenfalls keine und telefonieren. 2. **Kaputter Browser-/Client-Zustand.** Entkräftet: ein frischer Client zeigte dasselbe Verhalten → an das Konto gebunden, nicht an den lokalen Zustand. 3. **Safari-Spezifik.** Zurückgezogen. 4. **MAS↔Synapse-Geräte-Desync.** Entkräftet: beide Seiten kannten dieselben drei Geräte. Das Muster war der eigentliche Fehler: aus dem, was serverseitig sichtbar war, wurde wiederholt auf eine Ursache geschlossen, ohne sie an einem funktionierenden Konto gegenzuprüfen. Der teuerste Einzelfall war der erfundene `sub`-Wert — `clark` hätte die Formel sofort widerlegt, wäre sie vor dem Schreiben geprüft worden. ## Die Kette, die zum Fund führte 1. **Vergleich statt Einzelbetrachtung.** `open_id_tokens` über *alle* aktiven Nutzer abgefragt: `@apo` = 0, alle anderen zweistellig+. Damit war klar: der Call-Pfad scheitert für `@apo` am allerersten Schritt (kein OpenID-Token). 2. **Confounder entfernt.** Der Testraum war **unverschlüsselt** — Krypto/ Cross-Signing damit in einem Schritt raus (der ganze Block „18 Pseudo-Geräte aus 6 Resets" war eine Sackgasse). 3. **Live-Mitschnitt beim echten Call-Klick.** Ergebnis: *nichts* — kein `openid/request_token`, kein `call.member`-Event. Beides erzeugt das Element-Call-Widget-iframe; beide fehlten → das iframe wird nie aktiv. 4. **Der Nutzer-Hinweis „Anzeigename konnte nicht gesetzt werden"** lieferte den 500er mit vollständigem Stacktrace: `TypeError: 'NoneType' object is not subscriptable` in `_check_profile_size`. 5. **Der Kontext-Hinweis des Nutzers** — „`apo` ist ein Konto von vor der Authentik-Integration" — drehte die Suche von „angesammelter Müll" auf „Provisionierungs-Lücke". ## Grundursache und Fix `@apo` fehlte die Zeile in Synapses `profiles`-Tabelle (Deaktivieren löscht das Profil, Reaktivieren legt es nicht neu an; `@apo` ging durch sechs Resets). Fehlende Zeile → jeder Displayname-Schreibvorgang crasht → kein Displayname → Element-Call-Widget initialisiert nie → kein OpenID-Token, kein Call. Fix: die fehlende Registrierungs-Default-Zeile per `INSERT` nachgetragen, an `clark`/ `calltest01` gegengeprüft. Danach: Displayname setzbar, `open_id_tokens` 0→6, Call verifiziert. `@apo` war der einzige betroffene lebende Nutzer. ## Nebenstrang: die Sicherheitslücke Beim Anlegen des Testkontos entstand die case-sensitive Dublette `boje`/`Boje`. Der Faden führte zu einem Kontoübernahme-Vektor: MAS stand auf `on_conflict: add` und hätte kollidierende Localparts an bestehende Konten verknüpft. Fix `on_conflict: fail` (ADR-0011), erst nach MAS-Neustart aktiv — was die zweite Lehre lieferte: eine SOPS-Secret-Änderung startet den Dienst nicht neu. ## Was das Protokoll dem AAR voraushat Der AAR nennt die Lehren; dieses Protokoll zeigt, dass sie **teuer erkauft** waren: vier eingesammelte Hypothesen und ein schädlicher DB-Schreib gingen dem einen `open_id_tokens`-Vergleich voraus, der die Sache in Minuten entschied. Die Lehre „erst vergleichen, dann schreiben" steht im AAR als Satz — hier steht, warum sie einen Satz wert ist.