{
  "flow_id": "flow_2026-05-09T21-50-45-918Z_ComfortSleep",
  "created_at": "2026-05-09T21:50:45.930691+00:00",
  "input_start": {
    "flow": "escalado_formatos",
    "product": "ComfortSleep",
    "video_url": "https://www.facebook.com/61562217471968/posts/122192975072407249/",
    "country": "ES",
    "saturated": true,
    "source": "html_dashboard",
    "timestamp": "2026-05-09T21:50:45.918Z"
  },
  "sections": {
    "_rescue_descargar": {
      "level_resolved": null,
      "winning_hypothesis": null,
      "initial_break": "EXEC_FAIL · yt-dlp exit_code=1",
      "qc_attempts": [
        {
          "hypothesis": {
            "id": "qc_descargar_1",
            "level": "qc",
            "idea": "yt-dlp está desactualizado y la firma/cipher de la plataforma rompió la extracción",
            "feedback": "Ejecuta primero `python -m pip install -U --pre yt-dlp` (o `yt-dlp -U`) para subir a la última nightly. Luego reintenta la descarga con los mismos parámetros. Si la plataforma es Facebook/IG/TikTok, añade `--extractor-args \"generic:impersonate\"` y `--user-agent` de Chrome reciente para evitar bloqueos por extractor obsoleto."
          },
          "result": "FAIL",
          "detail": "EXEC_FAIL · yt-dlp exit_code=1"
        },
        {
          "hypothesis": {
            "id": "qc_descargar_2",
            "level": "qc",
            "idea": "La URL requiere autenticación/cookies y yt-dlp está intentando bajar un recurso protegido sin sesión",
            "feedback": "Reintenta pasando cookies del navegador con `--cookies-from-browser chrome` (o `--cookies cookies.txt` si hay export). Si sigue fallando, cae al fallback Playwright Chrome CDP:9222 sobre la pestaña ya logueada de Fer, intercepta el `.mp4` blob y guárdalo. NO reintentes yt-dlp sin cookies."
          },
          "result": "FAIL",
          "detail": "EXEC_FAIL · yt-dlp exit_code=1"
        },
        {
          "hypothesis": {
            "id": "qc_descargar_3",
            "level": "qc",
            "idea": "La URL recibida no es un enlace de video directo sino una página wrapper (ads library, share link corto, redirect)",
            "feedback": "Antes de pasar la URL a yt-dlp, resuélvela: `curl -sIL <url>` para seguir redirects y extraer la URL canónica del video, o si es FB Ads Library extrae el `video_hd_url`/`video_sd_url` del JSON embebido vía Playwright. Pásale a yt-dlp SOLO la URL final del .mp4 o el permalink canónico del post, no el share/wrapper."
          },
          "result": "FAIL",
          "detail": "EXEC_FAIL · yt-dlp exit_code=1"
        }
      ],
      "master_attempts": [
        {
          "hypothesis": {
            "id": "master_descargar_1",
            "level": "master",
            "idea": "La URL de entrada es un enlace 'posts' de Facebook (facebook.com/61562217471968/posts/122192975072407249/) que NO es directamente un video — es un post wrapper que contiene un video embebido. yt-dlp necesita la URL canónica del video (fb.watch, /videos/, /watch/?v=, o reel) para extraer. El problema viene de AGUAS ARRIBA: la estación que recolectó la URL del dashboard la guardó como /posts/ sin resolver al video real. La estación DESCARGAR recibe basura del input_start.",
            "feedback": "Fix concreto: añadir un pre-procesador de URL en el supervisor ANTES de DESCARGAR — Playwright con CDP ya logueado abre la URL /posts/, espera al video DOM (video[src] o link[rel=video_src]), extrae la URL canónica del video o el video_id, reconstruye como https://www.facebook.com/watch/?v={video_id}, y SOLO ENTONCES pasa a yt-dlp. Si hay múltiples videos en el post, escoger el primero. Esto resuelve el root cause aguas arriba sin tocar yt-dlp."
          },
          "result": "FAIL",
          "detail": "EXEC_FAIL · yt-dlp exit_code=1"
        },
        {
          "hypothesis": {
            "id": "master_descargar_2",
            "level": "master",
            "idea": "Fallback global a Apify actor 'curious_coder/facebook-ads-library-scraper' o 'pintostudio/facebook-video-downloader' como modo degradado. yt-dlp tiene problemas crónicos con Facebook (rate-limit IP, cipher rotativo, login walls intermitentes) y el flow no debería depender de UNA sola herramienta. El contrato del supervisor asume yt-dlp = source of truth pero Facebook lo rompe semanalmente.",
            "feedback": "Fix concreto: implementar cascada de descargadores en la estación DESCARGAR — (1) yt-dlp con cookies-from-browser=chrome, (2) si exit!=0, intentar fdown.net vía Playwright headless (paste URL → click download → capturar mp4), (3) si falla, getfvid.com mismo patrón, (4) si falla, Apify actor con FB cookies del entorno. Cada intento timeout 60s. Logguear cuál descargador funcionó para alimentar telemetría y rotar el orden por tasa de éxito. El flow nunca debe morir por un solo fallo de yt-dlp."
          },
          "result": "FAIL",
          "detail": "EXEC_FAIL · yt-dlp exit_code=1"
        },
        {
          "hypothesis": {
            "id": "master_descargar_3",
            "level": "master",
            "idea": "Re-arquitectura puntual: la estación DESCARGAR está acoplada a 'descargar mp4' pero el FLOW REAL de escalado_formatos solo necesita TRANSCRIPCIÓN + ANÁLISIS VISUAL del video referente. Si el mp4 no se puede bajar, el flow puede degradar a (a) extraer transcripción del HTML del post si ya viene con captions FB, (b) usar la URL pública de FB directamente con Whisper API que acepta URL remota, (c) screenshot frames vía Playwright sin descargar mp4 completo. El contrato 'mp4 obligatorio' es demasiado rígido.",
            "feedback": "Fix concreto: cambiar contrato de DESCARGAR de 'devuelve mp4_path' a 'devuelve {mp4_path?, transcript?, frames?}' con al menos UNO presente. Si yt-dlp falla, lanzar fallback degradado: Playwright captura HTML+captions del post, screenshots cada 2s del player, y si hay audio extraíble vía MediaSource API lo manda a Whisper local. ANALIZAR estación se adapta a recibir transcript+frames sin mp4. Esto desacopla el flow de la fragilidad de descargar Facebook."
          },
          "result": "FAIL",
          "detail": "EXEC_FAIL · yt-dlp exit_code=1"
        }
      ],
      "fer_pinged": true,
      "ts": "2026-05-09T21:51:49.085125+00:00"
    }
  },
  "history": [
    {
      "ts": "2026-05-09T21:51:49.085125+00:00",
      "actor": "rescue-ladder",
      "section": "_rescue_descargar",
      "mode": "replace",
      "bytes_after": 5114
    }
  ]
}