real-debrid-downloader/tasks/audit-loop.md
Sucukdeluxe 3bd6e3b23e Härtung Download/Rotation (Audit-Batch 1): Scheduler-Freeze, Cooldown-Respekt, Daily-Reset, Kategorisierung
Aus einem adversarisch verifizierten Multi-Agent-Audit (14 confirmed/11 refuted):

#1 HIGH Scheduler-Freeze: findNextQueuedItem hatte keinen activeTasks-Guard.
Wird ein Item zurueckgesetzt/ueberschrieben, waehrend sein alter Task noch in
einem nicht-abbrechbaren await parkt (z.B. Integritaets-Check), liefert
findNextQueuedItem dasselbe Item, startItem lehnt es ab ohne activeTasks zu
verkleinern → der SYNCHRONE Admission-Loop dreht endlos → Event-Loop friert
permanent ein. Fix: `if (this.activeTasks.has(itemId)) continue;`. Repro-Test
(ohne Fix haengt sogar der vitest-Timeout — Freeze bewiesen).

#2/#3 MED mega_debrid_cooldown:<ms> wurde verworfen: kein Parser (nur das
debrid_link-Analogon) → Item lief in den generischen 5s-Exponential-Backoff
und fragte cooled Accounts im Sekundentakt erneut an. Neuer
parseMegaDebridCooldownRetry (nimmt das frueheste Cooldown-Ende ueber alle
Accounts) + Handler VOR transient/generic → Item wartet die echte Cooldown-Zeit.

#7/#8 MED Mega per-Account Tages-Usage wurde am Tageswechsel nie zurueckgesetzt
(ensureProviderDailyUsageFresh ruecksetzte nur provider/debrid-link), und weil
es den Tagesschluessel zuerst weiterstellte, lief auch der Reset in
addMegaDebridAccountDailyUsageBytes ins Leere → Accounts blieben den ganzen Tag
faelschlich "am Limit" und schrumpften das (neue) Pro-Account-Umwandlungslimit.
Fix: megaDebridAccountDailyUsageBytes im Tageswechsel mit zuruecksetzen.

#14 LOW classifyAccountFailure: rate_limit-Branch vor quota (quota matchte
"limit" in "rate limit" → Fehl-Kategorisierung).

852/852 gruen, tsc unveraendert (6). #4 (empty→until-restart) bewusst deferred.
2026-06-17 04:22:20 +02:00

5.3 KiB

Autonomer Audit-Loop — Download/Fehler/Rotation (Goal 2026-06-17, 8h)

Disziplin: erst BELEGEN (Code-Zitat + konkretes Szenario), dann adversarisch verifizieren, dann TDD-Fix. Kein Blind-Fix. Tests gruen + tsc=6 nach jeder Runde. Periodisch releasen.

Runde 1 (laeuft)

  • Discover+Verify-Workflow ueber 7 Subsysteme (scheduler-slots, unrestrict-retry, mega-rotation, classify-cooldown, mega-web-token, provider-chain-timeout, account-availability).

Meine unabhaengigen Verdachtsfaelle (Cross-Check gegen Workflow)

  1. Web-Selbst-Cooldown (Analog zum API-214-Bug, HOCH): Caller-Timeout = 60s (DEFAULT_UNRESTRICT_TIMEOUT_MS, download-manager 114) umschliesst die GANZE Kette. Mega-Web braucht legitim laenger (per-Account-Queue bis 90s + Login + Generate). Feuert die 60s nach >=8s (MEGA_DEBRID_ABORT_MIN_RUN_MS_DEFAULT=8000), setzt die Rotation aborted:debrid → 120s Account-Cooldown (debrid.ts ~2037-2048), obwohl der Account GESUND ist — die App hat aufgegeben. → Kaskade ueber Accounts. Live im jf.zip belegt: Mega-Debrid Web | TIMEOUT_COOLDOWN | reason=aborted:debrid | cooldownSec=120. Fix-Kandidat: (a) per-Provider-Timeout statt globaler 60s; und/oder (b) Caller-Timeout- Abort NICHT als Account-Cooldown werten (EMA-Demotion regelt langsame Accounts bereits), oder nur sehr kurz.
  2. Globaler 60s-Timeout kappt Failover (Advisor-bewiesen, HOCH): download-manager 8759 AbortSignal.any([cancel, timeout]) → bei Provider1-Verbrauch des Budgets abortet das Signal → debrid.ts 3805 signal.aborted → throw, kein nextProvider. Fix: per-Provider- AbortSignal.timeout, Stop nur bei USER-Cancel.
  3. Exponential-Backoff bis 120s (generic unrestrict retry) — Item sitzt bis 2 min. Pruefen ob fuer haeufige transiente Faelle zu lang.

