findFallbackProviderNotInCooldown-Charakterisierungstest sichert den Invariant
ab, auf dem der Routing-Fix (986fbab) seine Sicherheit aufbaut: bei kein
Cooldown den ersten Provider, bei einem Cooldown den naechsten gesunden, und
NULL erst wenn ALLE Provider im Cooldown sind. Dieses null ist der Punkt, an
dem der Aufrufer queueRetry statt Reorder macht — wuerde der Helper hier je
einen abgekuehlten Provider als letzten Notnagel zurueckgeben, liefe der
Reorder am Sicherheitsnetz vorbei. Der Test friert das ein.
Zusaetzlich: entscheidungen-offen.md praezisiert, dass Option A des Failover-
Timeouts ein Drehregler ueber den Pro-Provider-Wert ist (30s/90s, 60s/180s),
kein fixer Wert.
Wenn ein Provider in den Manager-Cooldown laeuft (>=20 Fehler in Folge) und
auto-Fallback aktiv ist, berechnete der Manager zwar einen Ersatz-Provider
(findFallbackProviderNotInCooldown), warf ihn dann aber weg: der unrestrictLink-
Aufruf bekam keinen Hint, also baute debrid.ts die Provider-Kette frisch aus
providerOrder und fuehrte erneut mit dem ausgebremsten Provider 1 an — ein meist
in den 60s-Timeout laufender, verschwendeter Versuch, bevor ueberhaupt der
gesunde Provider drankam.
Jetzt wird der Ersatz-Provider als bevorzugter Lead durchgereicht. Die Kette
wird UMSORTIERT, nicht beschnitten: der ausgebremste Provider bleibt als letzter
Notnagel in der Reihenfolge, sodass kein Link gestrandet werden kann. Sind ALLE
Provider im Cooldown, erreicht der Aufruf unrestrictLink ohnehin nicht (der
else-Zweig queued einen Retry). Greift damit nur, wenn ein Provider bereits
nachweislich degradiert ist — strikt besser, wenn aktiv, und ohne Timeout-,
Cancel- oder Budget-Vertrag anzufassen.
- debrid.ts: reine leadProviderChainWith(order, preferred) (export) + optionaler
4. Param preferredLeadProvider an unrestrictLink; Reorder direkt nach Aufbau
der Reihenfolge.
- download-manager.ts: Ersatz-Provider in preferredLeadProvider festhalten und
an den unrestrictLink-Aufruf durchreichen.
- Tests: Integration (ohne Hint fuehrt realdebrid, mit Hint fuehrt debridlink) +
drei reine Helper-Tests fuer die No-Stranding-Invariante.
Zwei verbleibende HIGH-Punkte sind bewusst NICHT autonom geaendert, sondern als
Produkt-/UI-Entscheidung in tasks/entscheidungen-offen.md vorgelegt (globaler
60s-Failover-Timeout; gespiegelter Mega API/Web-Schalter).