Lanzador Estable F3 — Auto-update desatendido transparente (onedir + setup stub)
Descripción
Plan F3 del Lanzador Estable es eliminar la carrera del antivirus contra la re-extracción de .pyd nativos en cada arranque del Agente.
Cambios:
- Bootstrap de
--onefile→--onedir(los.pydviven en_internal, sin re-extracción en cada arranque). - Setup stub (
CreaRackAgent-Setup.exe,scripts/agent/setup_stub.py): un onefile stdlib-only que despliega el onedir en%APPDATA%una sola vez. - Rollback silencioso mejorado: si un paquete falla, reintenta y luego cae al embebido.
Problema que resuelve
Raíz del bug pydantic_core / _overlapped
El bootstrap en onefile se re-extrae a un directorio temporal _MEIxxxx en cada arranque. Durante esa extracción:
- Windows Defender (y otros AV) escanean la extracción en tiempo real.
- Un
.pydnativo puede ser bloqueado en ese preciso momento. - El arranque falla con
pydantic_core/_overlapped/_sqlite3.
Síntomas
- No-determinista (depende del timing del AV).
- Afecta a arranques normales (no solo tras update).
- Reintento manual → funciona (AV “soltó” la lib tras el primer intento).
Solución F3
Con --onedir:
- Los
.pydviven en disco (_internal/...) de forma permanente. - Se escanean una sola vez en la instalación.
- El antivirus no tiene nada que morder en posteriores arranques.
- El AV no puede interrumpir una lib que no se está extrayendo.
Arquitectura F3
1. Bootstrap en --onedir
- Compilado con
--onediren lugar de--onefile. - Código en
_internal/→ fijo en disco. - Mucho más pequeño que el onefile (~15-20 MB vs ~35 MB).
2. Setup stub (CreaRackAgent-Setup.exe)
- Otro onefile, pero stdlib-only (solo librerías de Python standard).
- Se ejecuta una sola vez (instalación).
- Funciones:
- Extrae el onedir embebido.
- Despliega en
%APPDATA%\CreaRackAgent. - Configura startup, protocolo
crearack://, toasts. - Lanza el Agente.
- Script:
scripts/agent/setup_stub.py. - Único onefile que queda en la máquina de usuario.
3. Vista de descarga (core/views.download_agent)
- Sirve el instalador (
CreaRackAgent-Setup.exe), no el bootstrap. - El usuario descarga e instala una sola vez (momento supervisado).
4. Agente simplificado
core/installer.pyse simplifica: ya no copia el.exe(roto en onedir).- El bootstrap ya no se auto-instala (el stub lo hace).
- Resultado: Agente onedir siempre corre desde el directorio de instalación (
%APPDATA%\CreaRackAgent).
Validación E2E
Status: Pendiente en VM limpia con Defender real (task #187).
Prueba en vivo (07-07, Agent 2.15.0 beta)
- Dani (onedir): Se actualizó solo, sin ventanas, de 2.15.0 → 2.15.1.
- Edu (onefile viejo, control): Falló con
_sqlite3(AV mordiendo la re-extracción) → reinstalación del onedir → OK. - Conclusión: La contraposición onefile-falla / onedir-funciona es la prueba definitiva del fix.
Notas de implementación
-
Hallazgo 1 (documentado para futuro): El onefile re-extrae
.pyden cada relanzamiento → AV puede morder uno.- Solución:
--onedir(aplicada en F3).
- Solución:
-
Hallazgo 2 (arreglado en 2.14.1): Al transicionar de embebido a primer paquete,
previous.txtvacío → watchdog se perdía.- Solución:
_watchdog_scriptborrador decurrent.txt, caída al embebido (aplicada en feature—agent-lanzador—rollback-silencioso-infalible).
- Solución:
Migración de flota legacy
Antes de tocar el sidecar de versión (que ordena updates):
- Reinstalar con el nuevo instalador (onedir).
- El bootstrap onedir es un binario nuevo (diferente hash que onefile).
- Una máquina sin bootstrap recibiría
url=Setup.exe→ intentaría swap del instalador (inválido).
Plan de flujos
- Instalación fresca: User descarga
CreaRackAgent-Setup.exe→ setup despliega onedir en%APPDATA%→ Agente corre. - Auto-update: Agente descarga paquete → verifica → swap de
current.txt→ relanza. - Rollback: Paquete falla → reintenta → cae al embebido (o
previous.txtsi existe).
Tests nuevos
tests/agent/test_setup_stub.py(+6 casos): extrae exe, preserva datos, reemplaza_internal, lee versión.tests/agent/test_agent_launcher.py(+3 casos): lógica de rollback del watchdog.
Véase también
- [[feature—agent-lanzador—rollback-silencioso-infalible]]
- [[feature—agent-lanzador—paquete-firmado-ed25519]]
- [[feature—agent-lanzador—bootstrap-zip]]
- [[incident—20260707—bootstrap-2-14-0-roto]]
- [[concept—agent-lanzador—cadena-fallback]]