Gate 4, slice 3: verfahren/, hosts/, vision/ and shared/ moved via git mv - six AARs to docs/aar/ (four harvested by the 2026-08-09 retro, two open), procedures and host knowledge to docs/wiki/ (admin, deployment, architecture, new area vision), the retro protocol and the commit mapping table to docs/sources/ (protokolle/, migration/). New: the wiki index linking every page, and the mirror-topology page carrying the why-two-places reasoning verbatim from the old CLAUDE.md (F-013 preserved). All moved-path references retargeted; the link checker drove the sweep to zero. pruefe_prosa.py added (pattern C+D): SHA citations resolve via repo, mapping table, optional component clones or a curated exemption list (documented dead Gitea-force-push commits, a vendor-repo tag, an Authentik uid that is hex but no git SHA, the external neckbeard reference); wiki task prose without an issue reference errors, with a visible pragma for deliberate checklists; the dead-tracker denylist now covers every mirrored repo's retired Gitea tracker (F-005) - two links re-verified against live GitLab titles and retargeted, five defused into honest historical citations. Verified: validate 0/0, gen_status --check current, drift 0. Demo on the pre-migration state fires 6 findings (3 orphaned SHAs, 3 task blocks); on the current tree exactly the 3 F-004 task blocks remain - they turn green in slice 4 when the issues exist, which is why pruefe_prosa joins CI only then. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.5 KiB
6.5 KiB
type, status, date, related
| type | status | date | related |
|---|---|---|---|
| aar | open | 2026-08-11 |
AAR — @apo konnte nicht telefonieren: fehlende Synapse-profiles-Zeile
Datum: 2026-08-11 · Beteiligt: sorb + Mac-Session · Stack: Synapse,
MAS, Authentik, Element Web / Element Call, MatrixRTC (K3s-Cluster)
Auftrag: @apo kann sich anmelden und schreiben, aber kein Call kommt
zustande — Grundursache finden und beheben, ohne weiter zu raten.
1. Ergebnis
Behoben und verifiziert:
@apotelefoniert wieder. Grundursache belegt: dem Konto fehlte die Zeile in Synapsesprofiles-Tabelle. Fix war ein einzelnesINSERTder Registrierungs-Default-Zeile, an zwei gesunden Konten (clark,calltest01) gegengeprüft.- Gegenprobe nach dem Fix:
displaynamegesetzt (vorher keine Zeile),open_id_tokens0 → 6, aktivesorg.matrix.msc3401.call.memberim Raum. - Dokumentiert: Runbook
docs/troubleshooting/CALLS-FEHLEN-PROFILE-ZEILE.mdim gitops-Repo (inkl. Index-Eintrag), Merksatz im Session-Gedächtnis.
Nebenbefund, separat behoben:
- Kontoübernahme-Lücke: Der MAS-Upstream-Provider stand auf
claims_imports.localpart.on_conflict: add— bei Localpart-Kollision verknüpfte MAS die neue Upstream-Identität mit einem bestehenden Konto (inkl. Dienstkonten ohne Upstream-Link). Aufon_conflict: failumgestellt (gitopsef04d86, nach git.lab gepusht), dokumentiert als gitops#61,priority:high. Ausgelöst durch die live reproduzierte case-sensitive Dubletteboje/Boje; das Zweitkontoboje(Authentik-ID 11) wurde gelöscht. Deployment verifiziert: Das SOPS-Values-Secret aktualisierte Flux, aber MAS lief noch mit der alten Config im Speicher (Pod älter als die Änderung) — erst einrollout restartmachtefailaktiv. „Committet" ≠ „deployed" ≠ „aktiv".
2. Die Kausalkette (belegt, nicht vermutet)
| Glied | Beleg |
|---|---|
@apo hat keine profiles-Zeile |
SELECT count(*) … = 0, während clark/sorb/calltest01 je eine haben |
| Displayname-Setzen crasht | PUT …/displayname → 500, TypeError: 'NoneType' object is not subscriptable in _check_profile_size (storage/databases/main/profile.py:354) — txn.fetchone() liefert None, row[0] fliegt |
| kein Displayname → Widget-Init bricht ab | Call-Klick erzeugte null Server-Aktivität: kein openid/request_token, kein call.member; Browser-Log damals „Messaging present but not yet started" (iframe meldet nie ContentLoaded) |
| kein Widget → kein Token → keine SFU | @apo als einziger aktiver Nutzer mit 0 Einträgen in open_id_tokens (die nicht geprunt werden) |
Herkunft der fehlenden Zeile: @apo ist ein Vor-Authentik-Konto, das durch
sechs Identitäts-Resets ging. Deaktivieren löscht in Synapse das Profil,
Reaktivieren legt es nicht neu an. frank (noch älter, nie zurückgesetzt) behielt
seine Zeile. Ob einer der früheren manuellen Eingriffe der auslösende Reset war,
ist nicht mehr zweifelsfrei zu klären — die Zeile ist jetzt wieder da.
3. Was ausgeschlossen wurde (gemessen)
| Verdacht | Warum entkräftet |
|---|---|
| Krypto / Cross-Signing (18 Pseudo-Geräte aus 6 Resets) | Testraum ist unverschlüsselt → Call braucht keine Krypto; clark telefoniert mit ebenfalls zurückgesetzten Schlüsseln |
| Server-Call-Pfad (SFU, RTC-Auth, OpenID-Endpoint) | calltest01/sorb bekommen sauber 200 auf openid/request_token und die Federation-Auflösung |
@apos Token / Session |
/sync läuft durchgehend mit 200, Messaging intakt |
| Login-Verknüpfung MAS↔Authentik | subject = Authentik-uid 2fafe38b…, korrekt |
4. Was zur Lösung geführt hat
- Der Sprung von „welcher Nutzer telefoniert nicht" zu „welche Tabelle ist
anders". Der Durchbruch war die
open_id_tokens-Abfrage über alle aktiven Nutzer:@apo= 0, alle anderen zweistellig+. Ein Vergleich statt einer Einzelbetrachtung. - Ein unverschlüsselter Testraum hat das größte Ablenkungsfeld (Cross-Signing) in einem Schritt geschlossen.
- Der Live-Mitschnitt beim echten Call-Klick zeigte die Abwesenheit jeder Aktivität — nicht ein Fehler, sondern nichts war der Befund.
- Der Nutzer-Hinweis „Anzeigename konnte nicht gesetzt werden" lieferte den 500er mit vollständigem Stacktrace — die letzte Meile von Korrelation zu Ursache.
- Der entscheidende Kontext kam von sorb: „
apoist ein Alt-Konto von vor der Authentik-Integration." Das lenkte die Suche von „angesammelter Müll" auf „Migrations-/Provisionierungs-Lücke".
5. Lehren für die Zukunft
- Bei Call-Problemen zuerst
open_id_tokensje Nutzer vergleichen. 0 bei einem sonst aktiven Konto ist das schnellste, eindeutigste Alarmsignal und trennt Client- von Server-Ursache in einer Abfrage. - Immer im unverschlüsselten Raum reproduzieren, bevor man Krypto verdächtigt. Das schließt einen ganzen Ursachenblock kostenlos aus.
- „Nichts passiert" ist ein Messergebnis, kein Sackgassen-Signal. Die
Abwesenheit eines
openid-Aufrufs hat den Fehler lokalisiert, nicht ein Fehlercode. - Alt-/mehrfach-zurückgesetzte Konten gegen frisch provisionierte diffen,
nicht nur gegen die Erwartung. Der Unterschied war eine fehlende Zeile —
sichtbar nur im direkten Vergleich mit
clark/calltest01. - Jeder DB-Schreib strukturiert: betroffene Zeile vorher anzeigen, an einem
gesunden Konto gegenprüfen, per
INSERT … ON CONFLICT DO NOTHINGstatt Überschreiben. Das ist die direkte Konsequenz aus den früheren unstrukturierten MAS-Eingriffen dieses Vorgangs — und diesmal eingehalten. - Beiläufige Symptome ernst nehmen: die Dublette
boje/Bojebeim Testkonto-Anlegen war der Faden, der die Kontoübernahme-Lücke (gitops#61) aufdeckte — ein Sicherheitsfund, der ohne den@apo-Vorgang unentdeckt geblieben wäre.
6. Offen / Folgetodos
- gitops#61 (
on_conflict-Härtung) ist gepusht und rollt über Flux; der case-insensitive Eindeutigkeits-Check immatrix-invitation-Prompt-Stage (damit der Nutzer schon bei der Registrierung statt erst beim Login scheitert) ist dort als bewusst offener Rest vermerkt. - Verwaiste Altlasten bei
@apo(10local_notification_settingsfür längst gelöschte Geräte, 18 Cross-Signing-Pseudoeinträge) sind kosmetisch und wurden bewusst nicht angefasst — sie haben mit dem Call-Problem nichts zu tun, und ein weiterer Eingriff widerspräche der Lehre oben.