Skip to content

Remote-Pulse: contrato del rol y reconciliación pendiente — 20 octubre 2026

Solo fuente. Base infraestructura c40bdb9; app propia <REDACTED>, main consultado por GitHub. No SSH, app HTTP, PostgreSQL, NAS, entorno/secretos o Vera. No se importó la app ni instalaron dependencias.

Matriz: declarado, requerido y observado

La columna viva procede únicamente de la observación dirigida de las 19:55 CEST, no de una nueva consulta ni de inferir valores privados.

Área Rol actual App upstream / observación y consecuencia
Revisión y layout clone main a /opt/rp/server; versión declarada0.1.0 App1.0.15 en server/pyproject.toml, código server/src/rp_server; unidad viva apunta /opt/rp/source/server. main flotante no fija entrega
Python/uv variable Python3.12 ignorada; paquetes/venv fijan3.12; pipx por pip3 global, uv bajo /root/.local/bin y symlink App requiere >=3.12. Declarar versión disponible en OS objetivo; Bookworm no aporta3.12 por defecto. PEP668 puede impedir pip global y /root puede impedir acceso de rp al uv enlazado; no son fallos runtime comprobados
Instalación uv pip install -r /opt/rp/server/requirements.txt No existe requirements raíz en ese SHA; server usa pyproject/uv.lock/hatchling. Instalar dependencias sueltas tampoco instala paquete src
Configuración TOML y RP_CONFIG_PATH, DATABASE_URL, RP_DATA_DIR, RP_LOG_DIR Settings usa entorno/.env, extra=ignore. Requiere POSTGRES_URL y JWT_SECRET; database.py consume postgres_url. No hay cargador TOML ni alias DATABASE_URL en fuente actual
Credenciales/URLs JWT solo escrito en TOML; URI postgresql://; sin sesión/OIDC explícitos POSTGRES_URL debe seleccionar asyncpg; JWT_SECRET y SESSION_SECRET privados. SESSION_SECRET tiene valor de desarrollo; omitirlo no es seguro. SERVER_URL por defecto localhost perjudica enrolamiento remoto. OIDC/URLs/proxies deben preservarse explícitamente, sin leerlos aquí
PostgreSQL módulos community.postgresql sin driver Python declarado; HBA local, URI localhost TCP Acreditar psycopg del intérprete Ansible y política socket/TCP. Línea HBA local no configura TCP. No se afirma identidad de BD/rol vivos por defaults
Orden migraciones postgres.yml ejecuta Alembic antes de app.yml Antes de crear usuario, clonar, venv y config: instalación limpia falla. Migración además en raíz incorrecta, sin mismo EnvironmentFile
Unit raíz /opt/rp/server, uvicorn rp_server.main, 2 workers, bind127.0.0.1 src necesita instalación; WorkingDirectory correcto server. Caddy remoto usa rp.lan:8080: bind solo loopback necesita mediador que el rol no acredita. Selección viva no acredita bind/workers/env reales
Proxy/identidad --proxy-headers sin política explícita de peers; opciones TOML obsoletas Settings trusted_proxies tiene defaults antiguos .247/.248/.250. Reconciliar Caddy .40/.41, encabezados y OIDC nativo; Pocket ID no tiene forward-auth
Frontend no construcción/copia SPA Fuente tiene solo .gitkeep en static/dash-next; script oficial construye Node22+/npm y empaqueta assets. Health200 no demuestra dashboard utilizable
Copias rol declara timer/script03:00 Lectura19:46 no encontró esa implementación. No acredita ausencia de otras copias/PBS. Reparación de PR82 es fuente, no instalación

Fuentes propias aprovechables

  • server/README.md, server/SETUP.md y server/dev.sh: contrato de desarrollo uv sync → variables → Alembic → uvicorn. Sus --reload/0.0.0.0 no constituyen una receta de producción segura.
  • server/pyproject.toml, server/uv.lock, server/alembic.ini y migraciones: paquete, resolución y esquema actuales. settings = Settings() se evalúa al importar; no usar imports de preflight contra el servicio real sin contexto.
  • scripts/build_dashboard.sh: Node22+, npm ci con lock y copia a server/src/rp_server/static/dash-next; wheel incluye esos assets. No ejecutar su rsync --delete sobre entrega viva durante exploración.
  • packaging/linux/remote-pulse.service ejecuta agente heartbeat, no servidor. El workflow release construye agentes; no acredita un instalador server actual.
  • Rol Caddy señala snippets/rp.caddy, ausente en árbol c40; las rutas RP están en Caddyfile.full-routing. Resolver fuente desplegada antes de actualizar imports/snippets. No copiar documentación de forward-auth antigua.

