# 🟠 Instabiler ErsatzschlĂŒssel: 4.024 Doppel-EintrĂ€ge in `copied` **Kein Datenverlust, keine Dubletten in PostfĂ€chern.** Aber die Buchhaltung stimmt nicht — und beim AufrĂ€umen lauert eine Falle (siehe „⚠ NICHT TUN"). ## Befund ``` Datei-Records: 58.051 ═ mbox_index: 58.051 ✓ (Drift 0) copied: 62.073 ← 4.022 mehr ``` `copied`-Zeilen ohne passenden `mbox_index`-Eintrag: **4.024**, davon **4.021 mit `sha256:`-SchlĂŒssel**. Verteilung exakt auf die Konten mit `--reindex --rebuild`: gb +2533, rb +719, byrne +564, crystal +112, roby +92. (gb hatte gemessen 2.537 Mails ohne Message-ID — passt auf ~4 genau.) ## Ursache Mails **ohne `Message-ID`-Header** bekommen `sha256:` als ErsatzschlĂŒssel. Der Hash wird aber ĂŒber **unterschiedliche Bytes** gebildet: | Pfad | hasht | |---|---| | Migration (`07-migrate.go`) | die **IMAP-Rohbytes** der Mail | | Reindex/Rebuild (`06-mbox.go`) | den **mbox-Record aus der Datei** | Die mbox-Fassung ist nicht byte-gleich mit der IMAP-Fassung: Der Writer setzt `>From `-Quoting und normalisiert Zeilenenden. → **anderer Hash → anderer SchlĂŒssel → dieselbe Mail steht zweimal in `copied`.** Betroffen sind alle **6.623** Mails ohne Message-ID (so viele hat `mbox_index` mit `sha256:`-SchlĂŒssel). ## ⚠ NICHT TUN: die „Waisen" einfach löschen Die 4.024 Waisen sind **nicht** der MĂŒll — sie sind die Zeilen, auf die der **Migrationspfad tatsĂ€chlich matcht** (er rechnet den IMAP-Hash aus). Die vom Rebuild ergĂ€nzten Zeilen (mbox-Hash) sind die redundanten. **Werden die Waisen gelöscht, hĂ€lt die Migration diese 4.021 Mails fĂŒr unkopiert und schreibt sie erneut ins Ziel-Postfach → echte Dubletten in fremden PostfĂ€chern.** Genau der Schaden, den wir vermeiden wollen. Aus demselben Grund darf die **SchlĂŒsselberechnung nicht einfach umgestellt** werden: FĂŒr Konten **ohne** Rebuild (kolmer, palamari, colak, 
) existiert nur der IMAP-Hash. Ein Wechsel auf den mbox-Hash lĂ€sst dort **alle** Message-ID-losen Mails als „neu" erscheinen → Massen-Neukopie. ## Fix (in dieser Reihenfolge, sonst knallt es) 1. **SchlĂŒssel vereinheitlichen:** Der ErsatzschlĂŒssel muss in **beiden** Pfaden ĂŒber **dieselben** Bytes gehen. Sauberste Wahl: ĂŒber die **mbox-normalisierte Fassung** (also das, was tatsĂ€chlich im Archiv steht) — dann liefern Migration und Reindex/Rebuild dauerhaft denselben Wert, auch nach jedem kĂŒnftigen Rebuild. → In `07-migrate.go` den Hash **nach** der mbox-Normalisierung bilden, nicht ĂŒber die IMAP-Rohbytes. 2. **Einmalige `copied`-Migration** (zwingend zusammen mit 1., nicht danach): FĂŒr jedes Konto/Ordner `copied` aus `mbox_index` neu ableiten (`message_id` aus dem Index, `mbox_done=1`), `target_done` aus dem bestehenden Stand ĂŒbernehmen (die Mails **sind** im Ziel — nicht auf 0 zurĂŒcksetzen!). Anschließend die alten IMAP-Hash-Zeilen entfernen. **In einer Transaktion**, mit ZĂ€hlung vorher/nachher. 3. **Abnahme:** `copied` == `mbox_index` (58.051 == 58.051), und der erste Watch-/Migrationslauf danach meldet **`archived=0 target=0 pending=0`** — also keine einzige Neukopie. Meldet er mehr, sofort stoppen: dann matcht der SchlĂŒssel nicht und es entstehen gerade Dubletten. ## Alternativ (wenn 1.+2. zu heikel erscheinen) Zustand **so lassen**. Er ist funktional korrekt: Der Migrationspfad matcht auf die IMAP-Hash-Zeilen, es wird nichts doppelt kopiert (live bestĂ€tigt: `complete=0 archived=0 target=0 pending=0 errors=0`). Kosten: `copied` ist um ~7 % aufgeblĂ€ht und die Zahl taugt nicht als Beleg fĂŒr „so viel ist archiviert". Dann aber **in `INSTALL.md` dokumentieren**, warum die Zahlen auseinandergehen — sonst rĂ€tselt in zwei Jahren jemand daran. ## HĂ€ngt zusammen mit Der noch offenen `body_sha256`-Bereinigung (byte-verschiedene Mails mit gleicher Message-ID, ~109 NachzĂŒgler): Beide drehen sich um „was ist die IdentitĂ€t einer Mail". Am besten **in einem Zug** lösen und **eine** SchlĂŒsselregel festlegen: - Message-ID vorhanden → `message_id` **+ `body_sha256`** (fĂ€ngt die byte-verschiedenen FĂ€lle), - keine Message-ID → nur `body_sha256`, - **`body_sha256` immer ĂŒber die mbox-normalisierte Fassung.**