User-Goal: bei kuenftigen Renaming-Problemen eine vollstaendige, sofort auffindbare Uebersicht —
JEDER Umbenenn-/Verschiebevorgang protokolliert UND danach verifiziert (liegt die Datei wirklich
unter dem Zielnamen? Quelle weg? richtige Schreibweise?).
- NEU desktop-rename-log.ts: pro Sitzung <Desktop>/Downloader-Log/rename-session_<ts>.txt; Ordner
selbstheilend (mkdir recursive vor jedem Write -> auch nach Loeschung zur Laufzeit sofort wieder
da). Synchroner Append, Schreibfehler verschluckt (bricht nie einen Download).
- verifyRename (sync) + verifyRenameAsync (Hot-Path): prueft Ziel-Existenz, echten On-Disk-Namen
(case-genau via readdir), Quell-Abwesenheit; Level INFO/WARN/ERROR. Nutzt denselben \?\-Long-
Path-Prefix wie der echte Rename (sonst falsche Urteile auf langen Scene-Pfaden).
- download-manager: renamePathWithExdevFallback = verifizierter Wrapper um die unveraenderte
Raw-Logik (deckt alle Media-Renames ab) + 3 Sync-Sites (startup-Dedup, Deobfuskation, Suffix-Fix)
via logVerifiedRenameSync; logRenameProcess spiegelt ins Desktop-Log.
- app-controller init/shutdown (getPath("desktop") gegen Startup-Crash abgesichert); support-bundle
packt das Log mit ein.
Adversarialer Review-Workflow (4 Linsen) fand + behoben: Long-Path-Verify-Bug (falsches OK
maskiert halb-fertigen Move), readdir-Fehler-False-OK, sync-I/O im Hot-Path, getPath-Guard,
Test-Temp-Cleanup. tsc 9 (Baseline), 663 Tests (+7 neue), Build gruen.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
User-Entscheidung: ein Mega-Debrid-Account am Tageslimit soll bis zum Programm-Neustart
uebersprungen werden, nicht alle 20s/2min neu getestet.
Ground Truth (Support-Bundle gegrept): der limitierte Account liefert im Web-Pfad NIE eine
unterscheidbare Meldung — "Kein Server" = 0 Treffer, "Antwort leer" = 20.861. Tageslimit und
transienter Blip sind auf Message-Ebene nicht trennbar (generate() findet ohne processDebrid-
Code keinen Code -> return null -> "Antwort leer"). Ein Trigger auf "Kein Server" waere toter Code.
Loesung (Verhaltens-Signal statt Wortlaut):
- megaDebridEmptyResponseStreaks zaehlt aufeinanderfolgende "Antwort leer"/"Kein Server"-
Treffer je Account; ab 3 wird der Account bis Neustart geparkt (until=MAX_SAFE_INTEGER,
nur In-Memory -> Neustart loescht). Erfolg/anderer Fehler setzt zurueck.
- classifyAccountFailure markiert beide Signale als limitSignal (Symmetrie: ein einzelner
evtl. transienter Treffer parkt NICHT, behaelt kurzen Cooldown).
- Skip-Branch: "uebersprungen (bis Neustart gesperrt)", traegt nicht zu earliestCooldownUntil
bei (kein absurder Retry-Timer); Post-Loop wirft klare Endmeldung wenn alle geparkt.
- generate() surfacet "Kein Server" zusaetzlich als Page-Error (falls es doch im HTML steht).
- UI: Rotations-Verlauf zeigt "bis Neustart gesperrt".
Verifiziert: tsc 9 (Baseline), 655 Tests + 5 neue (inkl. Wiring-E2E der eine echte leere
Antwort durch unrestrictWithAccounts->classify->catch->Park treibt), Build gruen.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>