Protección temporal, no modernización parcial

Primera tarea de remote_pulse_server/tasks/main.yml: fail explícito con la unión de tags actuales del rol, antes de todos los includes. No usa always: una fixture real mostró que always supera el never heredado y rompe una ejecución ordinaria. Sin checkout adicional, gran checker, consulta externa o variable de excepción. Pruebas locales copian entrypoint real y reemplazan includes por sentinelas en directorio temporal: normal, selecciones actuales y --check fallan antes de mutar. Otra fixture con los tags reales del play [remote_pulse, never] conserva rc0/omisión en ejecución ordinaria; la selección manual remote_pulse falla antes de los sentinelas. El test calcula la unión de tags de includes y tareas para detectar futuras ampliaciones no cubiertas por el guard.

No cambia playbook never, servicio vivo, systemd, boot, datos o copias. La protección cubre el entrypoint normal; omitir deliberadamente tags del guard, --start-at-task y direct include deliberados quedan fuera. No es una política de permisos. La reversión del commit quitaría el freno pero no arregla el contrato; no usarla para desplegar el rol obsoleto. Retirar la tarea solo con reconciliación revisada y pruebas de instalación/actualización en destino aislado.

Orden exacto de la reconciliación futura

  1. Acreditar propietario, unidad, revisión, recursos, Python/OS y persistencia existentes con lectura acotada. Preservar env privado por referencia; no sustituir BD/rol/URLs/OIDC ni claves por defaults o nuevos valores. Resolver otras copias y restauración verificable antes de cambios de esquema.
  2. Paquetes/driver PostgreSQL de Ansible y Python>=3.12 compatibles con OS; uv fijado accesible al usuario rp en ruta del sistema, sin depender de recorrer /root o pip global. Crear usuario/directorios respetando permisos vivos; no cambiar owner de /var/lib/rp por asumir el rol correcto.
  3. Entrega de revisión inmutable a layout canónico /opt/rp/source/server, reconciliando cambios propios. Preparar frontend desde lock en staging, no sobre assets vivos. Instalar paquete y dependencias desde server con uv sync --locked --no-dev y entorno proyecto explícito; decidir una venv única y alinear unit/migración, sin dos instalaciones ambiguas.
  4. Render privado del EnvironmentFile: POSTGRES_URL con asyncpg, JWT_SECRET, SESSION_SECRET, SERVER_URL, PUBLIC_DASHBOARD_URL y configuración OIDC/peers pertinentes. Secretos existentes conservados, no valores de ejemplo. TOML obsoleto no puede seguir aparentando ser fuente. Aislar shadow .env del checkout para que no altere la resolución sin inventario. Codificar credenciales reservadas en la URI y citar el formato EnvironmentFile correctamente, sin imprimir valores; interpolación de password literal no es una prueba de DSN válido.
  5. Configurar PostgreSQL/HBA conforme a transporte elegido. Separar creación del esquema de migración: ejecutar Alembic desde server con el mismo entorno y usuario que app, después de paquete/config y backup recuperable. Ensayo migración desde copia aislada antes de producción; rollback de código no revierte automáticamente esquema o datos.
  6. Unit coherente con ruta/venv/usuario y escritura mínima. Revisar dos workers: dispatcher y retención arrancan por proceso; conservar o cambiar concurrencia con evidencia del event bus/SSE, no por defecto. Elegir bind accesible solo a Caddy/red necesaria más firewall, o mediador explícito; no publicar 0.0.0.0 sin política. Forwarded headers y peers explícitos, login OIDC nativo.
  7. En fixture: imports/version/assets, config con referencias falsas, migración de copia PostgreSQL y arranque aislado, rutas autorizadas/no autorizadas, enrolamiento sintético, heartbeat, SSE y secretos/URLs preservados. No usar /health200 como sustituto. Validar ambos Caddy y recuperación de datos.
  8. Solo tras revisión: ventana de aplicación acotada, diff/rollback por componente e inventario de copias existente. Backup corregido se instala únicamente si sustituye/completa un propietario identificado, no para duplicar calendario. Restituir unidad/config/entrega previa coordinadamente; recuperación de BD solo mediante plan comprobado, sin tratar downgrade de código como DR.

No se implementa ninguna de estas fases operativas en esta intervención.