Volver a la wiki

Lanzador Estable del Agente (F1) — auto-update sin tocar el .exe

Resumen

v1.45.14 · Agent 2.14.0 (2026-07-07)

Fase F1 del Plan Lanzador Estable: reingeniería radical de la arquitectura de auto-update del Local Agent. El programa instalado (.exe) pasa a ser un bootstrap inmutable que se instala una sola vez y jamás vuelve a tocar. El código de la aplicación viaja en paquetes firmados (app-X.Y.Z.zip) que el bootstrap descarga, verifica y monta contra una cadena de fallback.

Problema resuelto: la raíz de los 6+ incidentes de actualización fallida (30-06 → 05-07/2026) era la carrera entre:

Resultado: brickazo silencioso o loop de actualización. Solución por construcción: si el binario instalado jamás cambia, el antivirus no tiene nada nuevo que evaluar. El riesgo criptográfico (firma Ed25519 verificada en el propio bootstrap) es incomparable a Authenticode.

Arquitectura

Bootstrap (terminal/agent/main.py)

~220 LOC, instalado una sola vez (versión 2.14.0 + clientes anteriores → migrate).

main.py (bootstrap, verificador Ed25519+SHA-256)
  ├─ Descarga manifest del SaaS
  ├─ Lee puntero atómico: qué versión ejecutar (current / previous / embebida)
  ├─ Verifica sha256 + firma Ed25519 del zip
  ├─ Monta `app_main.py` (y resto del paquete)
  └─ Ejecuta app_main.py con fallback: current → previous → embebida

Clave pública Ed25519 embebida: PACKAGE_PUBKEYS_HEX en main.py (generada por scripts/agent/generate_signing_key.py, fuera del repo).

Paquete de código (app-X.Y.Z.zip)

~0,5 MB por release típica (Python compilado a bytecode), contiene:

NO incluye:

Firma y distribución

  1. scripts/agent/build_app_package.py (invocado por build_agent.bat paso 4.7):

    • Empaqueta el código → app-X.Y.Z.zip
    • Calcula SHA-256
    • Firma con clave privada Ed25519 (~/.crearack/keys/agent_signing_ed25519.pem, FUERA del repo)
    • Emite app-X.Y.Z.meta.json (version, sha256, sig_ed25519, min_bootstrap_api, built_at)
  2. Clave privada: generada una vez por scripts/agent/generate_signing_key.py. FUERA del repo, en ~/.crearack/keys/. Hacer backup cifrado manual. Si se pierden, --rotate genera nueva + actualiza PACKAGE_PUBKEYS_HEX del bootstrap.

  3. Descarga: endpoint GET /downloads/agent-app/<version> (auth idéntica a /downloads/CreaRackAgent.exe).

Actualización en la máquina del cliente

Coordinada por core/pkg_updater.py:

pkg_updater.py (viaja en el paquete, se actualiza a sí mismo)
  ├─ Descarga zip + meta.json del SaaS
  ├─ Verifica con funciones del bootstrap (módulo agent_bootstrap, cero duplicación)
  ├─ Selftest: `--selftest-package` en destino
  ├─ Swap de puntero atómico (en ocio, nunca durante ejecución)
  ├─ pkg-watchdog: rollback de puntero si falla
  └─ Jamás crea un binario nuevo

Fallback garantizado:

Manifest v2 (API)

Campo nuevo en /api/agent/manifest (heartbeat):

{
  "version": "1.45.14",
  "sha256": "<SHA-256 del .exe viejo, para legacy>",
  "url": "/downloads/CreaRackAgent.exe",
  "package_version": "1.45.14",
  "package_url": "/downloads/agent-app/1.45.14",
  "package_sha256": "<SHA-256 del .zip>",
  "package_sig": "<firma Ed25519 en hex>",
  "package_min_bootstrap_api": 1
}

Orden de publicación (crítico para evitar race conditions):

  1. Publica app-X.Y.Z.zip + app-X.Y.Z.meta.json en media/downloads
  2. Publica .exe (bootstrap, si cambió)
  3. AL FINAL: publica .version (el manifest anuncia versión leyendo este file)

Así, jamás se ordena un update cuyos artefactos no estén ya servidos.

Testing y validación

19 tests nuevos (tests/agent/test_agent_launcher.py):

Suite agente: 83/83 verde · Suite servidor: 12/12 verde

Limitaciones (F1 → F2)

El bootstrap 2.14.0 aún no está compilado ni instalado en clientes. Pendiente F2 (task #187):

  1. Compilar el bootstrap (build_agent.bat paso 4.7)
  2. Instalar en la máquina de Edu (manual o última travesía por el swap legacy)
  3. 2-3 releases de validación E2E en producción

Sin impacto en Ayuda (nada visible para usuarios hasta que todos migren a bootstrap).

Plan completo

Ver agent-lanzador/PLAN_LANZADOR_ESTABLE.md (actualizado F1 completada).

Impacto de seguridad

Véase también

Subir