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>
113 lines
6.5 KiB
Markdown
113 lines
6.5 KiB
Markdown
---
|
|
type: aar
|
|
status: open
|
|
date: 2026-08-11
|
|
related: []
|
|
---
|
|
|
|
# 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:**
|
|
- `@apo` telefoniert wieder. Grundursache belegt: dem Konto fehlte die Zeile in
|
|
Synapses `profiles`-Tabelle. Fix war ein einzelnes `INSERT` der
|
|
Registrierungs-Default-Zeile, an zwei gesunden Konten (`clark`,
|
|
`calltest01`) gegengeprüft.
|
|
- Gegenprobe nach dem Fix: `displayname` gesetzt (vorher keine Zeile),
|
|
`open_id_tokens` **0 → 6**, aktives `org.matrix.msc3401.call.member` im Raum.
|
|
- Dokumentiert: Runbook `docs/troubleshooting/CALLS-FEHLEN-PROFILE-ZEILE.md` im
|
|
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). Auf `on_conflict: fail` umgestellt
|
|
(gitops `ef04d86`, nach git.lab gepusht), dokumentiert als
|
|
[gitops#61](https://git.lab/axion1337.chat/axion1337.chat-gitops/-/issues/61),
|
|
`priority:high`. Ausgelöst durch die live reproduzierte case-sensitive Dublette
|
|
`boje`/`Boje`; das Zweitkonto `boje` (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
|
|
ein `rollout restart` machte `fail` aktiv. „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 |
|
|
| `@apo`s 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:** „`apo` ist 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
|
|
|
|
1. **Bei Call-Problemen zuerst `open_id_tokens` je Nutzer vergleichen.** 0 bei
|
|
einem sonst aktiven Konto ist das schnellste, eindeutigste Alarmsignal und
|
|
trennt Client- von Server-Ursache in einer Abfrage.
|
|
2. **Immer im unverschlüsselten Raum reproduzieren, bevor man Krypto verdächtigt.**
|
|
Das schließt einen ganzen Ursachenblock kostenlos aus.
|
|
3. **„Nichts passiert" ist ein Messergebnis, kein Sackgassen-Signal.** Die
|
|
Abwesenheit eines `openid`-Aufrufs hat den Fehler lokalisiert, nicht ein
|
|
Fehlercode.
|
|
4. **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`.
|
|
5. **Jeder DB-Schreib strukturiert: betroffene Zeile vorher anzeigen, an einem
|
|
gesunden Konto gegenprüfen, per `INSERT … ON CONFLICT DO NOTHING` statt
|
|
Überschreiben.** Das ist die direkte Konsequenz aus den früheren
|
|
unstrukturierten MAS-Eingriffen dieses Vorgangs — und diesmal eingehalten.
|
|
6. **Beiläufige Symptome ernst nehmen:** die Dublette `boje`/`Boje` beim
|
|
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 im `matrix-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` (10 `local_notification_settings` fü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.
|