Bestaetigte Bugs (Workflow R1: 14 confirmed / 11 refuted) — priorisiert

  • [IN ARBEIT] #1 HIGH Scheduler-Freeze: findNextQueuedItem ohne activeTasks-Guard → synchroner Admission-Loop dreht endlos wenn ein reset/overwrite-Item noch im activeTasks parkt (non-abort- observing await, z.B. Integrity-Check). Fix: if (this.activeTasks.has(itemId)) continue;. TDD-Test (Freeze-Repro mit non-abort Mock + resetItems) geschrieben.
  • #2/#3 MED mega_debrid_cooldown: Delay verworfen — kein Parser (nur debrid_link_cooldown). Fix: Parser fuer beide Praefixe, queueRetry mit echtem delayMs. (Erklaert Rapid-Retry-trotz-Cooldown im jf.zip.)
  • #7/#8 MED Mega per-Account Daily-Usage wird am Tagesgrenze NIE resettet → Accounts faelschlich "am Limit" → schrumpft MEIN neues serialized-limit. Fix: megaDebridAccountDailyUsageBytes in ensureProviderDailyUsageFresh resetten.
  • #4 MED transiente leere Web-Antwort → permanenter until-restart-Park (limitSignal vom generischen "antwort leer"). Fix: limitSignal nur vom echten Daily-Limit (NO_SERVER_RE).
  • #5 MED Web echte Bad-Credentials erreichen invalid-Branch nicht (werden ewig retried). Fix: echte Web-Login-Fehlerphrasen in invalid-Branch.
  • #6 MED onefichier/ddownload-Routing ignoriert autoProviderFallback=off. Fix: Guard in catch.
  • #14 LOW Regex-Ordering classify: quota-Branch shadowt rate_limit. Fix: rate_limit vor quota.
  • #9 LOW overwrite wipet frisch geclaimten targetPath via altem .finally.
  • #10 LOW HTTP416 shared counter mit genericErrorRetries.
  • #11 LOW fresh-retry preempt typed transient handlers.
  • #12 LOW 15-failure-shelve + shared counters → mehr Retries als retryLimit.
  • #13 LOW self-poison: queue-wait zaehlt zu elapsedMs → abort-cooldown (Analog zu meinem Web-Verdacht #1).

Refutiert / Nicht-Bug (11) — nicht anfassen

providerStartReservations dead-state; debrid_link_cooldown cleanup; supprimé-fallthrough; mega-web 180s aborts whole rotation; EMA-removed-premise; quota-no-park asymmetry; connectApi single-flight cancel-couple; per-account queue chain-break (NON-BUG); mega-web slot-hold (NON-BUG); provider abort-vs-timeout heuristic; daily-limit aggregate early-exit.

Fixes (TDD, mit Test + Release)

Batch 1 → v1.7.215 (Suite laeuft)

  • #1 HIGH Scheduler-Freeze: findNextQueuedItem activeTasks-Guard. Repro-Test (ohne Fix haengt der Event-Loop so hart, dass nicht mal vitest-Timeout feuert = Freeze empirisch bewiesen). Mit Fix 288ms.
  • #2/#3 MED parseMegaDebridCooldownRetry (export) + Handler VOR transient/generic branch → Item wartet den ECHTEN Cooldown (min ueber alle Accounts) statt 5s-Busy-Loop. 5 Parser-Tests.
  • #7/#8 MED megaDebridAccountDailyUsageBytes Reset in ensureProviderDailyUsageFresh (laeuft via getSnapshot, also auch im Stall). Test: Tagesgrenze → leer.
  • #14 LOW rate_limit-Branch VOR quota (quota matchte "limit" in "rate limit"). Test: rate_limit-Kategorie.
  • [deferred] #4 empty-response→until-restart-park: 3-consecutive-streak ist reale Mitigation gegen transiente Blips; Mega-empty-Semantik nicht sicher verifizierbar → kein Blind-Change.

Batch 2 (geplant, naechste Runden)

  • Web-Timeout-Selbstcooldown-Familie: #13 elapsedMs inkl. queue-wait → ranLongEnough-Gate auf WORK-Zeit (mega-web traced workMs schon); + 60s-Caller-Timeout vs Web-Queue(90s) Mismatch. Braucht workMs-Threading.
  • #5 Web echte Bad-Creds erreichen invalid nie. #6 onefichier/ddownload routing ignoriert fallback=off.
  • #9 overwrite targetPath-wipe. #10 HTTP416 shared counter. #11 fresh-retry preempt. #12 shelve+shared counter.