diff --git a/app/scheduler/source_stats.py b/app/scheduler/source_stats.py index 37fee38..e6efa7f 100644 --- a/app/scheduler/source_stats.py +++ b/app/scheduler/source_stats.py @@ -117,7 +117,16 @@ def _health_score_from_telemetry(attempts: int, successes: int, p50_ttff_ms: int def _overall_stars(freshness: int, richness: int, health: int) -> int: if health == 0: - return 0 # offline gate — nieważne jak świeże/bogate + # Offline gate: health==0 (~0% udanych odtworzeń w telemetrii) zwykle = offline. + # ALE telemetria bywa NIEPEŁNA — część udanych odtworzeń nie wysyła eventu (zweryfikowane + # 2026-07-20: freshporno gra natywnie na realnym telefonie, PlaybackState=PLAYING, ale + # sukces się nie raportuje → sam błąd → fałszywe 0% → fałszywe offline). Więc gdy źródło + # jest EWIDENTNIE żywe (świeże ORAZ bogate ORAZ aktywnie ingestowane), nie chowamy go + # całkiem, tylko floor 2★ "działa, ale telemetria kuleje". Martwe źródła i tak mają + # niski freshness → gate zadziała. Patrz ticket: luka w emisji success eventu (native fallback). + if freshness >= 4 and richness >= 4: + return 2 + return 0 raw = 0.40 * freshness + 0.30 * richness + 0.30 * health return max(1, min(5, round(raw)))