Volver a la wiki

Servicio: Watchdog de monitoreo post-swap del auto-update

Resumen

Módulo: terminal/agent/core/updater.py
Función pública: _launch_swap_watchdog(target: str) -> None
Versión agente: 2.13.3+ (funcional); 2.11.4–2.13.2 (presente pero inoperante hasta la corrección)

El watchdog es un proceso hijo desacoplado que monitorea la integridad de un auto-update del Agente Local post-swap. Se lanza cuando el updater reemplaza el binario del Agente y está a punto de hacer os._exit(0) para ceder control a la nueva versión.

Ciclo de vida:

  1. Lanzamiento: El updater ejecuta _launch_swap_watchdog(target_version) con flags que permiten sobrevivir al padre.
  2. Monitoreo: El watchdog espera 30 segundos (DEFAULT_SWAP_WATCHDOG_DELAY) y realiza healthcheck (GET /health en localhost:9999).
  3. Acción correctiva:
    • ✅ Healthcheck OK → Versión nueva viva, misión cumplida.
    • ❌ Healthcheck falla → Versión nueva muerta (AV bloqueó arranque, corrupción, etc.).
      • Intenta relanzar: os.execv(new_exe, [new_exe, '--swap-retry', ...])
      • Si sigue fallando → revierte al binario anterior.

Firma de la función

def _launch_swap_watchdog(target: str) -> None:
    """Lanza un script PowerShell desacoplado que monitorea el swap post-actualización.
    
    Args:
        target: Versión destino del Agente (ej. "2.13.3"), usada en traza y naming.
    
    Comportamiento:
    - Genera un script .ps1 temporal con la lógica de healthcheck.
    - Lo ejecuta con subprocess.Popen() con flags que permiten sobrevivir al padre.
    - Retorna inmediatamente (el proceso hijo corre de fondo).
    - Registra el PID en update_watchdog.log para auditoría.
    
    Excepciones:
    - FileNotFoundError: Si powershell.exe no está disponible.
    - OSError: Error al escribir el script .ps1 o al ejecutar Popen.
    """

Componentes internos

1. Generación del script PowerShell (ps1)

Ubicación: Archivo temporal bajo AGENT_LOG_DIR (típicamente C:\Users\<user>\AppData\Roaming\CreaRack Pro\agent\).

Contenido del script:

Por qué PowerShell:

2. Lanzamiento con subprocess.Popen()

Flags de creación (a partir de 2.13.3):

creationflags=subprocess.CREATE_NEW_PROCESS_GROUP | getattr(subprocess, "CREATE_NO_WINDOW", 0),
stdin=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
close_fds=True,

Por qué estos flags:

Sin DETACHED_PROCESS: Aunque parezca contradictorio, no es necesario; CREATE_NEW_PROCESS_GROUP ya desacopla. Usarlo causaba conflicto semántico y mataba el proceso silenciosamente (incidentes 03-07 y 05-07).

3. Traza en update_watchdog.log

Ubicación: AGENT_LOG_DIR / "update_watchdog.log"

Registros que deja el updater (antes de lanzar):

[2026-07-05 12:56:00] Swap a v2.13.3: watchdog lanzado (pid 5432, powershell)

Registros que escribe el watchdog (desde el script .ps1):

[2026-07-05 12:56:00] Watchdog iniciado, versión destino: 2.13.3
[2026-07-05 12:56:30] Healthcheck OK, Agente v2.13.3 en ejecución
[2026-07-05 12:56:30] Misión cumplida, saliendo.

O en caso de fallo:

[2026-07-05 12:56:00] Watchdog iniciado, versión destino: 2.13.3
[2026-07-05 12:56:30] Healthcheck FALLÓ (AV bloqueó el arranque?), reintentando...
[2026-07-05 12:56:35] Reintento 1: ejecutando agent.exe --swap-retry
[2026-07-05 12:56:45] Healthcheck OK, Agente v2.13.3 vivo

O revertiendo:

[2026-07-05 12:56:00] Watchdog iniciado, versión destino: 2.13.3
[2026-07-05 12:56:30] Healthcheck FALLÓ
[2026-07-05 12:56:35] Reintento 1: FALLÓ
[2026-07-05 12:56:41] Reintento 2: FALLÓ (archivos corruptos?), revirtiendo a v2.13.2
[2026-07-05 12:56:45] Swap revertido, Agente v2.13.2 relanzado

Dependencias

DependenciaFuenteUso
subprocess (stdlib)Python builtinLanzamiento de PowerShell
pathlib.Path (stdlib)Python builtinUbicación de script .ps1, binary, etc.
logging (stdlib)Python builtinEscritura en update_watchdog.log
PowerShell.exeWindows system (C:\Windows\System32)Intérprete del script
localhost:9999/healthAgent HTTP APIHealthcheck (endpoint de monitoreo)

Historial de cambios

VersiónEstadoNota
2.11.4✅ IntroducciónPrimer watchdog (agent-robustez F2).
2.11.5–2.13.2❌ InoperanteFlags incorrectos (DETACHED_PROCESS) mataban el script silenciosamente.
2.13.1📊 Traza añadidaSe introdujo update_watchdog.log (evidencia del problema).
2.13.3✅ CorregidoEliminado DETACHED_PROCESS, añadido DEVNULL en handles.

Casos de uso

Caso 1: AV bloquea el arranque de la versión nueva

  1. Updater lanza swap (reemplaza binary, hace os._exit(0)).
  2. Watchdog sobrevive, espera 30s.
  3. Versión nueva (2.13.3) arranca pero AV mata agent.exe al extraer el onefile (sin reputación).
  4. Healthcheck falla → watchdog ejecuta agent.exe --swap-retry.
  5. AV deja pasar el reintento (historial) → Agente vivo.

Caso 2: Binario corrupto

  1. Updater descarga versión nueva, swap aplicado.
  2. Versión nueva arranca pero falla al inicializar módulos (import error).
  3. Healthcheck falla repetidamente.
  4. Tras N reintentos → watchdog revierte al binario anterior.
  5. Usuario ve: Agente sigue vivo en v2.13.2 (sin experiencia degradada).

Caso 3: Actualización exitosa

  1. Updater lanza swap correctamente.
  2. Versión nueva (2.13.3) arranca sin problemas.
  3. Healthcheck OK a los 30s.
  4. Watchdog registra éxito y termina.

Restricciones y limitaciones

Windows-only

No hay timeout global en Python

Caso de fallo silencioso (hasta 2.13.2)


Véase también

Subir