isGermanStream wertete die Titel-Regex /\b(german|deutsch)\b/ fuer JEDEN nicht
deutsch-getaggten Audiostream aus — also auch fuer eine bereits anderssprachig
getaggte Spur (z.B. {language:"eng", title:"German Commentary"}). Der Kommentar
ueber dem Titel-Fallback sagt ausdruecklich, er sei "used when the language tag
is missing", aber genau diese Gating-Bedingung fehlte.
Folge: pickAudioTrack (der EINZIGE Caller) nimmt den ersten isGermanStream-
Treffer. Lag eine eng-Spur mit "German"/"Deutsch" im Titel VOR der korrekt mit
"ger" getaggten Spur, gewann die englische Spur. Der Remux behielt dann Englisch,
verwarf die echte deutsche Spur, ersetzte das Original atomar in-place und
strippte den .DL.-Marker — irreversibler Datenverlust mit falscher Sprache, vom
System als Erfolg ("german-tag"/"remuxed") gemeldet. Single-Trigger, kein
compound-Vorbedingung. Betrifft genau die vom Nutzer bestaetigte Tonspur-Funktion.
Fix: Titel-Fallback nur noch ausfuehren, wenn KEIN Sprach-Tag vorhanden ist
(`if (lang) return false;` vor der Titel-Pruefung) — deckt sich exakt mit der
dokumentierten Absicht des bestehenden Kommentars. Korrekt getaggte deutsche
Spuren gewinnen jetzt immer; eine anderssprachige Spur mit "German" im Titel wird
nicht mehr faelschlich gewaehlt. Untagged-Spuren nutzen weiter den Titel-Fallback
(unveraendert), und der German-Release-Mislabel-Pfad (German-first-Konvention)
greift weiterhin.
Runde-7-Audit (adversarisch verifiziert) hat ausserdem den deferred-Extraction-
Cluster abgeschlossen: #10 CRC-Kleindatei-Delete und #12 7z-Exit-1-als-Erfolg sind
BENIGN, #11 resume-empty-output not-confirmed (compound), #13 = das dokumentierte
LOW Companion-Overwrite (PP-1, compound, nur Sekundaerdateien).
Rot-bewiesen: zwei reine pickAudioTrack-Tests (eng-Titel-"German" vor echter ger →
audioRelIndex 1; eng-Titel-"Deutsch entfernt" ohne echte dt. Spur → skip) failen
ohne den Gate. Volle Suite 884 gruen, tsc unveraendert.
104 lines
6.3 KiB
Markdown
104 lines
6.3 KiB
Markdown
# Offene Entscheidungen für dich (Audit-Loop 2026-06-17)
|
|
|
|
Diese zwei Punkte habe ich BEWUSST nicht autonom „gefixt", weil jede Lösung
|
|
einen Produkt-/Geschmacks-Kompromiss enthält, den du entscheiden solltest, nicht ich.
|
|
Beide sind verifiziert (Code-Zitat + Szenario), nur die Richtung ist deine Wahl.
|
|
|
|
---
|
|
|
|
## 1. Failover-Kappung durch globalen 60-Sekunden-Timeout (HIGH)
|
|
|
|
**Was passiert (belegt):**
|
|
`download-manager.ts` baut EINEN Timeout fürs gesamte Unrestrict:
|
|
```
|
|
const unrestrictTimeoutSignal = AbortSignal.timeout(getUnrestrictTimeoutMs()); // 60s
|
|
const unrestrictedSignal = AbortSignal.any([active.abortController.signal, unrestrictTimeoutSignal]);
|
|
```
|
|
Dieses EINE Signal geht an die komplette Provider-Kette in `debrid.ts`. Die 60s sind
|
|
also ein Budget für ALLE Provider zusammen, nicht pro Provider. Wenn Provider 1
|
|
(z.B. Mega-Web mit Account-Queue) das Budget verbraucht, dann sieht Provider 2 ein
|
|
bereits abgelaufenes Signal → `debrid.ts` wertet den Abbruch als „kein Failover" und
|
|
wirft, ohne Provider 2 echt zu versuchen.
|
|
|
|
**Aktuell weitgehend latent:** Seit v1.7.214 wird die API zuerst probiert (schneller Pfad),
|
|
Mega-Web ist nur noch Fallback. Das Szenario „langsamer Provider 1 hungert Provider 2 aus"
|
|
trifft in der Produktion derzeit selten. Deshalb dokumentiert statt dringend gefixt.
|
|
|
|
**Deine Entscheidung — zwei Richtungen (gleiche Spannung, andere Seite):**
|
|
|
|
- **A) Pro-Provider-Timeout:** Jeder Provider bekommt sein eigenes frisches Budget.
|
|
Failover bekommt IMMER einen echten Versuch.
|
|
*Kosten:* Worst-Case-Wartezeit pro Item steigt. Das Budget ist dabei ein DREHregler, kein
|
|
fixer Wert: 60s/Provider = bis 180s Worst-Case (3 Provider), 30s/Provider = bis 90s usw.
|
|
Du akzeptierst langsameres Worst-Case-pro-Item für vollständigeres Failover — und stellst
|
|
über den Pro-Provider-Wert ein, wie viel langsamer.
|
|
|
|
- **B) Globales Budget behalten, aber Slice für Failover reservieren:** Provider 1 wird auf
|
|
z.B. 35s gedeckelt, damit garantiert Zeit für Provider 2 bleibt.
|
|
*Kosten:* Ein legitim langsamer Provider 1 (Mega-Web-Account-Queue bis ~90s) wird früher
|
|
abgeschnitten → mehr Failover, auch wenn Provider 1 noch erfolgreich gewesen wäre.
|
|
|
|
Kernfrage, die nur du beantworten kannst: **Wie lange darf ein Item bei einem langsamen
|
|
aber funktionierenden Provider hängen, bevor wir ihn zugunsten des nächsten aufgeben?**
|
|
|
|
---
|
|
|
|
## 2. Gespiegelter Mega API/Web-Schalter (HIGH, in Runde 3 als 2/3 bestätigt)
|
|
|
|
**Was passiert (belegt):** Die Mega-Debrid API- und Web-Account-Zeilen teilen sich EINE
|
|
login-only Enable-Flag (`hasMegaDebridCredentials` gilt für beide; die Pro-Modus-Auswahl
|
|
läuft über `isMegaDebridModeEnabled(settings, "api"|"web")`). Dein Report: „API ausschalten
|
|
schaltet Web an" — weil der Schalter sich spiegelt.
|
|
|
|
**Warum ich es NICHT autonom geändert habe:**
|
|
- Daten-Modell-Fix (echte unabhängige Flags) braucht eine Settings-Migration, die
|
|
deaktivierte Accounts versehentlich re-aktivieren könnte.
|
|
- Die saubere UI-Variante (zwei echte unabhängige Schalter) ist ein Layout-Redesign — und
|
|
du bist UI-Geschmack-sensibel; das will ich nicht ungefragt umbauen.
|
|
|
|
**Deine Entscheidung:** Ein gemeinsamer Schalter (API+Web zusammen an/aus, klar beschriftet)
|
|
ODER zwei unabhängige Pro-Modus-Schalter (mehr Kontrolle, aber UI + Migration nötig)?
|
|
|
|
---
|
|
|
|
## Erledigt in dieser Runde (zur Info, kein Handlungsbedarf)
|
|
|
|
- **Deutsche Tonspur: falsche Spur-Auswahl behoben (Datenverlust-Schutz):** Die Erkennung der
|
|
deutschen Tonspur hat den Titel-Text einer Spur („...German...") auch dann ausgewertet, wenn die
|
|
Spur bereits ein anderssprachiges Tag hatte (z.B. eine englische Spur mit „German" im Titel, wie
|
|
„German Commentary"). Lag so eine Spur VOR der korrekt mit „ger" getaggten Spur, wurde die falsche
|
|
(englische) behalten und die echte deutsche Spur beim Remux unwiderruflich verworfen — das Ergebnis
|
|
wurde als Erfolg gemeldet. Jetzt wird der Titel nur noch dann herangezogen, wenn gar kein Sprach-Tag
|
|
vorhanden ist (so war es ohnehin gemeint). Korrekt getaggte deutsche Spuren gewinnen jetzt immer.
|
|
Rot-bewiesener Test. (Noch nicht released — wird mit der nächsten Runde gebündelt.)
|
|
|
|
|
|
- **Endlos-Wiederholung bei festem Wiederholungslimit behoben:** Wenn du ein FESTES Retry-Limit
|
|
(z.B. 5) eingestellt hattest UND ein Link sprunghaft verschiedene Fehlerarten produzierte
|
|
(mal Umwandlungs-Timeout, mal Abbruch mitten im Download, mal allgemeiner Fehler), konnte ein
|
|
Eintrag in einer Endlosschleife hängen: eine interne „Viele-Fehler"-Pause halbierte die Zähler,
|
|
sodass das eingestellte Limit nie erreicht wurde — der Eintrag scheiterte nie, blockierte dauerhaft
|
|
einen Download-Slot und hämmerte den Anbieter (weil dabei auch die Anbieter-Sperre zurückgesetzt
|
|
wurde). Jetzt wird das von dir eingestellte Limit hart eingehalten: nach N Versuchen scheitert der
|
|
Eintrag sauber. Standard-Einstellung („unendlich", der Auslieferungs-Default) war nie betroffen.
|
|
Rot-bewiesener Test.
|
|
|
|
|
|
- **Mega „bis Tagesreset gesperrt" parkt jetzt wirklich (statt alle 2 min neu zu versuchen):**
|
|
Wenn ALLE Mega-Accounts wegen wiederholt leerer Antworten bis zum Tagesreset geparkt waren,
|
|
hat das Tool den Fehler bisher als normalen Umwandlungsfehler behandelt und den ganzen Tag
|
|
alle ~2 Minuten neu probiert (und dabei den Provider-Circuit-Breaker mit Fehlern vollgemüllt).
|
|
Jetzt erkennt es den Park und legt das Paket EINMAL bis zum Tagesreset schlafen — genau das,
|
|
was der „bis Tagesreset"-Park eigentlich erreichen sollte. Bei Standard-Einstellungen heilte
|
|
sich das vorher schon um Mitternacht selbst (kein Datenverlust), war aber unnötige Log-Flut
|
|
und Churn. Rot-bewiesener Test.
|
|
|
|
|
|
- **MED Failover-Routing:** Wenn ein Provider in den Manager-Cooldown läuft (≥20 Fehler in
|
|
Folge) und auto-Fallback an ist, hat der Manager bisher zwar einen Ersatz-Provider berechnet,
|
|
ihn aber WEGGEWORFEN — die Kette führte trotzdem wieder mit dem ausgebremsten Provider an.
|
|
Jetzt wird der Ersatz-Provider als „Lead" durchgereicht und die Kette führt mit ihm an, OHNE
|
|
einen Provider zu verlieren (der ausgebremste bleibt als letzter Notnagel in der Kette).
|
|
Greift nur, wenn der Provider bereits nachweislich degradiert ist → strikt-besser-wenn-aktiv,
|
|
kein Timeout/Cancel-Vertrag berührt. Rot-bewiesener Test. (Hält für Roll-up-Release bereit.)
|