Skip to content

Alta disponibilidad: cobertura, estado y siguientes pasos

Seguimiento del 22 de octubre

Frente Evidencia actual Límite
Consola L1 PR3, main dd94d12a; sólo tasks.yaml entregado a CT212 19:00:44, sin reinicio. L1 ya no puede reanudar pausas o protecciones globales ajenas: ambas transiciones quedan bloqueadas antes del runner. 83 pruebas y CI Python3.12/3.14 correctas; L0/RUNS0, PID, estado y logs conservados. La recuperación selectiva de L1 sigue pendiente, no se probó un ciclo real. Entrega y límites.
Persistencia de consola, 19:41 UTC PR4, main da342e4c: estado y evidencia se sincronizan antes de continuar. 91 pruebas en Python 3.12/3.14 y ambos jobs CI correctos. Sólo app.py entregado a CT212; fixture nativa en temporal propio correcta. Revisión independiente 19:42:17: código exacto, PID 3635 activo/NRestarts 0, estado y tareas intactos, L0/RUNS0 y bloqueos L1 conservados. Sin tareas/probes/HA/Vera. Entrega y límites; la recuperación selectiva sigue pendiente.
Autenticación de consola, 20:13 UTC PR5, main a787845f: la app valida el JWT de Access antes de servir rutas, API y SSE. 111 pruebas en Python 3.12/3.14 y ambos jobs CI correctos; ensayo nativo aislado Python 3.13 con 20 pruebas y lectura JWKS correcta. Entregada con PID 3724 activo/NRestarts 0; salud local 200 y API anónima 401. Estado y tareas intactos; L1 sigue bloqueado. El acceso LAN que evita Cloudflare se rechaza, sin cookie alternativa ni login OIDC offline nuevo. Login real con propietario pendiente. Hallazgo, entrega y límites.
Sondeos de consola, 23 oct 00:43 UTC PR6, main cd966752: NFS consulta sólo metadatos de montajes; Vera fuera del sondeo automático. Sólo tasks.yaml entregado, sin reinicio. Revisión independiente 00:44:12: archivo/metadata exactos, PID3724 estable, L0/cero tareas y L1 bloqueado. No acredita lectura NFS ni recuperación HELD. Entrega y límites.
Observabilidad, 20:21–26 UTC Caché Prometheus: 45/45 targets up y 94 reglas de 23 grupos sanas, sin errores de evaluación. La alerta systemd se resolvió hasta nfs-health-monitor.service de VM208: último ciclo ordinario 20:26 devuelve 75 y los cinco motivos recientes son HELD. instance=localhost:9100 corresponde al target computo.lan:9100, no a CT217. Se conserva la alerta y la retención: no se invocaron manualmente monitor, reparación, probe o notificación. No acredita uso funcional ni recuperación NFS. Temperatura alta de pmx51 sigue pendiente de revisión física.
Compilación Scanner, 20:37 UTC PR14 plundrio-ecosystem, main c787d588: Rollup 4.63.3 → 4.63.5, sólo lock. Instalación aislada y build correctos; 26 entradas de Rollup/plataformas y manifest intacto. Validación y alcance. Sin checks GitHub definidos; prueba Mac Node26, no imagen Linux Node20. No se publicaron imágenes ni se recrearon Scanner/Hunter. El source de producción, su código custom y el trabajo en vuelo permanecen fuera de esta entrega.
Lock Mako RemotePulse, 20:29 UTC PR48 ya integrada en paralelo como main e4e6fe94: Mako 1.4.1 → 1.4.2, sólo server/uv.lock y seis checks correctos. Exportación local frozen/offline con uv 0.11.12 correcta, conservando el lock revisión 5 y cryptography 50.0.2. No se atribuye ese merge a esta actuación ni se desplegó al servidor. El arreglo upstream es específico de Windows; no acredita un vector alcanzable en el runtime Linux. No se repitió la auditoría general de RemotePulse.
Productor de dumps PR174, main 99a8ef58: publicador exclusivo y durable común PG/MySQL entregado el 22 a las 18:44. Primera observación natural posterior: 23 octubre 01:30:00–01:30:45 CEST, cron/exit0, tres exportaciones PG y tres skips intencionales, cero fallos. Validación natural parcial. MySQL sigue sin demostrarse: TRMNL estaba detenido y se omitió. Sin forzar trabajos ni abrir dumps; no prueba CRC posterior, SQL recuperable o restore.
Recuperación DATA-ONLY Jellyfin Copia ct/220/2026-10-21T23:12:05Z extraída desde PBS main local a cuarentena exclusiva en pmx50; cliente/unidad rc0 a las 19:49:54. SQLite 19:50:59: quick_check ok, 35 tablas y DB/WAL/SHM estables con IDs dentro del mapa. A las 19:51:07 ambos datasets/montajes/destinos ausentes y cinco unidades propias inactivas. Ejercicio de datos cerrado. Fallo ACL previo conservado; sin CT, pct restore, app o binds NAS. No acredita coherencia completa en caliente, Jellyfin funcional, NAS o HA. No se encadenan más restores.
Entrada DNS/TLS/OIDC 18:19:54: ambos DNS resuelven pocketid.monxas.casa a VIP .250 (26/13 ms). Discovery y JWKS por .40, .41 y .250: seis HTTP200, certificado validado, sin redirects, issuer y endpoints del mismo origen esperados, una clave pública y RS256. Desde Mac LAN con destinos fijados; ruta activa en ambos Caddy hacia CT213, sin Sablier. No prueba login, permisos, caída o conmutación. Procedimiento reproducible.
Prioridad C0 Ocho CT con cpuunits400 y peso del cgroup padre400: 123/155/212/213/214 y, desde las 17:57, DNS204 y Caddy270/271. La aplicación conserva el resto de configuración; la revisión independiente de las 17:59 confirma los tres nuevos pesos, estado running y PID/start conservados en sus propietarios actuales. Vaultwarden214 mantiene su comprobación de las 17:47. Sin reinicio ni acceso a secretos de la aplicación. Favorece prioridad bajo contención; no libera RAM ni acredita latencia o N−1. F8 y presupuesto histórico corregido.
HA y quórum 17:36: ambos nodos online, quórum y 14 recursos HA started en pmx51; 0 stopped/error. Boots pmx50 51c5b68b… y pmx51 86184726… conservados. No hay prueba de caída ni admisión N−1. La causa de los resets de pmx50 sigue abierta.
Réplicas ordinarias 17:36:57: 14 trabajos desde pmx51 hacia pmx50, último intento igual al último éxito, fail_count0 y sin error. Últimos ciclos entre 17:00 y 17:35 según recurso; duración 2,64–4,80 s y próximos ciclos sin retraso. Sólo estado cacheado: no se dispararon trabajos ni se restauraron datos.
Rotación de logs VM208 Los ocho contenedores comprobados de Immich y Arr tienen json-file, max-size10m/max-file3, heredados del daemon. Archivos actuales: 27,1 MiB agregados; mayor archivo 9,63 MB. Sin acción necesaria. No se leyeron contenidos, historial rotado ni rutas NAS; tampoco se recrearon servicios.
Exportador RemotePulse, entrega anterior PR42 integrada como e7fe5b98; entrega al servidor editable 17:38:13. Lock local conservado byte a byte, sin sync de dependencias, configuración o unidad modificadas. En aquella entrega se reinició únicamente el servidor: PID2244, sustituido después por3081; agente1681 conservado. Retorno local en /root/rp-server-maintenance-20261022-a2u7mp2_/.
Verificación del exportador 17:39:46: revisión independiente confirma HEAD/hash exactos y checkout limpio. Target Prometheus up/sin error; para hostname=rp-server sólo versión1.0.15, muestra de las 17:39:28 y edad18,18 s. La transición v1→v2 se prueba en CI con ASGI/SQLite y otro host intacto. El restart limpia el registro; el scrape de producción no sustituye esa regresión.
Triage python-jose, histórico de las 17:55 Se contrastó HS512, lista explícita de algoritmos y secreto no interpretable como clave pública DER. El vector descrito no aparecía en ese perfil; no acreditaba entropía ni seguridad global. La dependencia se retiró después, según la entrega siguiente.
Retirada de python-jose PR43, main 85efbbbe, entregada a CT280 a las 18:10:21: PyJWT2.15.1; python-jose, ecdsa, rsa, pyasn1 y six ausentes. Revisión independiente 18:12:20–47: HEAD exacto y limpio, servidor PID3081 y agente1681 activos, NRestarts0 y cgroups correctos. Sin cambios de clave, configuración, unidad, esquema DB o frontend. Los avisos GitHub75/76/78 seguían abiertos en la consulta de las 18:11; la entrega no equivale a su cierre automático.
Observación ordinaria posterior Target Prometheus up, sin lastError; último scrape18:12:28 y muestra propia de hace18,88 s. Para hostname=rp-server, host_up1 y versión1.0.15. Sólo caché Prometheus y metadatos: sin tokens de producción, enrolamiento, heartbeat manual ni consulta directa a la aplicación.
Auditoría y dependencias RemotePulse, 18:44 UTC PR47, main a65c53cd: corrige Safety vacío, valida cobertura completa con pip-audit y actualiza cryptography a 50.0.2; retira Pillow conservando QR SVG. Seis checks terminados SUCCESS; artefacto 12450745127: servidor 59/agente 38 paquetes, cero avisos y cero omisiones. 415 pruebas locales correctas, seis skips existentes y ocho casos PostgreSQL cubiertos por CI. Siete archivos del merge idénticos al head probado cec86ad8; PR46 cerrada como sustituida. Cero avisos de CI no equivale a entorno de producción actualizado.
Aplicación RemotePulse, 18:54 UTC Una aplicación al servidor se detuvo durante la instalación y recuperó fuente 85ef y todos los paquetes anteriores. Revisión independiente: checkout limpio y separado, servidor PID 6568 activo/Result success/NRestarts0, agente 1681 conservado; boots de host y CT estables. En ese intento no quedó producción actualizada. El stderr original se descartó y el rc final fue sobrescrito por la recuperación; no se atribuye causa exacta. La revisión del entorno fallido acredita retirada de tres distribuciones sin completar las nuevas; los directorios principales del entorno permiten escritura a rp. La causa y la entrega corregida quedan acreditadas en las filas siguientes.
Observabilidad tras recuperación, 19:00 UTC Caché Prometheus: target RemotePulse up, último scrape 19:00:28 sin error; host_up 1 y única versión propia 1.0.15. No hubo heartbeat manual, consulta directa a la aplicación, generación de credenciales o notificación. No prueba login OIDC ni funcionalidad global.
Entrega RemotePulse corregida, 19:15:29 UTC Fuente a65c53cd aplicada a CT280 en main. cryptography 50.0.2, Pillow ausente y las otras versiones exactas; 43 dependencias más rp-server editable. Sólo servidor parado/arrancado: PID 7254 estable, NRestarts 0 y cero entradas nuevas de prioridad error. Configuración privada, unidad y agente 1681 conservados; sin migraciones ni intervención sobre frontend o datos. Comprobación independiente 19:16:05: HEAD, rama main, tres hashes, inventario y servicios correctos, boots de pmx50 y CT280 iguales.
Observabilidad posterior, 19:16:42 UTC Target RemotePulse up y sin error; scrape 19:16:28, muestra real de host_up 1 con edad 14,23 s, posterior al arranque; única versión propia 1.0.15. Sólo caché Prometheus y metadatos: sin heartbeat manual, credenciales, notificaciones o login OIDC. No acredita salud funcional global ni failover.

La instalación inicial como rp no podía retirar cryptography/__pycache__: directorio root:root 0755 con cuatro archivos pyc root:root 0644. Un ensayo aislado reprodujo errno13, sin modificar el servicio. El ensayo corregido instaló las versiones exactas con UV 0.11.16 propiedad de root y HOME /root, desde el proyecto; pip check y fixtures Ed25519, Authlib RSA/JWK/RS256 y QR SVG sin Pillow pasaron después como rp. La segunda entrega usó ese mismo método, sin aplicar chmod/chown correctivo al entorno vivo. La herramienta ejecutada como root también pertenece a root; no se elevó el binario modificable por rp. El servicio conserva su usuario habitual y las pruebas de importación usan -B para evitar nuevas cachés de bytecode de root. El rol Ansible retirado sigue bloqueado; esta entrega no moderniza su contrato.

La recuperación de la entrega final queda en /root/rp-server-crypto-maintenance-<REDACTED>/. Recibos locales en rp-crypto-server-preflight-ba2m7qm0: aplicación v2 SHA <REDACTED>, comprobación independiente SHA <REDACTED> y caché Prometheus SHA <REDACTED>. Se conservan el intento fallido y su recuperación; no se convierten en PASS.

La publicación MySQL sustituye el antiguo check-then-mv, que podía reemplazar un symlink colgante. Las nuevas regresiones daban cuatro fallos antes y pasan con el publicador común:21 pruebas locales correctas, incluidas omisiones permitidas frente a una base inesperadamente detenida. La reconciliación exacta con producción encontró sólo tres comentarios ausentes y el patrón am-postgres:exited, ahora recogido en Git. Instalación con lock del productor, backup privado y CAS; conserva horario, permisos y bases dormidas. Retorno: /home/monxas/.local/state/pg-dumps-mysql-maintenance-20261022-1wxocsaq/.

El workflow PR39815435465 terminó SUCCESS: Python3.10 y promtool completados; todos los pasos de Python3.12, incluido Complete job, completados SUCCESS. Su resumen individual aún indicaba IN_PROGRESS al revisar, una inconsistencia conservada sin declarar ese check terminado ni repetir pruebas para cambiar metadata. El merge estándar no usó override administrativo. El ciclo ordinario posterior ya aporta la validación parcial que se detalla más abajo; no se forzaron dumps de prueba.

La sustitución conserva HS512 con lista explícita, los tokens legacy, el TTL y los errores de la API; mantiene la semántica de iat sin convertirla en una restricción nueva. exp se rechaza al alcanzar su instante, sin añadir gracia: el borde es hasta un segundo más estricto que antes. Se declararon las dependencias de firma Ed25519 y sólo se actualizó PyJWT a2.15.1, que incorpora las correcciones de sus avisos. Validación:73 pruebas focales,414 locales sin PostgreSQL,6 omitidas y8 excluidas; seis controles CI correctos, incluido PostgreSQL. Se probaron tokens sintéticos, claims malformados y payloads anidados sin provocar tráfico de producto.

El primer intento de entrega,18:09:34, se detuvo por permisos del directorio de trabajo de uv; se restauraron el entorno y checkout anteriores. El segundo, con cwd del repositorio, terminó correctamente. El retorno privado de la entrega final queda en /root/rp-server-security-20261022-sbpeiwn5/; el intento previo se conserva por separado. Los boots de pmx50 y CT280 permanecieron estables. El aviso de python-jose queda como triage histórico y la biblioteca ya no está instalada; no se afirma que GitHub haya cerrado los avisos.

Productor de dumps: validación natural parcial del 23 de octubre

Consulta de sólo lectura entre 2026-10-23 01:42:44 y 01:46:25 CEST (2026-10-22 23:42:44–23:46:25 UTC). VM208 declara Europe/Madrid. El historial existente de RunWisp registra pg_dumps, ejecución 01M5JZ6D626Q2JE38S8KACRHFM, iniciada por cron a las 01:30:00.002 y terminada a las 01:30:45.173 CEST: ended, success, exit0 y retry0.

El log de esa ejecución se clasificó en memoria, sin publicar su contenido: SUMMARY exported=3 skipped=3 failed=0. Jellystat, Paperless e Immich tienen un OK cada uno; AudioMuse, Jellyfin-share y TRMNL tienen un SKIP cada uno, con el motivo previsto de Sablier detenido intencionalmente, sin arrancarlos. No hay FAIL. Los tres finales PG de fecha 23 de octubre tienen estos metadatos, en almacenamiento local:

Productor PG Bytes Mtime CEST
jellystat-db 11 530 831 01:30:03.512
paperless-db 1 567 543 01:30:05.000
immich-db 191 128 533 01:30:41.862

Los tres son archivos regulares UID/GID1000, modo0600 y nlink1. Esto acredita la ejecución ordinaria PG y su publicación registrada después del cambio; no acredita una exportación natural MySQL/MariaDB, porque TRMNL se omitió. Esa cobertura sigue pendiente del horario y actividad ordinarios, sin despertar la base para fabricar una prueba. Tampoco se abrieron dumps, se recalculó CRC, se validó SQL o se ensayó restauración. La revisión no invocó productor, backup, retención, sincronización o notificaciones, ni accedió a rutas NAS.

Recibos seleccionados privados: metadatos de finales SHA <REDACTED>, historial del job SHA <REDACTED> y clasificación del log propio SHA <REDACTED>.

Avance global del 22 de octubre, cierre de ventana y recuperación

El homelab conserva HA parcial. La nueva medición de dos horas ha terminado; la campaña incompleta anterior sigue como histórica. No se ha corregido la causa de los resets de pmx50 ni probado failover físico o salud funcional global.

Frente Avance comprobado Límite y siguiente trabajo
Watchdog Tres resets por la tarde: 15:46, 16:07 y 16:21 CEST; último boot 51c5b68b…, kernel -19, con mensaje de watchdog expirado. Causa abierta. Prueba del -25 instalado pendiente de respuesta sobre acceso físico y reinicio. No se cambió pin, watchdog o réplicas. El incidente de las 15:46 detallado debajo es histórico.
Capacidad 121/121 muestras terminales y oferta histórica ligada a ambos boots; envolvente −3,81GiB con reserva 2 GiB, comparación por mayor ronda −2,02GiB. Ventana y composición posterior. Bordes de oferta parciales y picos intermedios desconocidos; no admisión N−1.
Jellyfin Lectura posterior 12:12: anon 374 MiB y file 2167 MiB; se conserva una instancia activa recuperable por HA. No equivale a caché garantizada recuperable ni descompone máximos históricos. No cambiar límites para hacer pasar el cálculo.
Integridad local Directorio de estado de VM208 endurecido 0775→0755 y fuente integrada en PR153. Rol homelab_tools lleva never: no hay convergencia automática que esperar. Sin recursión ni reinicios; se conserva para futuras aplicaciones explícitas.
Immich 3.3.5 aplicada a las 15:29–15:31; fuente Stacks PR7 integrada. Después del reset, 15:52: mismos contenedores/imágenes, server/ML/DB healthy y Redis running. Arranques de contenedores alrededor de 15:47 y nuevo boot VM208 c2a5e0bc…: hubo interrupción. RestartCount0 no significa continuidad. DR integral y prueba autenticada de biblioteca siguen pendientes.
Comprobadores PR152 integra comparación exacta de duraciones equivalentes de Alertmanager y comentarios estándar de iptables-save. La corrección del comparador no acredita entrega de notificaciones ni equivalencia de todos los campos del receptor Vera. No se modifica el proyecto del usuario.
Soularr Controlador central actualizado y leído de vuelta a las 13:15:59, exacto a main 6827825; perfil opt-in disponible. Estado y plan. Autenticación sin activar: faltan identidades permitidas de PocketID, cliente, ACL y login real. Instalar código no cambia las rutas ni demuestra protección.
Dumps PostgreSQL PR157 integrada; publicación exclusiva con fsync aplicada a las 12:46 y readback independiente a las 12:49. Bytes ajenos preservados. Falta observar el próximo job ordinario. Sin forzar copias ni afirmar que se haya producido un dump con el nuevo código.
RAM física A las 13:06:35, getters PCI/DMI cacheados confirman Radeon 1002:1681 sin driver activo y modelo Venus series. Total VRAM no disponible; BAR no acredita reserva UMA ni memoria recuperable. No se cambia el presupuesto N−1, firmware, módulos o crashkernel.
Observabilidad 16:14: 94 reglas sin errores y44/45targets up. Pi-hole exporter agotaba10s; un único restart16:26 lo recuperó: scrape0,27s y101seriesPi-hole,85no cero, a16:32. Misma imagen/configuración; causa del bloqueo sin demostrar. No se atribuye al binario un bug de otra versión ni se probaron notificaciones.
Guarda NFS Inicialización del lock corregida: archivo ausente creado y regla tmpfiles persistida; siguiente ciclo ordinario16:32 pasa deUNKNOWNaHELD. Continúa75bajo mantenimiento; no se habilitó reparación, se borró el pendiente ni se ocultó la alerta.
Térmica pmx51 16:56–16:57: 77–78 °C, frecuencia aproximada 2,8 GHz; Prometheus registra 3,78 transiciones térmicas/s en los cinco minutos anteriores. Una ventana nativa posterior de cinco segundos no registra incrementos. No es cuota de CPU ni porcentaje de rendimiento perdido. Los tiempos acumulado/máximo devuelven 0 ms; no se infiere impacto histórico nulo. Sin cambios de potencia o firmware.
Sync PBS Inspección de sólo lectura 16:56: colección correcta; último main-to-archive de 06:00–06:01:50 termina con status unknown, sin tarea en curso. No hay finalización correcta demostrada ni causa de almacenamiento acreditada. Mantener alerta y observar próximo ciclo natural; no se lanzó sync, verify, copia o limpieza.
RemotePulse propio Actualizado a 1.0.15 a las 17:14:53 desde main 8002bd2e; supervisor de bucles instalado. Revisión independiente 17:16: heartbeat disponible, agente sin reinicios y servidor conservado. Configuración, unidad y 28 dependencias iguales. No se atribuye esta corrección al incidente anterior ni se actualizan otros agentes. Las métricas conservan etiquetas de versiones antiguas; no son inventario fiable por sí solas.
Servicios Lectura 09:51: 12 contenedores arrancados, 0 reinicios; 11 healthy y Redis sin healthcheck. Es liveness de esa lectura; no se presenta como E2E ni como estado actual renovado al leer este documento.

Para recuperación de Immich se conserva lo ya demostrado el 20 oct con el dump del 19 oct: DB-only restaurada con 31.595 assets, 31.595 referencias presentes por metadata y tres originales upload recuperados con hashes. Son evidencias parciales, separadas y de aquella generación, no una restauración integral ni cobertura extendida a la publicación del 21 oct. No repetir pruebas para reconstruir este historial.

CT100 corresponde a Vera/OpenClaw, trabajo paralelo del usuario: su metadata cgroup formó parte del alcance N−1, pero no se investigan sus procesos ni se propone recortarlo. Los cuatro recursos estrictos y VM208 fuera de HA, las bibliotecas NFS, router/NAS y energía mantienen sus límites anteriores. SAI/Meross sigue sin activar; offsite, Jellyfin/PBS y CT217 necesitan sus propias admisiones de recuperación. No se fuerzan copias, restores, hardware o HAOS para cerrar una casilla.

La fuente de este cierre está en main; el portal de seguimiento continúa sólo en 127.0.0.1 del Mac. Ninguna publicación de documentación publica ese portal.

Entrega al agente propio de RemotePulse, 22 octubre 17:14–17:16 CEST

La corrección del supervisor está integrada en main 8002bd2e, con 183 pruebas locales del agente y seis controles CI correctos, incluidos Linux, macOS, Windows, servidor y seguridad. Un fallo o salida inesperada de cualquiera de los dos bucles ahora termina el daemon y limpia al hermano para permitir recuperación por systemd. No detecta por sí solo un bucle vivo pero bloqueado ni demuestra la causa del incidente anterior.

Se revisaron los 39 archivos diferentes respecto al commit instalado 6f57bc2: predominan formato y tipos; identidad, autenticación, comandos y dependencias runtime se conservan. Se construyeron ambos wheels desde sus commits exactos. Los 47 archivos Python del wheel 1.0.0 de retorno coincidían con los instalados antes del cambio.

En CT280 se preparó una copia local del entorno uv y ambos wheels; se detuvo únicamente rp-agent.service, se instaló el wheel completo 1.0.15 mediante uv tool install offline con versiones de dependencias restringidas y se arrancó esa misma unidad. Las 28 dependencias, configuración y unidad permanecen iguales; el servidor conserva PID519. La copia local de retorno está en /root/rp-agent-maintenance-20261022-ax7_ik8c/; no se ejecutó el instalador de enrolamiento ni el rol retirado.

La lectura independiente confirma agente PID1681, activo, enabled, Result success y NRestarts0; metadata instalada 1.0.15, supervisor FIRST_COMPLETED y recibo uv apuntando al wheel nuevo. Caché de Prometheus a las 17:16:19: rp_host_up=1 para hostname=rp-server, muestra de las 17:15:58 con edad 21,65 s y ninguna alerta de esa identidad. Las series de versión conservan tanto 1.0.0 como 1.0.15 porque el exportador no elimina etiquetas anteriores: no se infieren dos agentes ni un retorno de versión. Sin heartbeat manual o notificaciones.

Revisión térmica y de sync PBS, 22 de octubre 16:56–17:00 CEST

El contador térmico se contrasta con la documentación del kernel: cuenta transiciones del estado térmico del paquete. El exportador toma una serie por paquete; la regla no multiplica el mismo evento por sus cuatro CPU. El valor de 3,78 eventos/s no mide duración ni pérdida porcentual de rendimiento. CPU0 conserva 2.461.103 eventos durante una ventana posterior de 5,0003 s; los campos de duración existen y devuelven cero. Esa ventana corta no explica los episodios anteriores. Quedan pendientes diagnóstico físico y correlación temporal, sin pruebas de carga ni cambios de límites.

En PBS se comprobó antes de invocar --inspect que el helper instalado coincide con la fuente mantenida. No publica métricas ni escribe el contador. La tarea de hoy comenzó a las 06:00 y terminó a las 06:01:50 con estado unknown; el CLI de log devuelve ese mismo estado y no un cierre correcto. Su proximidad al arranque de las 06:02 es compatible con una interrupción, pero no identifica por sí sola la causa. No se toma el servicio oneshot inactivo después de otro arranque como prueba del resultado de las 07:00. El siguiente ciclo ordinario debe aportar su propio resultado; una nueva copia no se ha provocado para hacer desaparecer la alerta.

Incidente nuevo: pmx50, 22 octubre 15:46 CEST

Se detectó el cambio a00208e6… → f006953c… durante lecturas preparatorias para el restore Jellyfin. No se había creado un destino ni iniciado extracción, restore o montaje. pmx51 conserva 86184726…; a las 15:54 declara quórum y los 14 recursos HA started en51. No hubo un failover de esos recursos: ya vivían allí. Los invitados de50 volvieron a arrancar por la configuración existente.

Evidencia Hora CEST
Último journal retenido del boot anterior 15:45:35,859
Último Pulso anterior, secuencia34707 15:45:41
pmx51 registra enlace a host1 caído 15:45:45,357
pmx51 registra token ausente7500ms 15:45:49,081
Primer journal del kernel nuevo 15:46:09,091
Primer Pulso del boot nuevo 15:46:19, uptime11,34s

El kernel nuevo imprime razón AMD 0x02000800, watchdog hardware expirado. Ese mensaje no identifica la causa de la pérdida de alimentación del contador. La separación último Pulso→primero nuevo es38s, incluyendo fases desconocidas; no equivale a38s de congelación ni a un timeout medido.

Los últimos120 paquetes conservan secuencia contigua. Mux y CRM avanzaron schedstat en119/119 intervalos; LRM en24/119. MemAvailable14385–14789MiB, PSI memoria0/0 y CPU PSI0/0 en el último paquete. Esto acredita progreso hasta esa muestra, no KEEPALIVE ni actividad durante los segundos posteriores.

El PSI I/O some/full final fue4,40/4,18. Una lectura comparativa del mismo boot halló máximo5,33/4,84 a las15:14–15:17, y3,34/2,61 a las15:29–15:32, sin reset en esas ventanas. El pico final no es excepcional por amplitud. Las réplicas ordinarias100/123/155/171/215/216/217/218 se ejecutaron durante la última ráfaga de SSH desde51; su proximidad no acredita causa. No se cambiaron horarios, frecuencia o rate por esta correlación. A las15:57, ZFS declara pools sanos; es estado actual, no una prueba de ausencia de fallo transitorio.

Kernel instalado y selección de arranque

La consulta nativa de las15:59 confirma 7.0.14-19-pve activo y fijado. 7.0.14-25-pve ya está instalado desde19oct17:06 según dpkg; existen imagen, initrd y árbol de módulos. No se instaló en esta investigación. No aparece ninguna fila retenida con _KERNEL_RELEASE=7.0.14-25-pve; la ausencia no prueba que nunca se haya usado. Se corrige así la ambigüedad anterior de «candidato»: está disponible localmente, pero su funcionamiento no está demostrado.

La instalación de19 fue el27sep, antes del inicio histórico de cuelgues del5oct; las fechas no prueban una regresión. Una comparación real de kernels requiere una ventana de mantenimiento y recuperación del arranque. No se cambió el pin, GRUB, BIOS ni timeout, ni se solicitó otro reboot. La causa continúa abierta.

Evidencia privada seleccionada: watchdog-f006-20261022/ (HA, réplicas, ZFS y selección/historia del kernel), watchdog-a002-f006-retained-d9uq4a9u/ (Pulso, SHA del recibo9a025c89…) y watchdog-a002-prior-io-windows-95icwou2/ (comparación, SHA6c59fd32…). Ninguno contiene volcados de RAM ni credenciales.

Cierre de medición del parser, 22 de octubre 08:35 CEST

PR149 está integrada en main c73f86c…: parser C optativo, con 258 pruebas locales Python 3.12/3.14 (una específica Linux omitida en Mac), revisión independiente y cinco checks CI correctos. La regresión de dos bibliotecas con un descriptor reutilizado pasó en Linux 3.10/3.12. La identidad cargada queda fijada incluso ante un fallo posterior; los dos cargadores usan alias distintos.

Una compilación aislada en pmx50 terminó correctamente en 0,146 s, sin salida y con el grupo propio retirado. El artefacto ELF x86-64 de 15.624 bytes quedó root:root/0600 en un directorio nuevo 0700. Boot, mux y compilador coincidieron antes y después. Se usó el toolchain existente: fijar gcc no acredita por sí solo cc1/as/ld ni constituye una construcción reproducible. Los límites CPU/AS son por proceso y FSIZE por archivo; no se afirma una cuota agregada.

La admisión posterior de sólo lectura verificó artefacto y libsystemd sin cargar el parser. Después, una consulta GetAll real con el parser C terminó correcta: 3,265 ms CPU y 9,478 ms de pared, MainPID1485/active/running, cero CPU de hijos, CORE0/AS256MiB/CPU1s, entorno limpio, nondumpable y guarda posterior verificados. Una lectura independiente confirmó terminados los procesos efímeros e identidad del artefacto conservada. El artefacto no está activado en ningún servicio.

Un intento anterior se detuvo en worker_preflight con cero consultas: el transporte omitía el argumento - exigido para stdin. Se conservó ese UNKNOWN, se verificó la corrección mediante lectura de flags/argv y no se debilitó la guarda. Sólo la ejecución posterior realizó GetAll.

No se acepta todavía el capturador completo ni se resuelve la causa del reset. Los 4,083 ms de la consulta anterior y los 3,265 ms actuales son observaciones separadas, no una comparación causal A/B. La medida aislada no justifica repetir la captura que excedió el 1 %. El siguiente trabajo revisa los costes restantes manteniendo cadencia, checkpoints y contabilidad completos. N−1 y las restauraciones pendientes conservan sus límites documentados abajo.

Recibos privados: build watchdog-parser-build-only-yu6oc7dw/native.json SHA d428003d…; admisión watchdog-parser-phase-a-q9d12gqv/native.json SHA 1a26c37f…; consulta watchdog-parser-one-query-x9ur55cb/query-native.json SHA ff002869…, cierre independiente a7660ed2… y POST e4e4b93a….

Actualización del 22 de octubre, 07:21 CEST

La inestabilidad de pmx50 sigue siendo el P0. Se han confirmado dos arranques adicionales: 05:16:07 (bc8c2eb8…) y 06:02:37 (a00208e6…). El kernel del último vuelve a registrar hardware watchdog timer expired; ese indicador no identifica la causa inicial ni resuelve la duda sobre bits AMD retenidos. Las admisiones del boot e269… quedan históricas y no se reutilizan para ejecutar pruebas.

Comprobación Resultado y límite
Cluster a las 07:02 Quórum de tres votos; pmx51 conserva boot 86184726…; los 14 recursos HA figuran started en pmx51. No demuestra salud funcional completa ni un failover en estas dos caídas.
Pulso externo previo Últimos paquetes de los boots anteriores a las 05:15:38 y 06:02:08. En las últimas 60 muestras de cada tramo, mux y CRM avanzaron CPU en 59/59 intervalos; presión de memoria observada cero y MemAvailable mínimo de 14,3/14,6 GiB. No acredita KEEPALIVE ni descarta un bloqueo posterior.
Corosync en pmx51 Pérdida de enlace a las 05:15:42,830 y 06:02:13,118, seguida de timeouts de token. Describe el orden observado; no prueba la causa del reset.
Journals previos de pmx50 Consultas correctas en ventanas acotadas, sin filas retenidas. No equivale a ausencia de fallos. Pulso recibió 159 mensajes KMSG en las ventanas elegidas, sin coincidencias en los patrones seleccionados de watchdog/lockup/OOM/NVMe/hardware/thermal.
Campaña N−1 Incompleta: 87 muestras y 88 frames hasta las 02:38:23; terminal real exit2/UNKNOWN y sin frame final. No se calculó margen de dos horas ni se consultó oferta adicional. El corte precede a los resets; relación causal desconocida.
sd-bus en el boot actual Admisión readonly renovada. Una consulta medida correcta a las 07:15:31: 4,083 ms CPU y 10,334 ms de pared; proceso protegido contra volcados, identidad del mux estable. No acredita el presupuesto del capturador completo.
Capturador completo con sd-bus Ensayo previsto de 30 s a las 07:19:40: UNKNOWN por presupuesto, con 40,366 ms CPU total en 2,126 s; el límite del 1 % se conserva. Diez eventos recibidos, dos keepalives exitosos y cero pérdidas en ese tramo breve. No cubre ninguna caída ni acepta las decisiones de clientes como observadas.
Cierre del ensayo POST 07:20:46: registro vacío, grupo e instancia retirados, once controles globales intactos y bootstrap terminado; mux1485/start456 y boot actual conservados. Sin reintento ni recuperación automática.

La activación consumió 9,34 ms de CPU y las tres guardas periódicas 25,10 ms. La configuración previa al intervalo tuvo otro alcance (98,08 ms): no deben sumarse todas las fases como si midieran la misma ventana. La consulta aislada barata no basta para admitir el conjunto; el siguiente trabajo es atribuir y reducir coste real sin modificar el 1 %, 1 Hz ni las tres guardas iniciales.

Fuentes integradas durante la noche: PR142 (backend optativo), PR143 (admisión metadata de cuarentena), PR144 (reductor local de campaña terminal), PR145 (inspector de biblioteca) y PR146 (privacidad del observador). PR146 quedó en main 9b8262d…, con 237 pruebas en Python 3.12/3.14 y cinco checks CI correctos. Se revisó por root; no se afirma una nueva revisión independiente porque los agentes auxiliares agotaron su cuota. Preparar o integrar fuente no implica restauración ni despliegue de servicios.

Jellyfin conserva su modelo de una instancia activa con recuperación HA al otro nodo. Los mapas y permisos observados a las 01:51, y los 216 GiB disponibles en ZFS a las 02:03, pertenecen al boot anterior. No son capacidad actual garantizada. No se ha creado dataset ni namespace de recuperación ni extraído payload PBS. Antes del restore faltan admisión fresca, mapa efectivo, destino con cuota, autoridad PBS y validación aislada. Las seis bibliotecas NFS requieren cobertura propia. Immich completo, CT217, recuperación fuera del NAS y energía siguen abiertos.

Recibos seleccionados privados: watchdog-overnight-pulse-5lf69o7g/analysis.json SHA 2060c51e…; consulta watchdog-sdbus-one-query-newboot-ohmw53ey/native.json SHA cd85a65b…; ensayo watchdog-sdbus-v3-newboot-j_ud9zel/closure.json SHA 3e8cde3b…, POST 67ee9d08…; demanda N−1 SHA 1979f5d4…. El portal de seguimiento permanece exclusivamente en el Mac, en loopback.

Comprobación binaria del kernel, 22 de octubre 07:34 CEST

Se ha acreditado la presencia de la escritura de borrado en el binario instalado. Se leyó sólo código y metadata local de /boot/vmlinuz-7.0.14-19-pve y System.map; la descompresión y el desensamblado se hicieron en el Mac. El ELF resultante tiene build-id <REDACTED>, igual al build-id expuesto por el kernel en ejecución, con boot a00208e6… estable durante las lecturas.

La función print_s5_reset_status_mmio mapea cuatro bytes de 0xfed803c0, lee con ioread32, descarta el caso 0xffffffff y pasa el mismo valor y dirección a iowrite32 antes de iounmap y del mensaje. Los destinos de llamadas se contrastaron con System.map y el destino iowrite32 contiene el store MMIO movl %edi,(%rsi). Esto acredita código de writeback compilado, consistente con la corrección W1C; no acredita que el hardware haya limpiado eficazmente el registro ni identifica la causa raíz. No se leyeron ni escribieron registros MMIO durante la investigación, ni se cambió kernel, firmware o watchdog.

La duda anterior sobre inclusión compilada queda resuelta para este build. Siguen sin obtenerse los dos archivos fuente Ubuntu exactos; no se afirma un build reproducible ni eficacia física del borrado. La observación del fallo y la reducción del coste del capturador siguen siendo los siguientes trabajos. Recibo privado watchdog-kernel-binary-provenance-hx_h842n/receipt.json SHA 6c2939ca…; análisis 9fc4a123…, imagen original ad9dda39…, ELF 4a2c0068….

El prefijo N−1 incompleto también se validó offline con el receptor mantenido: 87 muestras correctas y ninguna terminación. Su máximo de suma por ronda fue 13,65 GiB; no es demanda atómica ni un margen contra la oferta del otro nodo. La suma de máximos por huésped no coincidentes fue 13,70 GiB. No se consultó oferta adicional ni se elevó a campaña completa. Recibo descriptivo nminus-demand-campaign-98kkaaxm/incomplete-prefix-description.json, SHA 8ffc8a01….

Registro histórico del 21 de octubre

Nuevo arranque: 21oct, 17:07:26 CEST. pmx50 tiene boot <REDACTED_UUID>. El kernel vuelve a declarar hardware watchdog timer expired (0x02000800); la causa sigue abierta. Recuperación a las 17:13: 28 huéspedes running, 14 HA started, 14 réplicas OK y quórum correcto. Las guardas del boot bff quedaron invalidadas. El presupuesto de las 16:15 es histórico, no un N-1 actual. Jellyfin 220 se conserva para recuperación en el otro nodo. WP-Pulse se retira por decisión del usuario: target Prometheus y rutas Caddy ya retirados; CT281 detenido con onboot0 a las 17:31. Presupuesto instantáneo posterior: +681,37 MiB después de reservar 2 GiB, incluyendo Jellyfin. Tres intentos de captura de once eventos terminaron UNKNOWN por coste del observador y sus POST independientes verificaron limpieza. PR128/131/134 integran correcciones; ninguna acredita todavía el límite nativo del1% ni identifica la causa del reset. No queda captura nueva activa. Cloudflared ya se monitoriza desdeCT217: configuración27 aplicada a las23:15, conservando los26 jobs anteriores y el tokenHA. Readback independiente23:20: dos targetsUP, up1 y gauge4+4, con muestras originales de5,3s/28,4s. Las dos alertas se aplicaron después en una fase separada: configuración de scrape intacta y dos evaluaciones sanas posteriores exigidas por el helper. Readback independiente23:40:27:23grupos/94reglas,94healthok/0otros y dos evaluaciones propias crecientes acreditadas. Notificaciones y rutas públicas de aplicación siguen sin prueba E2E.

Revisión del 21 de octubre de 2026. Cada lectura conserva su fecha y epoch; los apartados15:16 y anteriores describen evidencia histórica. El homelab tiene HA parcial: diez recursos admiten el otro nodo y cuatro siguen estrictos en pmx51. Política y réplica no acreditan capacidad suficiente ni salud E2E. La inestabilidad de pmx50 sigue siendo el P0; backup completo, energía y pruebas de recuperación funcional continúan abiertos.

Cloudflared: consumidor y reglas aplicados en fases separadas

Después de cerrar la precedencia seleccionada de CT219, el contrato privado admitió únicamente los dos productores y el origen del observador. Las fuentes versionadas siguen siendo candidatos fuera del despliegue ordinario; la activación manual usa el helper mantenido y conserva los recibos originales. La PR135 corrigió el pin del template posterior a la retirada de WP-Pulse.

Primero se prepararon cuatro archivos privados, se validó el candidato con el promtool existente y se aplicó una sola transición 26→27. El helper acreditó la nueva configuración cargada, con token de HA conservado enRAM, inode 1107915 y owner/modo originales. Las reglas quedaron intactas. Configuración nueva SHA37ab7898…, backup y recuperación separados, sin rollback necesario.

El readback independiente de las 23:20:34 conserva contenedor, PID1181/start8461, bootf96a y padre861. Dos targets exactos, up=1 y gauge4+4; los timestamps originales de muestra tenían5,308s/28,390s de edad y coincidían con lastScrape a menos de2ms. No se infiere frescura del timestamp de evaluación de PromQL. La comprobación sólo consultó configuración y datos cached; no forzó scrapes, recargó el servicio ni consultó aplicaciones públicas.

Las reglas se prepararon después, con baseline de 27 jobs y un contrato privado propio:

  • CloudflaredNoConnections: gauge cero con scrape sano durante 2 minutos.
  • CloudflaredMetricsMissing: 5 minutos de scrape fallido, gauge ausente o retirada de un target esperado; también cubre la desaparición del job entero.

La validación nativa comparó semánticamente todas las reglas anteriores con las cargadas usando el formatter del servidor 3.15.0 y comprobó reglas/config con promtool antes de escribir. La aplicación posterior cambió sólo el archivo de reglas, conservando su inode/owner/modo y toda la configuración 37ab. El camino exitoso exige dos evaluaciones nuevas y sanas tras la recarga, dentro de 75 s. Tardó 47,9 s; backup previo conservado y rollback innecesario. Combinado SHAaf54ed71…; no se ejecutaron pruebas de notificación ni fallos sintéticos.

Recibos seleccionados privados:

Fase Evidencia
Aplicación job27 ct217-cloudflared-manual-20261021-pk3w1gpm/apply-native.json, SH
Scrapes independientes cloudflared-consumer-readback-98s0tt_n/native.json, SH; peer9e1a27d8…
Validación reglas ct217-cloudflared-rules-plan-20261021-547q790s/validate-native.json, SH
Aplicación reglas Mismo directorio, apply-native.json, SH; peer09ca8193…

El readback independiente de las 23:40:27 cerró la comprobación: 23 grupos, 94 reglas y 94 evaluaciones sin error; todas las semánticas cargadas coinciden. Las dos alertas nuevas avanzaron de 23:39:53.749 a 23:40:23.749, posteriores a la recarga de las 23:31:14. Configuración de 27 jobs, PID, montajes y full9 se conservaron; el archivo de reglas tiene 42997 B, mismo inode1029537/owner1000/modo y SHAaf54. Ambos targets siguenUP/up1/gauge4+4, con muestras originales de28,465s/21,547s y coherencia con lastScrape inferior a 2 ms. Cero escrituras, recargas o avisos durante esta lectura. Recibo cloudflared-rules-readback-2e5hmaw1/native.json, SH; peer.

La recuperación futura retira primero el grupo de reglas con su recibo y baseline de 27 jobs; después puede retirar el job con su recibo original y contrato594. No se reescriben esos recibos ni se retiran ACL/listeners como efecto lateral. La entrega de avisos, la caída del propio CT217 y la continuidad pública de VIP/TLS/auth/backends siguen teniendo cobertura pendiente. Esta observación no acredita N−1 completo ni resuelve el watchdog.

Nuevo incidente17:07 y recuperación observada

El kernel de e269 registra una razón de reset AMD compatible con expiración del watchdog hardware. El btime 1792595246 corresponde a las 17:07:26 CEST: es el inicio del kernel, con resolución de 1 s, no el instante exacto del reset físico. pmx51 conserva el boot <REDACTED_UUID>. La captura finita de las 16:31–16:33 fue una línea base sana y había terminado; no cubre este incidente.

La lectura de las 17:13:22–30 fija ambos boots y cuatro inventarios idénticos: 28/28 huéspedes running, 14 recursos HA started en pmx51, 14 réplicas enabled OK/fail0 y quórum de 3 votos/2 necesarios en ambos. La raíz/appdata de 220 tiene réplica 220-0 OK; sus seis bibliotecas continúan en NAS compartido. Se observó el mount NFS exacto, raíz / y solo lectura en ambos hosts, sin acceder a medios. Esto acredita recuperación de infraestructura y metadata; no estabilidad, reproducción o N-1.

El journal seleccionado del boot bff, mux/LRM/CRM de las 17:05–17:08, terminó correctamente con cero filas retenidas. No prueba ausencia de eventos ni decisión de fencing. En el superviviente sí quedaron 24 filas en la ventana 17:05–17:10: pérdida de alcanzabilidad a las 17:07:09,352518, aviso de token ausente 7500 ms a las 17:07:09,877113 y recuperación de alcanzabilidad a las 17:07:45,755525. Entre las dos marcas del mismo reloj transcurren 36,403007 s. Es pérdida de comunicación observada, no prueba de carrier físico, causa del bloqueo o self-fencing. Las clases quorum exportadas no fijan dirección ni miembros; no se infiere pérdida de quórum propia.

Antes de ese arranque no se habían aplicado máscaras WP, onboot0, parada del CT ni cambios Caddy/Jellyfin. La retirada del target WP en Prometheus/pmx51 sí se aplicó a las 17:06 y se verificó a las 17:08. La cronología no demuestra relación causal. Los planes del boot bff se preservan sin ejecutar; cualquier nueva actuación usa admisión explícita e269 y las nuevas identidades de huéspedes/procesos.

Recibo privado bajo ~/.local/state/ SHA256
watchdog-e269-reset-20261021-jl21w7n9/kernel-reset.json <REDACTED>
Mismo directorio, prior-unit-journal.json <REDACTED>
Mismo directorio, survivor-journal.json <REDACTED>
postreset-e269-cluster-jellyfin-20261021-t8om6o4k/receipt.json <REDACTED>

Autoridad y frescura de los indicadores de reset

El literal x86/amd: Previous system reset reason [0x02000800] procede de la inicialización de CPU AMD. En la tabla de Linux, bit25 indica expiración del watchdog; bit11 no tiene descripción. Es distinto del registro SP5100 FIRED, cuyo bit1 se convierte en WDIOF_CARDRESET=32. Las relecturas sysfs del mismo boot devuelven el valor cacheado del driver, no nuevas expiraciones. Véanse la decodificación AMD, el probe SP5100 y el sysfs cacheado.

Existe una corrección histórica relevante: algunos bits AMD podían conservar una razón antigua y ciertos resets no los actualizaban. El commit oficial e6416c2, de15oct2025 añade la escritura de borrado W1C durante el arranque. Linuxv7.0 ya la contiene; esto no demuestra que el kernel instalado esté afectado por aquel defecto.

La evidencia local acredita kernel y vermagic7.0.14-19-pve. El bump oficial de ese paquete y el árbol cacheado señalan fuente Ubuntu68e0cc19…, pero las dos rutas exactas de fuente downstream no estuvieron accesibles. No están acreditadas la inclusión exacta del clear en el binario instalado ni su eficacia en el hardware actual. La referencia histórica7735HS tampoco sustituye a una medición CPUID nueva.

La lectura sigue siendo compatible con un reset reportado por watchdog, sin identificar cliente, bloqueo de CPU, firmware o fallo físico que lo originó. La siguiente comprobación de esta salvedad es obtener los dos archivos exactos amd.c y sp5100_tco.c y sus parches; no requiere otra captura ni cambiar el kernel. Revisión privada watchdog-reset-status-primary-20261021-n5mnn6jl/receipt.json, SH.

Jellyfin: recuperación en un único nodo y protección de montaje

CT220 ya tiene HA started: prefiere pmx51 y admite pmx50, una sola instancia. El ensayo gestionado por HA del 19 de octubre incluyó reproducción por CPU en pmx50 y retorno VAAPI a pmx51. Fue una migración controlada, no una caída física ni una prueba actual de clientes/medios. TV gateway 110 continúa estricto en pmx51 y su continuidad para el cliente TV queda por comprobar.

PR115, main <REDACTED>, añade exclusivamente al arranque ordinario de220 RequiresMountsFor=/mnt/nas/media y una comprobación local de /proc/self/mountinfo hasta EOF: mountpoint exacto, export esperado, raíz/, NFS/NFS4 y ro. No accede al NAS ni acredita que responda. Once pruebas y peer independiente pasan; CI 5/5 PASS. No inicia/reinicia/monta el contenedor. La dependencia también puede detener 220 si su unidad de montaje se detiene explícitamente; debug queda fuera del alcance del arranque HA ordinario.

Convergencia mediante Ansible-pull ordinario comprobada en ambos nodos: pmx51 terminó a las 17:17:15 y se leyó a las 17:17:31; pmx50 terminó a las 17:29:21 y se leyó a las 17:29:40. Fuente, helper/drop-in y dependencias cargadas coinciden, NeedDaemonReload=no. No se forzó pull ni se inició, reinició o montó nada. Queda protegida la ruta del próximo arranque; no equivale a failover funcional probado. Recibo jellyfin115-convergence-e269-20261021-voet1tvo/closure.json, SHA256 <REDACTED>. La aceptación metadata-only del guard instalado pasó en ambos nodos a las 17:53:53–56: una ejecución por host, rc0/ready/stderr0, con hashes, boots y propietario antes/después idénticos. No se inició Jellyfin ni se accedió a medios. Recibo jellyfin115-installed-guard-acceptance-20261021-1bz3i0bf/receipt.json, SHA256 <REDACTED>.

Retirada WP-Pulse: fases reales

Fuentes y guardas anti-despliegue fusionadas en PR114/main 520b327, CI 7/7 PASS. Prometheus: a las 17:06:44–46 retirado un único target WP, conservando 26 jobs, toda otra configuración y el token HA en RAM. RULES no cambió bytes/full9. A las 17:08:17–19 quedaban 0 series WP y WPPulseDown inactive/healthok. Su regla runtime residual es inerte al usar ==0 sin absent; la fuente ya la retira. No se activó el helper Cloudflared ni se cambió otra alerta.

Tras el nuevo reset, Caddy usa admisión e269/861. Aplicación rolling de 270 a las 17:17:50 y 271 a las 17:18:47: cinco imports retirados del archivo vivo yseis rutas WP retiradas del JSON admin. Todos los demás objetos cargados, autenticación ylogging se conservaron. Un único POST por nodo, sin incertidumbre. El archivo en disco yel admin conservan por separado sus objetos ajenos; una futura adaptación del archivo puede retirar logging derivado de WP. No se declara equivalencia completa entre file-adapt y admin ni se resuelve esa diferencia con cambios ajenos.

Backups/configuraciones privadas y recuperación parcial se conservan dentro de cada huésped. No se tocaron WordPress productivos externos, datos, discos, secretos ni copias. Diez unidades propias quedaron enmascaradas a las 17:22:36. La parada usó una única petición, sin force ni reintento. El observador inicial terminó uncertain durante el seguimiento; no se reinterpretó como éxito. La lectura independiente a las 17:30:43 encontró el UPID stopped/exitstatus OK; a las 17:31:31, API PVE y pct status confirmaron stopped/onboot0, resto de config idéntico, otros 27 huéspedes y 14 recursos HA sin cambios. Se preservaron ocho comandos de lectura pendientes y los backups de recuperación parcial.

Nueva lectura conjunta a las 17:33:53–17:34:15, epochs e269/861 y WP281 stopped/onboot0 antes y después: MemAvailable mínimo del receptor 14.994,38671875 MiB − demanda máxima RAM+swap de los diez migrables 12.265,015625 MiB − reserva 2.048 MiB = +681,37109375 MiB. Incluye Jellyfin220. Fórmula, cuatro inventarios y PID/start/cgroups comprobados por root y peer independiente. Es una envolvente instantánea positiva; no prueba picos, arranque conjunto ni estabilidad. Los cuatro recursos estrictos y los servicios sin HA no adquieren cobertura por este resultado. No se atribuye ahorro causal entre los boots bff y e269 ni se confunde RAM residente con memoria recuperada.

Recibo privado SHA256
wp-prometheus-retirement-20261021-bpf4r2_b/applied.json <REDACTED>
Mismo directorio, stale-readback.json <REDACTED>
wp-retirement-e269-20261021-8srb4qx6/caddy270-applied.json <REDACTED>
Mismo directorio, caddy271-applied.json <REDACTED>
Mismo directorio, stopped-independent.json <REDACTED>
Mismo directorio, post-comparison.json <REDACTED>
nminus-native-e269-after-wp-20261021-gx87hpft/calculation.json <REDACTED>

RAM física y RAM utilizable, 17:36 CEST

SMBIOS type17, leído exclusivamente por sysfs, declara en ambos nodos dos módulos de 16 GiB: 32 GiB instalados. La lectura de /proc/iomem calcula la unión de intervalos System RAM; las reservas de espacio de direcciones no se tratan automáticamente como DRAM instalada. No se accedió a /dev/mem ni se cambió BIOS, GRUB, RAM o watchdog.

Nodo Instalado SMBIOS System RAM del mapa MemTotal Linux
pmx50 32 GiB 29,747883 GiB 28,493862 GiB
pmx51 32 GiB 31,784492 GiB 31,128338 GiB

pmx50 tiene aproximadamente 2,634 GiB menos utilizables que pmx51. Su gap 32→System RAM es 2,252117 GiB y System RAM→MemTotal otros 1,254021 GiB. Esta proyección no identifica la causa concreta, ni acredita UMA/BIOS como motivo. La reserva no es equivalente a caché de Linux que se pueda contar como RAM libre. Recibos physical-memory-20261021-x66mw0bc/pmx.json SHA256 <REDACTED> y pmx2.json SHA256 <REDACTED>.

Comprobaciones posteriores: reservas y última franja Pulso

Reserva de captura de fallos identificada

La lectura posterior de metadatos (memory-reservations-20261021-q6ty3l2g) fija 640 MiB de Crash kernel en pmx50, coherentes con el parámetro crashkernel presente; pmx51 no tiene ese parámetro ni esa región. La documentación del kernel sobre kdump explica su propósito: memoria reservada para el kernel que captura un fallo. La reserva no se retira ni se cambia mientras se investiga la inestabilidad.

El mapa cacheado de firmware ya declara aproximadamente 2,0366 GiB menos de System RAM en pmx50 que en pmx51, antes de las reservas Linux. Para pmx50 se puede separar 32→28,493862 GiB en: 2,252117 GiB fuera de System RAM, 0,625 GiB de crashkernel y 0,629021 GiB de otra contabilidad del kernel todavía sin atribuir. Todos los bloques declarados están online; HardwareCorrupted, HugeTLB y CmaTotal reportan cero. CmaFree no concuerda con CmaTotal y no se usa para inventar una reserva. Esto no identifica el propósito de las reservas de firmware ni prueba que sean UMA. No hubo cambios, reinicios, acceso a /dev/mem o pruebas hardware.

Recibos memory-reservations-20261021-q6ty3l2g/pmx.json, SHA256 <REDACTED>; pmx2.json, SHA256 <REDACTED>.

Pulso retenido antes del reset17:07

Una única lectura a las 17:49:28 del log existente de pmx51 seleccionó 96 muestras del boot bff, desde 17:05:26 hasta 17:07:02, y el primer paquete e269 a las 17:07:38. El receptor/PID/start y el snapshot local de 16 MiB quedaron fijados; no se activó colector ni captura. Los timestamps son de recepción.

Mux1485/start473 y CRM1913/start793 avanzaron runtime en 95/95 intervalos; LRM2008/ start2070 en 19/95, último avance a las 17:07:00 y pausa máxima de 5 s, sin campos desconocidos en los roles antiguos. La última muestra reportaba lag 0,01 s, load 0,57, PSI cpu/mem/io 0,00 y MemAvailable 14013 MiB. No aparece saturación sostenida anterior al último paquete. Actividad de CPU no prueba KEEPALIVE, entrega al mux ni alimentación física del watchdog.

Hay 36 s entre el último paquete viejo y el primero nuevo; btime 17:07:26 deja 24 s sin observación antes de comenzar el kernel. Esa referencia usa el reloj del otro host y no fija cuándo ocurrió el reset físico. El cese de Pulso es compatible temporalmente con el token ausente 7500 ms observado por Corosync en pmx51 a las 17:07:09,877, pero no distingue bloqueo global, pérdida de red o fencing. No se repite la ventana cerrada ni una línea base sana para suplir ese hueco.

Recibo watchdog-e269-pulse-final-20261021-review/result.json, SHA256 <REDACTED>.

Camino del cliente TV: no asumir dependencia de 110

El ADR original de LG del 4 de mayo diseña TV y destinos locales en la misma /24: el tráfico intra-LAN usa ARP directo y no atraviesa 110. La documentación de octubre sitúa LG en .227; la dirección no procede del ejemplo del ADR. La fuente de red también declara splitDNS Pi-hole para monxas.casa hacia VIP .250. Por tanto, Jellyfin por .220 o VIP .250 puede ser local; incluso el dominio público puede resolver a VIP si el cliente usa ese DNS. 110 es el gateway para WAN, no una dependencia inevitable del acceso LAN a Jellyfin.

Faltan URL, máscara, DNS y resolución realmente usados por el cliente LG, y su comportamiento sin Internet. El siguiente ensayo debe acreditar ese camino antes de ampliar HA de 110. La fuente no documenta IPTV multicast, y el máximo de 1 GiB de 110 no equivale a demanda medida ni está incluido en el presupuesto de los diez migrables. No se consultó el TV ni se modificó red o afinidad. Análisis privado tv-jellyfin-continuity-source-20261021-5x6tjham/analysis.md, SHA256 <REDACTED>.

Incidente y recuperación del arranque de las15:16

El btime histórico de pmx50 en este apartado es 15:16:26 CEST, boot bffef9a4…; pmx51 conserva 86184726…. La consulta del kernel del boot actual, con UUID sin guiones, terminó rc0 y seleccionó: x86/amd: Previous system reset reason [0x02000800]: hardware watchdog timer expired. Esto acredita el mecanismo de reset, no el motivo por el que expiró. La lectura acotada posterior conserva identidad SP5100 TCO timer, bootstatus32 y timeout10, sin abrir /dev/watchdog, ioctl, trazas o cambios de política. El heartbeat60 de inicialización del kernel y el timeout10 cacheado son observaciones de fases distintas, no una prueba de configuración defectuosa. Las firmas de journal no coincidentes no prueban que faltaran mensajes; su cobertura de retención queda unknown.

La consulta seleccionada de 15:47:39, bajo guarda del host bff, buscó únicamente mux/LRM/CRM en el boot74 y la ventana15:14:00–15:16:30, con límite64 filas/512KiB. Terminó rc0/stderr0 y devolvió cero filas retenidas. No acredita ausencia de eventos, cobertura de retención ni causa del reset; no se repitió la consulta.

La observación nueva 15:30:55–15:31:01 fija ambos boots antes/después y encuentra un inventario estable de28 invitados running, incluida VM208 en pmx50, observada sólo por PVE. Ambos nodos declaran quórum:2 nodos,3 votos presentes de3 esperados y2 requeridos. Los14 recursos HA están started en pmx51 y el CRM declara fencing armado. Los14 trabajos de réplica fuente de pmx51 reportan OK/fail_count0; no se ejecutó ningún trabajo. Réplica no equivale a backup, y running/started no acredita funcionamiento de aplicaciones.

CT219 permanece en pmx50 como LXC running. Se observa un nuevo arranque del mismo huésped, boot <REDACTED_UUID>, proceso292/start2908 e InvocationID <REDACTED>; no es el PID292 del boot anterior. Binario 2026.10.1 y argv hash coinciden con la fuente observada; NRestarts1 se registra sin atribuirle causa. El config328bytes, ACL623, ORDER55 y binding138 conservan contenidos y hashes esperados. La tabla propia es semánticamente exacta; nftables está active/exited, BindsTo/After están cargados y NeedDaemonReload=no. El EnvironmentFile requerido mantiene198bytes y su hash privado, sin exportar valores. Entorno cargado y proceso seleccionan.219:20241; el único socket de ese puerto pertenece al proceso actual y el gauge local vale4. Esta persistencia se observó, sin repetir apply, reload o restart. Los nuevos st_dev/full9 son observaciones: no revalidan planes mutadores ni rollback del boot74.

Recibo privado bajo ~/.local/state/ SHA256
watchdog-1516-20261021-8o0k4mlj/current-kernel-reset-selected.json <REDACTED>
watchdog-final-signatures-20261021-m903shc2/receipt.json <REDACTED>
postreset-bff-cloudflared-pve-20261021-mqqldu4m/pmx.json <REDACTED>
Mismo directorio, pmx2.json <REDACTED>
Mismo directorio, receipt.json <REDACTED>

Procedencia observada y siguiente captura offline

La lectura nativa de 15:50:10, con bootbff y mux1485/start473 estables, NRestarts0, fijó /proc/PID/exe en /usr/sbin/watchdog-mux:18.888bytes, SHA256 <REDACTED>. Su MD5 coincide con la entrada exacta del registro local de dpkg para pve-ha-manager5.2.5. Esto acredita consistencia con ese registro, no paquete firmado, reproducción desde fuente ni igualdad fuente→binario.

La metadata de modinfo para el archivo instalado sp5100_tco declara intree=Y y vermagic7.0.14-19-pve, compatible con uname7.0.14-19-pve x86_64. No demuestra igualdad con los bytes del módulo cargado, temporización efectiva ni que el contador físico se alimentara. No se abrió dispositivo, cargó módulo, emitió ioctl ni modificó runtime en esa lectura. La causa del reset sigue desconocida.

El diseño offline inicial, anterior a la sesión nativa descrita abajo, propuso una sesión finita del mux existente: intentos/resultados de keepalive y epoll, con boot/PID/start y reloj monotónico, correlacionados con Pulso y firmas existentes de cliente/inhibición. Prevé120s/deadline125s y límites de10.000eventos/1MiB, con pérdidas explícitas; son presupuestos propuestos, no resultados medidos. Antes de elegir técnica hay que acreditar disponibilidad y semántica nativas: no se presuponen tools, tracefs, perf/eBPF, símbolos u offsets utilizables. Esa propuesta inicial no constituía captura instalada ni una lectura proc capaz de demostrar keepalive. Si faltan puntos fiables, la brecha se mantiene abierta; no se pausa, parchea ni reinicia mux para forzar esa evidencia. No se vuelve a consultar la ventana de journal cerrada.

Evidencia privada en watchdog-binary-driver-ro-20261021-t_g00feb/, bajo ~/.local/state/: receipt.json, SHA256 <REDACTED>; capture-design.md, SHA256 <REDACTED>.

Admisión causal readonly, 18:08 CEST

El21oct18:08:08, una lectura acotada fijó el boot e269 antes y después, con kernel7.0.14-19-pve. No creó instancias de traza, abrió el dispositivo, emitió ioctl, cambió política ni reinició servicios. Confirma timeout10, identidad SP5100 TCO timer y bootstatus32. El kernel de captura está cargado (crash_loaded=1), con671.088.640bytes reservados; esto no demuestra que un reset físico alcance panic/kexec ni que haya un vmcore nuevo.

Los12formatos consultados de syscalls (entrada/salida de ioctl, epoll_wait, read, write, close y accept4) son legibles y sus hashes quedaron guardados. La fuente5.2.5 usa accept, no accept4: esta lectura no admite todavía la observación de nuevas conexiones del mux. No se infiere la recepción de un ping del cliente a partir de una escritura exitosa de éste, ni cierre mágico por el tamaño de una lectura. Hace falta relacionar FD, identidad y recepción.

La lista nativa de funciones trazables contiene los nombres exactos watchdog_ioctl, watchdog_ping y __watchdog_ping. No aparecieron los nombres exactos sp5100_tco_timer_ping/sp5100_tco_timer_start; eso no demuestra que el controlador carezca de cualquier punto instrumentable. El atributo sysfs pretimeout está ausente; no se anuncia ni configura esa capacidad.

Esta admisión aporta disponibilidad de puntos, no cobertura causal ni permiso automático de activación. El siguiente diseño debe conservar retorno/duración de epoll, última renovación recibida por cliente y motivo de inhibición, además de intento/resultado de ioctl. La fuente alimenta sólo en la rama nfds==0: actividad continua puede impedir llegar a esa rama sin que expire un cliente; es una hipótesis comprobable, no una causa observada. Una copia numérica fuera del nodo debe declarar pérdidas y huecos, sin convertir el silencio UDP/SSH en prueba de bloqueo global. Se mantienen los límites de la captura anterior hasta revisar un diseño nuevo; no se repite una línea base sana por defecto.

Recibo privado watchdog-causal-capabilities-20261021-pcuns0f2/result-v3.json, SHA256 <REDACTED>. Los dos primeros intentos readonly rechazaron un alias sysfs de kexec por O_NOFOLLOW, antes de completar la inspección. El tercero admitió el destino sysfs seleccionado y terminó exit0/stderr0. Los intentos fallidos no se cuentan como admisiones completas ni activaron trazado.

Tramo kernel–controlador disponible, 18:13 CEST

Una segunda lectura, sólo de capacidades nuevas y con el mismo boot e269 antes/después, encontró los formatos estáticos watchdog:watchdog_ping, watchdog_start, watchdog_stop y watchdog_set_timeout. Los tres primeros exponen id/err; el último añade timeout. También encontró los nombres trazables correctos tco_timer_ping, tco_timer_start y tco_timer_get_timeleft. La primera consulta usó otros nombres exactos y no podía resolver esa disponibilidad. No se activó ninguno de estos puntos.

En watchdog_dev.c upstream v7.0, __watchdog_ping emite el evento después del retorno de ops->ping. Es un punto propuesto para distinguir la petición de usuario del retorno del controlador, sin crear probes dinámicos. El diseño debe admitir los formatos nativos y registrar el dispositivo0 incluso cuando intervenga un worker del kernel: filtrar sólo el PID del mux podría ocultar esa ruta. No se ha cotejado cada parche del kernel PVE con esa fuente upstream.

El controlador upstream SP5100 v7.0 usa tco_timer_ping: lee el control, escribe el bit de disparo y devuelve0. Observar ese retorno todavía no mide que el contador físico se haya renovado. No se propone leer MMIO, abrir /dev/watchdog ni emitir una llamada de prueba.

Recibo privado watchdog-causal-capabilities-20261021-pcuns0f2/kernel-link.json, SHA256 <REDACTED>, observado21oct18:13:02 CEST, exit0/stderr0. Es disponibilidad para el siguiente diseño; no captura del incidente ni corrección de la causa.

Retorno del controlador y entrega externa verificados, 18:40–18:41 CEST

PR116, main05872d5, añadió streaming numérico finito y receptor privado. PR117, main<REDACTED>, añadió los cuatro eventos estáticos watchdog, protocolo2 y recuperación explícita de ocho eventos. Cada PR pasó cinco checks; la segunda acumula84pruebas offline y revisión independiente. Ambas fuentes quedan inactivas por defecto y fuera de Ansible-pull.

Una admisión readonly separada fijó el boot e269, muxPID1489/start502, binarioSHA087af87e…, FD3, dispositivo0 y los ocho formatos actuales. El alias legacy char10:130 difiere del nodo watchdog0 char243:0, coincidente con sysfs; la relación legacy→id0 se contrastó con la fuente Linuxv7. Los filtros PID de la instancia propia estaban vacíos y su máscara cubría los16CPU online. No se abrió el dispositivo, emitió un ioctl de prueba ni cambió política HA.

Root ejecutó una única validación nueva de90s, con inicio18:40:14,396 CEST, exportando al Mac desde el principio. El receptor exigió boot/PID/start y protocolo2, archivosEXCL600 y secuencia completa. El límite de la herramienta sigue siendo120s: esta sesión valida señales nuevas y su entrega, no repite la captura anterior como prueba del incidente17:07.

Observación seleccionada Resultado
Duración observada 90,016230s
Eventos / frames de entrega 450 / 452
Pares KEEPALIVE con retorno0 90
Callbacks watchdog_ping con err0 90
Callbacks observados en otro TID 0
Errores / pérdida detectada 0 / 0
Pares epoll interiores 89
Mayor intervalo ioctl / callback 1,001227 / 1,001226s
Ring propio total 304KiB
CPU del lector 0,205088s (~0,228% de un CPU)

Los90callbacks observados llevan el TID del mux y caen dentro de sus pares ioctl completos. Es una correlación observada en esta sesión; no se impone esa correspondencia a workers diferidos. No hubo eventos start/stop/set_timeout. Se conservan una salida epoll inicial sin entrada y una entrada final sin salida: no se afirma cobertura completa de esos bordes. El coste indicado es sólo del lector, no el coste total kernel/transporte ni una garantía de perturbación cero.

El receptor recibió terminal completo; la reconstrucción de sus450objetos numéricos coincide por SHA con events.jsonl del nodo. Workerexit0, supervisor y receptor terminados, cleanup verificado e instancia propia ausente. Seis controles globales conservaron los hashes de admisión; máscaras y filtros de cobertura se comprobaron antes/durante/después. No queda un observador activo ni un daemon.

Esto prueba retorno de callbacks y entrega finita fuera del nodo. No acredita el contador físico, no cubre el reset17:07 y no identifica su causa. Todavía faltan recepción/decisión de clientes HA y evidencia conservada durante un fallo. No se programa ni repite automáticamente otra sesión.

Evidencia privada en watchdog-static-native-20261021-_4a7iuhk/:

Artefacto SHA256
admission.json <REDACTED>
post-readback.json <REDACTED>
independent-analysis.json <REDACTED>
Objetos numéricos reconstruidos / archivo remoto <REDACTED>

Binario exacto y decisiones del mux: análisis offline, 18:55–19:03 CEST

La lectura de ELF de las 18:55 fijó e269, mux 1489 / start 502 y el ejecutable de 18.888 bytes con SHA256 <REDACTED> y GNU build-id <REDACTED>. El ELF está stripped: no tiene .symtab ni .debug_info; sí contiene .gnu_debuglink. No aparecieron los símbolos seleccionados. Los dos destinos debug concretos comprobados después estaban ausentes; eso no demuestra que no exista un artefacto debug en otra fuente.

Se obtuvo del paquete público 5.2.5 una copia del ELF cuyos bytes/SHA coinciden exactamente con ese ejecutable, sin instalar, ejecutar ni extraer scripts del paquete. El índice firmado no fue verificado: se acredita identidad por hash con el binario observado, no procedencia criptográfica del repositorio ni una compilación reproducible desde toda la fuente.

El análisis estático de instrucciones, cadenas y flujo de control identificó dos stores directos de 0 al mismo dato inicializado en 1: uno en la ruta de caducidad de cliente y otro en la desconexión sin cierre mágico. También localizó el store de tiempo tras una lectura positiva. Esto hace concreto el diseño para observar esas decisiones; no demuestra que se ejecutaran durante un reset, que se hayan encontrado todas las escrituras indirectas o quién era cada cliente. Los offsets ELF no son direcciones vivas bajo ASLR y no se publican como un punto de instrumentación admitido.

Este análisis no registró ni admitió ningún uprobe. El diseño posterior sólo plantea eventos seleccionados sin fetch de registros, memoria o payload, y requiere revisión de propiedad/registro global, aislamiento, coste y recuperación. Llegar al sucesor de un store no equivale por sí solo a demostrar cualquier valor actual ni todos sus posibles caminos de entrada. No se instala debug ni se usa un símbolo de otra compilación para suplir la falta de mapping comprobado.

Inspección nativa de viabilidad de uprobes: lectura, no admisión

La inspección posterior del 21 de octubre, aproximadamente a las 19:18 según el recibo del coordinador, ejecutó el lector revisado SHA256 <REDACTED>. Los cuatro módulos fijados se cargaron por stdin en RAM con Python -B, sin instalar archivos en el nodo. La fuente estaba publicada en PR 119, cabeza a0dc64e, todavía sin fusionar y con CI pendiente en ese instante. Después se integró a las 19:19:38, main <REDACTED>, con cinco checks correctos. El lector sigue inactivo por defecto y fuera de las tareas del rol: esa integración no lo instala ni ejecuta por Ansible-pull.

El resultado fue rc0, sin stderr: e269, PID 1489 / inicio 502, FD 3 y ELF exacto se mantuvieron antes y después. Tracefs estaba montado; uprobe_events se leyó hasta EOF con 0 bytes y 0 definiciones. Los dos snapshots de registro, controles y ocho formatos conocidos coincidieron. El control genérico events/uprobes/enable devolvió ENOENT; se conserva como ausente, sin inferir que el kernel no pueda registrar eventos nuevos.

Esta lectura no admite registrar o activar probes. Exclusión de otros escritores, prueba de registro, formatos de nuevos uprobes y admisión permanecen false. Tampoco hubo captura, apertura del dispositivo, ioctl o escrituras de tracing/runtime. Un registro vacío durante dos lecturas no prueba exclusión de escritores entre ellas ni proporciona una operación CAS/EXCL. Las señales syscall/watchdog ya disponibles siguen siendo contexto, sin iniciar otra sesión.

Recibo privado watchdog-uprobe-ro-launcher-20261021-j51z4qey/native-output.json, SHA256 <REDACTED>.

Pulso contextual: preflight y convergencia verificada, 19:07–19:19 CEST

La fuente revisada SHA256 <REDACTED> añade mux_obs=v1 al mismo paquete Pulso, conservando ha_proc=v2. Exporta sólo PID/start, secuencia, tiempo monotónico, presencia 0/1/? del marcador y cantidades de descriptores de archivo (FD), FD socket e inodos socket distintos. Doble proyección dentro de la misma guarda de PID/start, límites de 128 FD / 256 caracteres / 50 ms y errores como unknown; los enlaces quedan en RAM. El emisor conserva completos ambos bloques antes de la cola variable dentro del límite de 1400 bytes. Ochenta y dos pruebas offline y peer independiente pasan. PR 118 se integró a las 19:09:36, main <REDACTED>, tras cinco checks correctos. La integración de fuente no sustituye el cierre de convergencia descrito abajo.

Marcador presente no acredita cliente vivo ni inhibición; ausente no prueba cero clientes porque mux 5.2.5 no comprueba el retorno de mkdir/rmdir. Los sockets de journald también cuentan. Dos proyecciones iguales a 1 Hz pueden perder transiciones o ABA, y un fork de journalctl en el cgroup del mux deja el rol unknown. Estos contadores no se denominan client count, ni prueban recepción de pings, decisión interna o estado físico del watchdog.

El preflight nativo seleccionado de las 19:07 ejecutó una proyección del candidato sin enviar red ni escribir runtime. Con e269 y mux 1489 / start 502 estables observó marcador 0, 7 FD, 3 FD socket y 2 inodos socket distintos en 1,319275 ms. Es coste de esa única muestra, no un límite garantizado ni evidencia continua. El emisor vivo seguía con SHA 2750306f…; el candidato todavía no estaba desplegado. En la fuente sólo pmx50 es TX y pmx51 RX. El ciclo ordinario de Ansible-pull, iniciado a las 19:18:15, terminó exit0/inactive y dejó el nuevo SHA instalado. La lectura de las 19:19:10 encontró TX activo con PID 183436 y NRestarts=0; mux 1489 / inicio 502 continuaba sin cambios. No se forzó pull ni reinicio manual.

A las 19:19:15, pmx51 conservaba boot 861, receptor PID 1559 y mux PID 931 con sus inicios y estados iguales antes/después. El tail local acotado a 65.536 bytes contenía 29 bloques nuevos; los tres exportados, recibidos a las 19:19:12–14, llevan secuencias 27–29, marcador 0, 7 FD, 3 FD socket y 2 inodos socket distintos. Las líneas recibidas miden 763–766 bytes, incluyendo el prefijo del receptor; los bloques seleccionados están completos. Esto cierra instalación y recepción de la extensión mediante el ciclo ordinario, no persistencia tras otro reboot, continuidad futura, recepción de pings HA o causa de los resets.

Recibo privado bajo ~/.local/state/ SHA256
watchdog-client-elf-20261021-fv9816zt/result.json <REDACTED>
Mismo directorio, debug-paths.json <REDACTED>
watchdog-elf-offline-20261021-467sy5i0/analysis.json <REDACTED>
Mismo directorio, uprobe-design.json <REDACTED>
pulse-mux-native-20261021-wbp_0vra/pmx-preflight-v2-output.json <REDACTED>
Mismo directorio, sender-readback-output.json <REDACTED>
Mismo directorio, receiver-readback-output.json <REDACTED>
Mismo directorio, closure.json <REDACTED>

Línea base del mux, 16:31–16:33 CEST

La PR113, maina355fb2, pasó32pruebas offline en Python3.12/3.14 y cinco checks. Después de una admisión readonly independiente, root completó una sesión nativa finita de16:31:27,665 a16:33:27,831, sin repetir ni provocar fallo. Bootbff, mux1485/start473 y exeSHA conservaron identidad. El resultado aporta evidencia nueva de la ruta normal de alimentación del mux, sin cerrar el incidente15:16.

Medida seleccionada Resultado
Pares interiores KEEPALIVE con retorno0 120
Errores / pérdida / pares interiores incompletos 0 / 0 / 0
Mayor intervalo observado entre retornos correctos 1,001135s
Pares interiores epoll 119
Eventos numéricos / bytes 480 / 19.920
Borde epoll inicial / final Una salida sin entrada / una entrada sin salida
Ring solicitado / real por CPU / total 16 / 19 / 304KiB

La cuantización del ring quedó comprobada sin relajar el límite total512KiB. El lector consumió0,191235s de CPU en120,021831s (~0,159% de un CPU); esto no mide todo el coste kernel ni prueba perturbación cero. La reserva transitoria previa era una estimación, no una medida del pico de asignación. El supervisor terminó exit0 y limpieza verificada, instancia propia retirada y los seis controles globales con hashes idénticos antes/después. No queda un observador permanente ni un job nuevo. La fuente permanece inactiva por defecto.

Es una línea base de120s, no una captura del fallo ni una causa demostrada. Los bordes se declaran incompletos y sólo los pares interiores aportan evidencia. Retval0 no mide el contador físico; faltan último ping/decisión de cliente y la cadena anterior al reset. No se desarmó HA, cambió timeout ni reinició el mux. Recibo privado ~/.local/state/watchdog-keepalive-native-20261021-t08rshqd/receipt.json, SHA256 <REDACTED>. La revisión offline verificó las proyecciones y reparseó independientemente los480eventos numéricos:480=240+238+2, FD3/requestexactos/retorno0, sin huérfanos interiores y máximo1.001.135.000ns. No volvió a consultar el nodo. Archivo numérico SHA256 <REDACTED>.

Reinicio manual previo: fase3 UNKNOWN preservada

Después de la fase2, se emitió una sola orden systemctl --no-block --job-mode=fail restart cloudflared.service en CT219, entre15:14:50 y15:15:26 CEST. La hora exacta quedó en el recibo durable del huésped phase3-restart-attempt.json; no se exportó. El supervisor observó job218→0 y sólo un PID nuevo,583. Su último estado, 15:15:26,299, era active/running, NRestarts0, Result=success, ExecMainStatus0 y NeedDaemonReload=no; InvocationID <REDACTED> y ExecMainStartTimestampMonotonic4566872464. La ventana acotada agotó su plazo; no quedaron acreditados en ese recibo start_ticks583, socket, gauge o las comparaciones finales de identidad/token. Un último error transitorio no localiza el check del proceso nuevo ni demuestra un fallo persistente suyo. La causa precisa del timeout queda sin demostrar.

CT123 conservó4 conexiones y la misma unidad entre15:14:50 y15:15:31. El primer readback posterior deCT219 abortó por la guarda del host tras el reset real. Se preservan el UNKNOWN y el fallo de guarda, sin otro restart, rollback, retirada de ACL o traslado silencioso de guardas. La lectura de recuperación anterior pertenece al nuevo epoch y no convierte la fase3 histórica en PASS. La proximidad temporal entre la orden y el reset no acredita causalidad.

Recibo privado cloudflared-ct219-rollout-20261021-7v5abjzl/phase3-HOLD-closure.json, SHA256 <REDACTED>. El phase3-result.json original conserva SHA256 <REDACTED>; el fallo de readback phase3-independent.json, SHA256 <REDACTED>.

Cierre de red, 15:42 CEST

Evidencia histórica del boot bff. Una guarda PRE 15:37:12 y otra POST 15:42:20 enmarcan las pruebas únicas de 15:41:22–26. Los campos seleccionados son idénticos salvo fecha: boots bff/0e227506, propietario/tipo/estado PVE, PID292/start2908/InvocationID, argv/binario, full9 y hashes de archivos, EnvFile, ACL exacta, dependencia, socket único.219:20241 y gauge4→4. No se reconfiguró CT219 durante esas lecturas.

Desde CT217 se obtuvo HTTP200 y gauge4 mediante un único GET nativo. Desde pmx51/.51, una conexión TCP agotó2,5s mientras un ping tuvo respuesta. Son los resultados de esas rutas concretas, compatibles con la ACL; no prueban todos los orígenes, IPv6, rutas públicas, autenticación o backends. CT123 no se modificó. El listener LAN sí está activo, protegido por la tabla observada; que el contrato global siga pendiente no significa listener inactivo. No se promueven gates ni se activa consumidor/alertas por estos recibos.

Recibo privado bajo ~/.local/state/ SHA256
cloudflared-acl-network-bff-20261021-x2w14p25/receipt.json <REDACTED>
cloudflared-bff-network-guards-20261021-jatx5a16/pre.json <REDACTED>
Mismo directorio, post.json <REDACTED>
Mismo directorio, receipt.json <REDACTED>

Cloudflared: revalidación de metadatos y salud nativa, 20:32–20:38 CEST

La lectura nueva de 20:32:58–20:33:10 conserva propietarios/tipo/estado PVE y boots antes/después de cada huésped: CT219 en pmx50/e269 con guest 41dca5bb…; CT123 y CT217 en pmx51/861 con guests 1f77b833… y f96a8cfc…. Los tiempos proceden de observed_utc con conversión Europe/Madrid, no de un offset supuesto. Son observaciones enmarcadas por guardas, no un snapshot atómico común.

CT219 estaba active/running, PID292/start3137, NRestarts1 y NeedDaemonReload=no. Conserva listener propio 192.168.0.XXX:20241, tabla ACL exacta, include/config/drop-ins con sus identidades/hashes y dependencia After/BindsTo de nftables. Esto revalida persistencia seleccionada en e269; no convierte la fase3 UNKNOWN histórica en PASS ni acredita una causa del reset. No se cambió ni reinició219, no se leyó el contenido privado del EnvironmentFile y la huella del path del ejecutable no se presenta como hash de sus bytes.

CT123 sigue active/running, PID129/start3011, NRestarts0, con socket propio 127.0.0.1:20241, sin ACL dedicada ni bind LAN nuevos. No se consultó su gauge en esta ronda. En CT217, Prometheus conserva container/StartedAt/PID1181@8461, network_mode host y mismo netns; ambas rutas seleccionadas hacia .207 y .219 usan origen .217 por eth0. La ruta no demuestra conectividad HTTP ni aceptación por la ACL. No se hizo GET desde217 ni prueba actual de origen denegado.

Después del peer de metadatos, una lectura nativa separada de CT219 a las 20:38:09,583 CEST devolvió HTTP200 y gauge4, con proyección completa antes/después idéntica al baseline de20:32:58. Fue un único GET al socket nativo acreditado .219:20241/metrics, sin proxy, redirect ni retry, con timeout/cap y sin exportar métricas brutas. No hubo peticiones públicas, backends o productos. El closure de20:33 conserva correctamente health_verified=false porque precedía ese GET; el recibo posterior amplía la evidencia sin reescribirlo.

No se modificaron CT219/123, consumidor Prometheus ni alertas. La comprobación allow/deny de15:41 pertenece al boot bff y continúa histórica; no se reutiliza como admisión actual ni se acreditan rutas públicas, autenticación o E2E. El gauge actual sólo acredita conexiones nativas de219; el antiguo4+4 no se promueve a una comprobación actual conjunta. La centralización sigue pendiente.

Recibos privados bajo cloudflared-fresh-parent-20261021-qsquvhv9:

Recibo SHA256
closure.json (metadatos, sin HTTP) <REDACTED>
independent-peer-metadata.json <REDACTED>
health219-next/result.json (salud nativa posterior) <REDACTED>

CT123: apply UNKNOWN y lectura posterior, 21:13–21:32 CEST

El único apply ACL de 21:13 CEST terminó UNKNOWN en single_acl_apply; el resultado intermedio conserva unknown_preserve_acl_and_files. Se preservan ambos recibos, sin promoverlos a PASS. No se escribió el bind LAN ni se pidió daemon-reload, restart, servicio nftables global o endpoint HTTP.

La lectura de 21:32:10,939 CEST conserva antes/después propietario CT123/lxc/ running en pmx51/861, guest1f77 y el proceso cloudflared129/start3011, active/running, NRestarts0 y NeedDaemonReload=no. El listener propio sigue 127.0.0.1:20241. Están presentes los tres archivos de esta fase: payload ACL, config nftables con include y drop-in de orden; no hay drop-in de bind. Sus identidades/hashes quedaron capturados, sin repetir apply ni recovery.

La tabla propia está presente, pero su comparación normalizada con la esperada sigue siendo distinta: único path de delta $[0].table.comment:key_presence. Esto registra la diferencia observada; no establece por qué falta/sobra ese campo ni lo elimina del comparador. La ACL exacta y la exposición siguen sin admitirse. La persistencia de archivos y la continuidad del proceso no sustituyen esa admisión ni demuestran allow/deny actual, conexión desde217 o E2E. La fase123 y el bind LAN siguen abiertos; consumidor/alertas permanecen sin activar.

Recibo privado cloudflared-ct123-phase1-diagnostic-20261021-uriqu0_o/diagnostic-native.json, SHA256 <REDACTED>. La lectura no hizo cambios y conserva el UNKNOWN original.

La lectura posterior de 21:36:11 CEST, con proceso129/start3011 estable, aclara la discrepancia: nft1.0.6 omite table.comment en JSON, mientras la salida texto de la tabla propia contiene el marcador exacto esperado. No se exportó la tabla completa ni se volvió a aplicar la ACL. Esto aclara el comportamiento del verificador; la reconciliación formal sigue pendiente, con corrección de fuente en preparación. No se declara la ACL reconciliada/admitida ni se avanza el bind LAN a partir de esta lectura.

Recibo privado cloudflared-ct123-table-comment-20261021-wy6xbc5g/native.json, SHA256 <REDACTED>.

CT123: reconciliación y transición verificadas, 21:46–22:39 CEST

La PR130, main9176e2b, integra la compatibilidad estricta con nft1.0.6: sólo acepta la omisión JSON si el texto nativo tiene el marcador propio exacto y una segunda lectura JSON conserva la política. No se acepta una tabla sin marcador por su versión. La reconciliación observacional de21:52 acreditó ACL, archivos y backup exactos, con el mismo proceso129/loopback y cero aplicaciones nuevas. Su recibo nuevo 24b6c6b9… no transforma el UNKNOWN original en éxito.

La PR132, maina7f90d0, integra recuperación explícita compatible con ese recibo observado. Exige sus pins/provenancia, proceso y loopback actual/futuro; la guarda CAS del archivo30 precede a la retirada de ACL. Cincuenta pruebas en3.12/3.14, peer/root y cinco checks CI correctos. No se ejecutó rollback nativo.

A las22:14 se instaló una vez el binding50 y se solicitó una daemon-reload. El resultado fue UNKNOWN/ValueError en loaded_definition_readback, sin restart ni HTTP. Se preservan recibos y no se repiten instalación/recarga. Una lectura independiente de22:20 acreditó bindingLAN exacto, NeedReload=no, dependencias nftables, dropins30+50, argv semánticamente igual en archivo/loaded/proceso y ACL exacta. El proceso129 seguía loopback. Falta el literal anterior y no se atribuye una causa probada al fallo de verificación.

La transición siguiente y la vuelta explícita a loopback se revisaron con 18 fixtures y peer/root. A las22:39:51 una petición propia aCT219 devolvió HTTP200/gauge4 con identidad estable. Con esa salud de0,87s de antigüedad al iniciar la admisión, una sola RestartUnit deCT123, job818, acreditó a las22:39:58:

  • PID1318/start17526513 nuevo, activo y NRestarts0; padres/propietario estables.
  • Escucha actual y futura 192.168.0.XXX:20241, ACL retenida y dependencias cargadas.
  • Un GET propio HTTP200/gauge2; cero cambios de binding/reload/ACL u otro conector.
  • Recibos UNKNOWN históricos intactos; sin retry ni recuperación automática.

Recibo seleccionado privado cloudflared-ct123-phase3-xtse3pyi/native.json, SHA<REDACTED>; peer independiente3aff9592…. Esto acredita salud nativa de ambos conectores en esas lecturas, no conectividad actual desdeCT217, rechazo desde51, scrape/alertas, rutas públicas, autenticación ni backends.

Acceso aCT123 observado, 22:47 CEST

Una secuencia acotada leyó productor PRE, hizo un GET ligado explícitamente a .217, un intento TCP ligado a.51, y leyó productor POST. HTTP200/gauge4 a las22:47:47; el TCP desde51 agotó2,5026s a las22:47:51, sin HTTP ni ping. El mismo1318@17526513, unidad, ACL exacta, binding actual/futuro y propietario permanecieron iguales antes/después. Ruta del observador217 por eth0 y del nodo51 por vmbr0, estables; contenedor Prometheus hostnet/PID1181@8461 exactos. No se reintentó, modificó infraestructura ni consultó backends públicos.

Cierre privado cloudflared-ct123-network-admission-plan-20261021-gg8iwv31/network-closure.json, SHA<REDACTED>. El timeout aislado no prueba causalidad de DROP; unido al positivo y las guardas acredita el comportamiento observado para esos dos orígenes. La prueba propia deCT219 del arranque actual se detalla a continuación. Consumidor y alertas siguen sin activar; no es una prueba E2E de las aplicaciones.

Acceso aCT219 observado, 22:54 CEST

Una segunda secuencia independiente, de un GET217 y un TCP51, acredita HTTP200/gauge4 a las22:54:46 y timeout2,5023s desde51 a las22:54:50. El mismo PID292/start3137, boot41dc, ACL exacta, listenerLAN, archivos públicos y metadatos seleccionados de unidad/binding permanecieron iguales antes/después; padrepmx50 e269 y dueño219 estables. Los probes conservaron origen/ruta/netns del observador 217 y origen51. Cero escrituras, reintentos, HTTP negativo o ping.

Cierre privado cloudflared-ct219-network-admission-plan-20261021-r13deh1_/network-closure.json, SHA<REDACTED>. Estas guardas no abren el contenido privado del EnvironmentFile219: no se readmite toda la configuración de un arranque futuro por esta prueba de red. La precedencia efectiva del entorno requiere su comprobación seleccionada antes de cerrar la admisión del consumidor. Las dos pruebas de red actuales cubren los orígenes217/51, sin acreditar todos los demás orígenes, IPv6 externo, backends, scrape, carga de reglas o entrega de avisos.

Precedencia seleccionada deCT219 verificada, 23:01 CEST

Una lectura adicional de sólo lectura cerró la precedencia de métricas. El EnvironmentFile requerido tiene identidad/permisos completos y coincide en RAM con el pin privado revisado; no define TUNNEL_METRICS. El proceso292/start3137 seleccionaLAN, no tiene flagCLI de métricas y la definición futura Environment selecciona la misma dirección sin UnsetEnvironment que la elimine. Dos snapshots conservaron baseline601fe/ACL/listener/boot y propietario, sin HTTP, escrituras, recargas o reinicios. No salieron credenciales, nombres ni nuevos hashes del texto privado, sólo metadatos y resultados booleanos.

Recibo cloudflared-ct219-precedence-1gxczith/native.json, SHA<REDACTED>; peer2e8b4baf…. Esto acredita la precedencia seleccionada actual/futura de métricas con esos pins, sin admitir rotación de credenciales o un reinicio futuro. Se prepara el contrato privado del consumidor con estas pruebas; job27 y reglas continúan sin aplicar. Los pins deberán conservarse durante cada fase posterior.

Consumidor: procedencia de fuente corregida, 22:52 CEST

La PR135, main9d4a490, corrige dos pins obsoletos del contrato para fijar el template posterior a la retirada de WP-Pulse (520b327, templateSHA2c0914a8…). El resto del contrato es idéntico, incluidos todos los gates false/null. Una prueba renderiza los26 jobs reales, construye el27 con token sintético y exige conservación semántica completa; otra rechaza reintroducir el endpoint WP retirado. Setenta y una pruebas3.12/3.14, peer, dos regresionesroot y tresCI correctos. No cambia helper, template vivo ni reglas y no instala scrape o alertas.

Ansible-pull ordinario no aplica estos candidatos deCT217. La activación usa el helper manual ya existente, primero configuración26→27 y después las dos reglas, con baseline actual y guardas/recibos separados. Ambas fases siguen pendientes; la retirada prevista es reglas primero y job después, conservando sus recibos originales y sin modificar ACL o listeners de los productores.

Prometheus: baseline actual de sólo lectura, 22:57 CEST

El preflight actual deCT217 confirma26 jobs y campos explícitos de la configuración cargada iguales a disco; PID1181/start8461 y contenedor/StartedAt, boots, montajes bindRO, inodes y archivos estables antes/después. La última recarga declarada por Prometheus es21oct17:06:43 CEST y sigue exitosa. Se hicieron tres GET locales: runtimeinfo antes/después y config, sin consultas de métricas, promtool, staging, escritura, HUP o restart.

El token HA permanece no vacío en RAM del nodo y no sale al Mac; la redacción de secretos de la API no demuestra igualdad de token cargado ni autenticación. Las reglas pasan esquema/hash estable, pero su semántica cargada todavía no se ha verificado. Recibo privado ct217-consumer-preflight-20261021-vj9viv3f/native.json, SHA<REDACTED>. La baseline sólo contiene metadatos/hashes; no es instalación del job27 ni admisión de reglas, y cualquier deriva posterior exige detener la transición.

Registro y retirada de tres probes deshabilitados, 20:11–20:13 CEST

La PR124, integrada en 9863a5f con cinco checks correctos y 130 pruebas, permitió validar una única ida y vuelta nativa del registro. A las 20:11:28 se crearon tres definiciones propias deshabilitadas, se validó su ABI nativa de cinco campos (IDs 2342–2344) y se retiraron: seis operaciones append en total. No se pidió enable, captura ni activación de traps. Los offsets pertenecen al ELF exacto fijado; no se recogieron hits ni se exportó la dirección implícita de los formatos.

La ventana coordinada aceptó el riesgo residual de otro escritor: el lock y las comparaciones antes/después no son exclusión demostrada ni CAS del kernel. El transporte terminó con exit 0, stderr vacío, sin timeout ni reintento. La lectura independiente de las 20:13:13 encontró registro global vacío, grupo propio ausente, directorio de instancias vacío y controles globales idénticos al baseline; el proceso bootstrap original había terminado. Se conservaron boot e269, mux PID 1489/start 502 y SHA del ejecutable 087af87e….

Queda acreditada la creación, validación y limpieza de definiciones deshabilitadas, no una captura ni su coste durante hits. No queda un observador nuevo activo. Esta prueba no identifica la causa del reset, una decisión de inhibición, el cliente responsable ni la alimentación física del watchdog.

Recibos privados en watchdog-disabled-native-20261021-3pebzogb:

Recibo SHA256
output.jsonl <REDACTED>
post-readback.json <REDACTED>
transport-receipt.json <REDACTED>

Captura de once eventos: fuente integrada, ejecución nativa pendiente

La PR126, cabeza 3872025, se fusionó en main 971fe63 tras revisión root/peer y cinco checks CI correctos. Las 156 pruebas offline pasan en Python3.12/3.14: 26 nuevas y los130 tests anteriores intactos, incluido fork real y estado padre/hijo distinto. La matriz CI Python3.10/3.12 incluye la nueva suite. Este párrafo registra el estado de fuente previo a la primera ejecución nativa de20:58, documentada a continuación.

La fuente añade una entrada opt-in separada: registra las tres definiciones propias deshabilitadas, fija formatos y permite una instancia finita de los ocho eventos anteriores más tres puntos post-store exactos del mux. La ventana de habilitación es distinta de la de registro; instancia/identidad/fases están acotadas explícitamente y el helper deshabilitado permanece byteidéntico. El parser valida el IP implícito y lo descarta en RAM; protocolo/receptor v3 sólo transportan enums cerrados, timestamp/TID y vínculo al plan, preservando v1/v2. No se solicitan fetchargs ni payloads o memoria adicional de procesos.

La limpieza deshabilita/drena/retira primero la instancia propia y sólo después retira las definiciones exactas. Fallo parcial, hijo todavía vivo, cambio de identidad, escritura ajena o transporte incompleto conservan UNKNOWN; recovery es explícita, con ventana sólo de limpieza, sin habilitar. Flock/atestación operativa no prueban exclusión absoluta ni CAS del kernel. El presupuesto CPU del lector no demuestra el coste total de traps/kernel ni garantía frente a picos.

La integración fuente está resuelta; la primera captura nativa11 no fue aceptada, como detalla el apartado siguiente. La aceptación deshabilitada de20:11–20:13 sólo acredita creación/ABI/retirada. Ni ésta ni una captura breve saludable cubren el siguiente reset, identifican la causa P0 o prueban alimentación física. El encabezado conserva su ancla histórica; la ejecución nativa dejó de estar pendiente, pero su aceptación sigue abierta.

Primera captura v3 UNKNOWN y limpieza independiente, 20:58–21:01 CEST

Una única ejecución nativa planificada para30s a las 20:58 CEST terminó UNKNOWN tras aproximadamente3,36s. La razón observer_cpu_budget quedó acreditada mediante la proyección del outcome fijado por hash. No se reintentó ni se ejecutó recovery. El stream parcial conservó12 frames/10 eventos, dos retornos ioctl0 y dos callbacks watchdog con err0; no constituye la aceptación de30s. Los cero hits de los nuevos puntos del mux no demuestran ausencia de actividad del cliente. En el fallo no quedaron registrados CPU, duración y pérdida del worker: ausentes no significa cero. Los3,36s corresponden al intento observado, no a una medida de CPU del worker.

El POST de 21:01:43,752 CEST, de sólo lectura, verificó registro global vacío, grupo propio ausente, cero instancias, once controles globales idénticos y bootstrap original terminado. Se conservaron e269, mux1489/start502 y el binario fijado. La limpieza está acreditada independientemente; la captura sigue UNKNOWN y no queda un observador nuevo activo. El presupuesto excedido es del capturador; no identifica la causa de los resets ni acredita alimentación física.

La PR128, cabeza bea9c30, se fusionó a las 21:35:51 CEST en main <REDACTED>, con cinco checks CI correctos. La corrección de fuente reutiliza descriptores de directorio sólo durante una ronda finita, conservando contenido fresco, full9, autoridad de ancestros/leaf/montaje y guardas completas. Mantiene cadencia1Hz y límite CPU1%; sólo v3 evita el fast_guard exterior cuando su guard completo ya lo acredita. Añade telemetría numérica por fase también en UNKNOWN y errores tipados cerrados. El helper de registro deshabilitado sigue byteidéntico. Pasan 166 pruebas en Python3.12/3.14 y el peer repitió las166 en3.12. La fusión no implica instalación ni ejecución. No se ha probado el presupuesto real en PVE ni el coste total de traps/kernel; no hubo otra ejecución nativa para validar esta corrección.

Recibos privados bajo watchdog-v3-native-plan-20261021-fykxhl23:

Recibo SHA256
closure.json <REDACTED>
post-native.json <REDACTED>
capture-final-peer-closure.json <REDACTED>

Coste del observador: dos ensayos posteriores y corrección contable

El ensayoPR128 de21:41 terminó UNKNOWN:26,506687msCPU/2,04598689s≈1,29555%, loss0. El POST21:42 acreditó limpieza, once controles intactos y mux1489@502 estable. La PR131, maine6dc8fb, añadió batch de permisos completo y medida de activación sin cambiar1%/1Hz/reloj. Sus170 pruebas3.12/3.14, peer/root y cincoCI fueron correctos.

Un único ensayo nuevo de21:58 volvió a terminar UNKNOWN: 26,879791msCPU/2,059693081s≈1,30504%, loss0. Activación4,662152ms y tres guards 16,203175ms; quedan6,014464ms sin atribución precisa. Configuración previa y cleanup posterior están fuera del intervalo y no se suman al coste observado. El POST21:59 verificó registro vacío, grupo/instancias ausentes, once controles intactos y bootstrap terminado, con el mismo boot/mux. No queda captura activa.

La PR134, main9054b36, integra a las22:28 una corrección de contabilidad: muestras adyacentes CPU/pared al terminar las guardas, evitando comparar CPU posterior con pared previa. Conserva inicio/gracia/límite/cadencia y las once señales.172 pruebas3.12/3.14, peer, tres regresionesroot y cincoCI correctos; recibo integrado71b31238…. No hay ensayo nativo posterior: la corrección no acredita cumplir1%, no rehabilita ninguno de los tres UNKNOWN y no identifica causa del watchdog. No encadenar capturas equivalentes ni aumentar límites para obtener un PASS.

La PR133, maind98bd41, integra además la admisión documental del restore aisladoCT217. Sigue pendiente acreditar snapshot/destino/capacidad, restaurar sin arranque y revisar aislamiento antes de iniciar servicios. No se ejecutó restauración ni arranque de prueba.

Revisión de correcciones y guard de PBS, 19:36–19:54 CEST

La comparación de fuentes oficiales posterior a pve-ha-manager 5.2.5 no identificó una corrección demostrada de estas expiraciones: watchdog-mux.c conserva los mismos bytes. El kernel PVE 7.0.14-25 es un candidato de mantenimiento frente al -19 observado, no un remedio acreditado del watchdog. No se instaló ni se reinició el host; tampoco se ha cerrado la equivalencia entre sus fuentes downstream y el controlador cargado. Véanse la comparación de HA y el changelog del kernel.

La corrección CRS #7974 ajusta predicciones de memoria del planificador dinámico. La lectura acotada de la configuración actual, bajo boot e269, encontró cero líneas crs:: conforme a los defaults de la fuente revisada, el modo efectivo es basic y el reequilibrado automático está desactivado. Esa ruta dinámica no se utiliza en la muestra actual; no se extrapola al pasado. El recibo privado crs-applicability-20261021-vzcv_r6p/output.json tiene SHA256 <REDACTED>. Esto no modifica las afinidades ni el margen N-1 medido de +681,37 MiB y no resuelve el P0.

La PR121, integrada a las 19:36 con tres checks correctos y 19 pruebas independientes, sustituye el criterio «hay un mount» de archive por una comprobación de identidad: árbol de montajes visible, export NFS, ext4/rw, fragmento de unidad y backing del loop por metadata local. Ante una identidad incorrecta o desconocida mantiene HOLD; sólo conserva el start de la unidad existente si la ausencia está acreditada. No abre el NAS, la imagen ni el dispositivo, ni detiene PBS.

El preflight nativo del helper exacto a6b1464e… devolvió verified en 21,838915 ms, bajo e269, sin ejecutar el wrapper, enviar notificaciones ni modificar el runtime. Se conservó una copia privada del wrapper anterior, sin exportar su URL. La lectura independiente de las 19:50:54 confirmó el helper instalado con el SHA exacto, wrapper root0700 idéntico a la fuente renderizada y credencial conservada respecto de la copia privada. El helper instalado devolvió verified en 52,516861 ms, incluido el arranque de Python. El pull ordinario de las 19:49:30 terminó correctamente; esta lectura no ejecutó el wrapper ni realizó peticiones de red o escrituras de runtime.

El timer disparó el guard a las 19:54:15. La lectura posterior de sus unidades, bajo e269, encontró Result=success, status 0 e inactive/dead; el inicio monotónico del guard (10009342115) es posterior al final del pull (9772472909). El timer continúa active/waiting. Se acredita instalación y una ejecución ordinaria correcta, sin disparo forzado. Ese exit 0 no prueba llegada a Healthchecks, contenido del archive, integridad de las copias ni recuperación.

Recibos privados en pbs-archive-identity-native-20261021-acqihhh6:

Recibo SHA256
preflight-output.json <REDACTED>
baseline-output.json <REDACTED>
backup-output.json <REDACTED>
installed-readback-output.json <REDACTED>
installed-units.json <REDACTED>
natural-run-units.json <REDACTED>

Recuperación histórica después del arranque de las13:59

La captura nativa de 14:20:53 CEST, con boots 74ed704b…/86184726… estables antes/después, confirma quórum3/3 con QDevice, 28/28 invitados running (8 en pmx50 y20 en pmx51), los14 recursos HA started en pmx51 y14 trabajos de replicación fuente sin errores ni fail_count. CRM master en pmx51 armado; LRM de pmx50 idle/watchdog standby y pmx51 active. Standby del LRM no demuestra que el watchdog hardware esté desarmado. MemAvailable era14,49GB/11,43GB y PSI memoria avg10=0 en ambos; esta lectura no recalcula demanda N-1.

A las 14:21:32–14:21:34, CT270 en pmx50 y CT271 en pmx51 mantienen Caddy/keepalived active/running, NRestarts0 y VIP únicamente en CT270, con propietario y boots comprobados antes/después. No hubo peticiones HTTP, login, ensayo de conmutación ni prueba funcional de productos. Los gauges cloudflared de13:43, la salud WP de13:01 y el balloon efectivo de VM208 anterior al reset se conservan como históricos. Las lecturas de14:38 descritas más abajo actualizan únicamente capacidad, balloon y gauges locales.

La instrumentación Pulso de PR100 conservó 90 muestras de13:57:15 a 13:58:45: identidades estables de mux1446@604, LRM2032@2116 y CRM1941@927. En89 intervalos, mux y CRM avanzan en todos; LRM avanza en18, con un máximo de cuatro intervalos sin avance (unos4,03s). Runtime acumulado avanza 2.536.369ns,10.937.566ns y18.750.681ns respectivamente. Esto no muestra una congelación total antes del último paquete, pero tampoco acredita keepalives. El último paquete precede32s al arranque y45s al primer paquete del boot nuevo (13:59:30). El comportamiento durante ese hueco y el desencadenante siguen abiertos. El kernel confirma el mecanismo; sysfs conserva bootstatus32, identidad SP5100 TCO timer y timeout10, sin abrir el dispositivo watchdog.

Los primeros lectores de journal devolvieron error por el UUID con guiones; la consulta con UUID normalizado terminó rc0 en ambos boots. Esos errores no significaban ausencia de journal. Las guardas del boot anterior abortaron la inspección de CT219 antes de entrar al invitado. No se trasladó de forma implícita ninguna admisión de escritura al nuevo arranque.

Evidencias privadas: watchdog-1359-20261021-wfrbfm8_/ y ha-epoch74-20261021-9siz5qxu/, bajo ~/.local/state/.

Evidencia SHA256
Pulso seleccionado receiver-result.json <REDACTED>
Análisis independiente local de90 muestras <REDACTED>
Confirmación seleccionada de journal, transcrita de la salida nativa <REDACTED>
Snapshot pmx50 <REDACTED>
Snapshot pmx51 <REDACTED>

Contratos y cambios de fuente posteriores

El informe ordinario de VM208 de 14:23:03 CEST, leído a las14:33, pasa la validación del lector y cubre11 contratos: mantiene los dos fallos conocidos de deriva de N8N_API_KEY en hunter/scanner y29 verificaciones pendientes. Es evidencia posterior al reset de13:59; no prueba login, restauración ni salud de productos fuera de esos contratos. No se lanzó un colector nuevo.

PR108, integrada en 04c8eb67, añade recuperación explícita del consumidor Prometheus27→26 ligada al recibo durable, backup privado, identidad y hashes del cambio. Las53 pruebas y CI pasaron; no se activó el job27. La ACL propia y los bindings de PR109, integrados en 402ded03 con cinco checks correctos, estaban sin aplicar a las14:37: el CI aislado comprobó nftables1.0.9 real en un namespace nuevo, pero el getter D-Bus ha quedado seleccionado de nuevo a las14:37:54–14:37:57. CT123 devuelve EnvironmentFiles vacío exacto; CT219 declara un archivo, cuyo contenido no se leyó en esa primera lectura. CT219 estaba bloqueado en ese punto; ambos carecen del entorno explícito loopback exigido por el plan de rollback. Ninguna lectura convierte esos gates en admisión de escritura.

PR110, integrada en e4da59c, añade el contador acumulado runqueue_delay_ns al bloque Pulso v2 mediante la misma lectura schedstat. Las37 pruebas y cinco checks pasaron. La comprobación de 14:40:18–14:40:19 acredita convergencia ordinaria: Ansible-pull comenzó14:38:15 y terminó exit0; el emisor se reinició dentro de ese ciclo a las14:38:46, PID96056/NRestarts0, con fuente SHA256 <REDACTED> exacta de PR110. El receptor pmx51/PID1559 permaneció inalterado y recibió tres muestras14:40:16–14:40:18 con v2/boot74 y runqueue uint64 en los tres roles. No hubo force-pull ni reinicio manual. No demuestra keepalives ni causa del reset. Recibo privado ~/.local/state/pulse-v2-convergence-20261021-9ecs_x2z/receipt.json, SHA256 <REDACTED>.

GitHub mantiene la alerta de desarrollo WP Dependabot146 para braces3.0.3, sin versión corregida indicada en esta revisión. No se cambió WP ni se amplió su revisión funcional por este aviso.

Recuperación después del arranque de las 11:56 (histórico)

El nuevo snapshot nativo confirma quórum3/3 con QDevice, los14 recursos HA started en pmx51 y las14 réplicas fuente sin error ni fail_count. Los cuatro recursos estrictos siguen siendo110/172/217/218. Las identidades de boot 558fbd3c…/86184726… permanecieron estables durante esas lecturas. MemAvailable era13,45GiB en pmx50 y9,38GiB en pmx51; PSI memoria avg10=0 en ambos, con presión CPU some avg10=37,13 en pmx51 como foto puntual. Esto no recalcula demanda conjunta N-1 ni acredita recuperación funcional de todos los invitados. Se conserva el presupuesto medido de las11:03 como histórico.

La entrada se revalidó entre 12:12:57 y 12:13:03: Caddy y keepalived activos en CT270/271, NRestarts0 y VIP sólo en CT270. Ambos cloudflared están activos; CT219 tiene un reinicio interno registrado y CT123 ninguno. Los logs seleccionados no acreditan un gauge actual de conexiones: el 4+4 de las11:04 queda fechado, sin declarar avería por errores históricos de CT123. No se hicieron peticiones públicas ni ensayo de conmutación.

CT281 a las 12:13:47: nuevo boot 44de8787…, API PID885 y web PID886 activos, NRestarts0, con inicio11:57:19. Pillow13.0.0 persiste; Next15.5.23 sigue sin actualizar. La lectura de Sharp por ruta directa no lo encontró y se conserva como UNKNOWN: no implica ausencia de la dependencia transitiva. No se arrancó ni reinició ningún servicio como parte de esta revisión.

Originales terminó antes del reset según ledger y métricas persistidas. La observación de recuperación de las 12:11:57–12:13:22 mantiene padre, propietario VM208 y nuevo guest boot 37823909… estables. Documentos/proyectos conservan sus éxitos de las 11:10; photos figura COMPLETE a las 11:21:40, pics a las 11:22:44 y publicación del dump a las 11:24:34. El productor de las 12:10:02, leído a las 12:12:03, coincide: collection_success=1, process_running=0, los cuatro grupos sin copying/failed y publicación sin fallo ni intento en curso. No se volvieron a leer destinos, manifiestos ni bytes del dump; tampoco se acredita aquí coherencia integral o restauración. La incertidumbre RPC se resolvió a las 12:22:25 CEST mediante comparación controlada de contexto: mismo binario, flags, entorno limpio y directorio; root devuelve CLI1 y monxas devuelve CLI0. El daemon pertenece a monxas y su socket es1000:1000/0600. Como monxas, healthy=true, scheduling_active=true y config_stale=false. El mismo handle 01M5EVJZJ197C2JJW55BGER204 figura ended, exit_code0, failed=false, missed=false, con próxima ejecución 22oct11:10 Europe/Madrid. No hubo reinicio ni relanzamiento. El UID del lector era la diferencia controlada; no se atribuye a una capa concreta del socket/daemon sin traza. El primer comprobador tenía además un defecto local ante rc no cero, que no explica por sí solo el fallo observado.

Distribución y cobertura real

flowchart TB
  INTERNET[Internet / Cloudflare] --> T[Túneles CT123 pmx51 + CT219 pmx50]
  LAN[LAN / dos DNS] --> VIP[VIP Caddy .250]
  T --> VIP
  VIP --> EDGE[Caddy CT270 pmx50 + CT271 pmx51]
  EDGE --> CORE[Identidad y núcleo: diez recursos HA migrables]
  EDGE --> STRICT[CT110 / 172 / 217 / 218: HA estricto pmx51]
  EDGE --> V208[VM208 pmx50: aplicaciones Docker sin HA]
  CORE --> DATA[NAS / datos y dependencias compartidas]
  STRICT --> DATA
  V208 --> DATA
  PBS[PBS186 pmx50: main local + archive TerraMaster]
  DATA -. recuperación por copias, no continuidad .-> PBS

El esquema representa dominios de fallo y dependencias, no todas las rutas de cada aplicación. El mapa detallado conserva sus fechas del 20 de octubre; los propietarios PVE se revalidaron hoy.

Nodo y cobertura Invitados actuales Recuperación ante pérdida del nodo
pmx51, diez HA migrables CT100 Vera, CT123 cloudflared, CT155 WireGuard, CT212 maint, CT213 PocketID, CT214 Vaultwarden, CT215 avisos, CT216 pegamento, CT220 Jellyfin, VM171 Home Assistant HA permite recuperación en pmx50, con aislamiento, réplica y capacidad suficientes; hay interrupción
pmx51, cuatro HA estrictos CT110 TV gateway, CT172 ha-ml, CT217 observabilidad, CT218 personal Esperan pmx51; tener réplica no anula esa afinidad
pmx51, seis sin HA PVE CT200 n8n, CT204 Pi-hole2, CT271 Caddy, CT301 Warpgate, CT302 Trove, CT303 Argus Retorno del nodo o recuperación específica; DNS/Caddy tienen pareja fuera del nodo
pmx50, siete activos sin HA PVE CT186 PBS, VM208 media/cómputo, CT219 cloudflared2, CT251 RAG, CT270 Caddy, CT280 Remote-Pulse, CT305 Homelable Retorno del nodo o recuperación específica; Caddy/conector tienen pareja en pmx51
pmx50, retirado CT281 WP-Pulse: stopped/onboot0 desde17:31 No se espera recuperación automática; datos/copias conservados

El trabajo de Vera sigue siendo del usuario en paralelo; sólo se leyó el estado PVE de su CT, no su aplicación ni sus cambios.

Qué ocurre si cae cada nodo

  • Cae pmx50: el núcleo de pmx51 permanece y conserva pareja de entrada. Se interrumpen VM208 y sus aplicaciones, PBS, Remote-Pulse, RAG y Homelable. VM208 no forma parte del presupuesto N-1 ni se traslada al Celeron por defecto.
  • Cae pmx51: pmx50 conserva sus invitados y pareja de entrada; los diez HA migrables pueden recuperarse allí. Los cuatro estrictos y los seis sin HA esperan recuperación específica. PocketID es una instancia: entrada viva no equivale a autenticación disponible mientras se recupera su CT. Se pierde observabilidad CT217 precisamente durante ese fallo.
  • Falla NAS, router, switch, alimentación o Internet: ninguna de las dos situaciones anteriores garantiza continuidad. Son dominios compartidos que deben tratarse por separado. QDevice y DNS primario comparten la RPi.

El playbook actualizado sustituye las instrucciones de agosto: no mover archivos de /etc/pve, restaurar sobre IDs de producción ni confundir una IP libre en la LAN con aislamiento de una restauración.

Qué está funcionando y hasta dónde se ha comprobado

Área Evidencia fechada (las lecturas anteriores a13:59 son históricas) Cobertura pendiente o límite
Clúster y HA Ambos nodos con quórum 3/3, requerido 2; QDevice presente. CRM activo en pmx51; 14/14 recursos started No hubo ensayo de caída hoy; watchdog standby del LRM de pmx50 no significa hardware desarmado
Réplicas PVE 14/14 habilitadas, State OK, FailCount 0; edad inferior a su intervalo Asíncronas: pueden perder lo posterior al último sync; no protegen de corrupción/borrado replicado
Caddy / VIP Estado activo y VIP sólo enCT270 en la lectura histórica; journal del fallo natural acredita CT271 MASTER durante56,621s y posterior retorno a BACKUP. El22oct18:19, discovery/JWKS de PocketID por ambos Caddy y VIP responden HTTP200 con TLS validado. VRRP histórico y rutas seleccionadas actuales; sin login, disponibilidad durante el fallo ni RTO de aplicaciones
DNS Ambos resolvers, .204 RPi y .23 CT204, responden NOERROR y A .250 para pocketid.monxas.casa; 26/13 ms a las18:19:54 del22oct Una consulta por resolver no prueba toda la zona ni que todos los clientes usen ambos
Cloudflared Configuración27 aplicada y scrapes independientes23:20: dos targetsUP/up1/gauge4+4 y muestras originales frescas. Dos reglas aplicadas después con configuración intacta y condición de dos evaluaciones sanas Readback23:40 verifica23grupos/94reglas saludables y dos evaluaciones crecientes; sin prueba de entrega de avisos, caída del observador ni E2E de rutas públicas
Dozzle Running, sin reinicios/OOM, OIDC nativo configurado; ruta única sin Sablier; Dozzle sin socket directo, sidecar interno sin puertos publicados Login/claims/autorización no probados; depende de VM208, sin HA propio
Sablier Healthy, sin reinicios/OOM; ACL del puerto 10000 y hooks IPv4/IPv6 presentes, Caddy permitido en IPv4 Dormir/despertar real no invocado; instancia única en VM208
Contratos VM208 Informe validado ordinario de 11:23:03: 11 contratos; hunter/scanner y dependencias running/healthy antes del reset Dos fallos de deriva de configuración y 29 verificaciones pendientes; no equivale a 29 averías ni acredita salud posterior al reset
PBS Checker sano 07:00, sync completado hoy 06:03; capacidad producida 10:35 Archive con alerta de reserva; restore de archive y custodia independiente no demostrados
Originales Cuatro grupos COMPLETE y publicación exitosa a las11:24:34; ledger/productor posteriores al reset y mismo handle ended/exit0 confirmados12:22 Integridad completa de destinos, coherencia de generación y restauración Immich aún pendientes; no se relanzó la copia
Energía Propuesta de coordinación documentada Coordinador nuevo SAI/Meross desactivado, autonomía/cableado de NAS y red/parada nativa pendientes

Los dos fallos de contratos son compose.environment/N8N_API_KEY en hunter/scanner: fuente versionada vacía frente a clave no vacía en runtime. La entrada vacía es una máscara de seguridad deliberada, preparada en Stacks b1ae78c para evitar heredar la credencial n8n del env_file compartido; el código propio revisado no la consume. No corresponde copiar la clave activa a Compose para eliminar el aviso. La aplicación de esa limpieza sigue diferida por estabilidad y por la ausencia de un drain persistente que preserve trabajo en curso. Tampoco se recrean servicios sólo para silenciar el informe. El diagnóstico previo y homelab-stacks/custom/plundrio/DEPLOYMENT.md documentan las condiciones. Las 29 verificaciones pendientes son 11 funcionales, 11 de acceso, cinco de política de imagen y dos de recuperación. El productor ordinario posterior de las 11:23:03 CEST conserva ese reparto: 11 funcionales caducadas; accesos con seis recibos nunca completados y cinco caducados; política de imagen en ABS/Karakeep/Prowlarr/Radarr/Sonarr; recuperación en Plundrio/Onepacerr. Se leyó a las12:20, pero su fecha sigue siendo anterior al reset. No se cerraron pendientes usando sólo healthy ni se invocaron los health endpoints de Hunter/Scanner, que pueden consultar servicios externos. Según la revisión previa, el candidato de autenticación de Soularr seguía sin activar y su acceso LAN nativo sin autenticación requería cerrar consumidores/clientes/allowlist antes del cambio. No se revalidó su runtime hoy. Véase la coordinación previa.

Capacidad N-1 y tiempos de recuperación

A las 10:41:37 CEST, las métricas existentes de node-exporter tenían edades de 7,50/8,16 segundos y mostraban:

Memoria disponible pmx50 pmx51
Muestra actual 13,467 GiB 11,807 GiB
Mínimo observado en 24 h 11,625 GiB 9,380 GiB
Percentil 5 observado en 24 h 12,619 GiB 10,157 GiB

La ventana cruza reinicios y huecos; no acredita continuidad ni carga máxima. La muestra de las 10:41 no incluía demanda conjunta. Esa carencia se cerró con lecturas nativas entre 11:03:02 y 11:03:10 CEST, sin ejecutar el comprobador general ni acceder a aplicaciones/NAS:

La captura posterior al reset, 16:15:36–16:15:56 CEST, conserva los bootsbff/861 y el mismo método:13.397,4140625MiB disponibles −12.578,984375MiB de demanda máxima RAM+swap de los diez migrables −2.048MiB de reserva = −1.229,5703125MiB. Sigue sin admitir N-1; no acredita picos ni arranque conjunto. El usuario confirmó conservar Jellyfin220 en failover y descartar aplazarlo. Esta muestra precede al nuevo reset17:07 y a la retirada WP descrita arriba; no se atribuye ahorro entre epochs ni se presenta como presupuesto actual. Recibo privado ~/.local/state/nminus-native-epochbff-20261021-ij_e3m5k/calculation.json, SHA256 <REDACTED>. Las ventanas anteriores conservan carácter histórico.

La captura nueva de 14:37:40–14:38:04, posterior al reset13:59, conserva boots74/861 y políticas idénticas antes/después. Mantiene el resultado negativo:

Presupuesto operativo por el método existente 11:03, histórico · MiB 13:44–13:45, histórico · MiB 14:38, última muestra histórica · MiB
Menor MemAvailable observado en pmx50 13.529,87 13.582,53 13.693,95
Demanda de diez migrables, RAM+swap 13.689,81 13.663,18 13.652,63
Reserva 2.048 2.048 2.048
Margen sin crédito adicional de balloon −2.207,95 −2.128,65 −2.006,68

Los14recursos HA, diez migrables, cuatro estrictos y propietarios se mantienen en cuatro inventarios. Dos lecturas por nodo conservan identidades de cgroups y PID/start de QEMU; se usa el máximo por invitado y el mínimo MemAvailable, sin pretender atomicidad entre nodos ni acreditar picos/arranque. Los datos PVE seleccionados, ligados al PID nativo estable, confirman HA171 máximo6144, target/actual5632MiB y VM208 máximo8192, target/actual7680MiB, con shares0 y balloon actualizado durante la captura de14:38. Los5,5/7,5GiB efectivos quedan revalidados en el nuevo epoch: VM208 PID4919/start3714 y VM171 PID5918/start4636 estables antes/después. No acreditan otro1GiB de ahorro incremental del host ni se suman otra vez. El primer lector falló por exigir int donde PVE devuelve memory como string numérico; tras normalización estricta y peer, se repitió la captura completa. UNKNOWN y diagnósticos previos se conservan sin tratarlos como medidas.

Recibo privado actual: ~/.local/state/nminus-native-epoch74-20261021-zoq8yg3o/calculation.json, SHA256 <REDACTED>. El lector reutilizado sólo cambia el boot fijado; nueve fixtures pasan y el cálculo local reproduce exactamente la fórmula del recibo anterior.

Recibo privado histórico de la ventana13:45: ~/.local/state/nminus-native-epoch558-20261021-t911w2hp/calculation.json, SHA256 <REDACTED>.

Se suma una vez memory.current+swap por LXC y VmRSS+VmSwap del QEMU de VM171. Incluye caché y swap: no demuestra un OOM inevitable, pero no admite N-1 por el criterio actual. No hay crédito extra de balloon, ARC o caché. La muestra posterior de RAG251/Homelable305 suma 1.532,57 MiB contables: ni esa hipótesis completa cubre el déficit de referencia y no equivale a RAM que se liberaría al apagarlos. Los +374/+828 MiB del 19oct son históricos. Método, composición, guardas y plan de admisión.

Además, la fuente anterior de normalidad rechazaba la línea válida actual fencing armed (CRM watchdog active). La corrección PR96 acepta sólo los pares documentados armed/active y standby/standby; standby con recursos, desarmado, duplicados, combinaciones incoherentes y formatos desconocidos siguen sin acreditar failover. Dieciocho regresiones aisladas pasan y el replay del estado nativo guardado devuelve los 14 recursos; antes fallaba. No cambia la fórmula, la reserva ni exclusiones. Convergencia ordinaria confirmada en ambos hosts: ciclos pmx50 11:22:00–48 y pmx51 11:25:29–11:26:28 con éxito, archivo instalado SHA <REDACTED>. No se ejecutó el chequeo general como prueba; la medida negativa independiente sigue siendo el presupuesto observado. Recibos de instalación.

Para garantizar todos los límites de esos diez invitados se necesitarían 19.328 MiB + 2.048 MiB de reserva = 21.376 MiB, antes de sobrecostes; pmx50 tenía 13.790,32 MiB disponibles. La diferencia de −7.585,68 MiB describe la falta de garantía al máximo configurado, no un déficit de consumo real ni un OOM actual. No procede reducir más RAM sin medir la demanda conjunta.

La recuperación HA tiene corte: los ensayos/documentación anteriores sitúan la fase de recuperación de nodo alrededor de 2–2,5 minutos. Home Assistant añade su arranque, con estimación histórica total de unos ocho minutos; no es un RTO medido hoy ni continuidad de integraciones. VM171 mantiene failback=0 y debe moverse en frío por la migración AMD/Intel no fiable en ensayos anteriores.

RPO configurado por réplica Recursos Último sync observado hoy
5 minutos CT212/213/214 10:35:02–08
15 minutos CT100/123/155/215/216/217/218/220, VM171 10:30:05–35
30 minutos CT172 10:30:02
Una hora CT110 10:00:01

RPO depende del último sync completo y su consistencia; RTO depende también de capacidad, aislamiento y arranque de la aplicación. La distinción está descrita en la documentación primaria de HA PVE y replicación PVE.

Copias: qué se ha recuperado realmente

Elemento Prueba existente Lo que falta
PBS main CT123 restaurado aislado el 19oct; ensayo completado y limpiado Otros invitados, pérdida del host y restore desde archive
Paperless 3.3.2 Restauración aislada con SQLite/Redis; 146 originales con hashes iguales, tres PDF y metadatos/índice comprobados Login e integraciones
Immich BD de 31.595 assets: 10.803 photos y 20.792 pics; referencias de metadata y tres uploads recuperados con hash Aplicación completa, todos los bytes y coherencia entre dump/generación de originales
CT217 observabilidad Job/snapshot observado y 16 binds bajo rootfs en la muestra del 20oct Especificación completa de recuperación aún false; restore de datos/configuración/secretos y arranque de sus 26 jobs
CT280 Remote-Pulse Backup registrado el 20oct a las 05:00 Restauración PostgreSQL/aplicación

PBS main es local; archive es loop/ext4 sobre TerraMaster. No se presupone que ambos contengan todas las mismas generaciones ni que el segundo sea una copia independiente ante pérdida de NAS, alimentación o ubicación. No hay custodia offsite acreditada.

A las 10:35, archive tenía 225,96 GiB libres y 14,956 %: dispara PBSDataReserveLow, a unos 0,67 GiB del umbral del 15 %. No es agotamiento inmediato. Main tenía 166,20 GiB y 35,008 % libres. Conviene medir tendencia y generaciones recuperables antes de cambiar retención, no bajar el umbral ni forzar prune/GC para colorear el panel en verde.

La telemetría anterior de originales, a las 10:35, registraba collection=1, process=0, documents_failed=1 y photos_last_success=0. La publicación estaba configurada, pero el último reporte indicaba enabled=0/success=0 y disparaba OriginalsDumpPublicationRequired. nas_nfsd_dstate_degraded estaba pending, no firing; no demuestra causa de los resets.

El ciclo ordinario de las 11:10 sí se ejecutó: documentos y proyectos acabaron correctamente a las 11:10:19/42; photos estaba copiando con heartbeat 11:16:15. Pics no había comenzado de nuevo y publicación seguía pending. Se retoma la generación 20261020; no hay éxito global nuevo. El registro canónico del ciclo conserva el handle único, guardas y recibos para seguir el mismo trabajo.

Seguridad pendiente de dependencias

La consulta de GitHub posterior a este informe confirma abierta la alerta 146: braces, severidad high, dependencia transitiva de desarrollo en services/wp-pulse-server/web/pnpm-lock.yaml, sin versión corregida declarada. El cierre de Pillow no cierra esta alerta ni acredita explotación. Corresponde revisar su cadena de dependencia y una mitigación compatible o actualización cuando exista, sin silenciar la alerta por ser de desarrollo. Tras la retirada de WP a las17:31, esa revisión se exige antes de una eventual reactivación, sin ampliar ahora el proyecto por este aviso.

Cambios ya cerrados esta mañana

  • WP-Pulse CT281: Pillow 13 instalado y verificado con wheel oficial, hashes y prueba PNG/JPEG en memoria; servicio arrancado, sin afirmar E2E. El primer resultado incierto por permiso de un SBOM se conserva y fue reconciliado mediante verificación estricta independiente. Detalle.
  • Pulso: PR95 integrada y desplegada por el ciclo ordinario a las 10:32:39. El receptor existente registró mlockall=ok mlock_errno=0; VmLck 94.468 kB, PID560740, cero reinicios internos. Se corrige el diagnóstico del retorno C, no se atribuye a él la causa de los resets. Detalle y límites.
  • Playbook de failover rehecho con propietarios, afinidades, réplicas y recuperación segura actuales. No se alteraron HA, memoria o afinidades.

Avance de diagnóstico y restauración, 13:45 CEST

La PR100 está fusionada en main (bd4a445), con revisión independiente y ocho checks correctos, incluida la matriz Python3.10/3.12. El Pulso existente añade identidad y contadores de progreso de watchdog-mux, LRM y CRM; incluye runtime en nanosegundos para evitar confundir falta de un tick de CPU con falta de actividad. No cambia la política del watchdog ni acredita keepalives o causa del reset. Mantiene un paquete por segundo y el tope1400bytes; el bloque añadido aumenta bytes y puede recortar antes la cola de temperaturas/detalle. Presupuesto estático:21lecturas pequeñas por muestra, hasta75.669bytes; coste real aún sin medir.

La admisión readonly de las 13:20:37 conserva los boots 558fbd3c… y 86184726…: emisor pmx50 activo, PID1381/NRestarts0, y receptor pmx51 activo, PID1559/NRestarts0. pmx51 no tiene emisor, conforme al inventario. Los procesos HA siguen activos con PID estable. Fusionar permite que el siguiente Ansible-pull ordinario copie y reinicie sólo el emisor existente de pmx50; no se forzó pull. El ciclo de pmx50 iniciado13:23:45 terminó con salida0 y reinició el emisor a las13:24:15, PID204256/NRestarts0. A las13:25:16 su SHA256 coincide con main (1e489573…). El receptor pmx51 conserva PID1559 y registra el nuevo bloque completo en las13:25:13/14/15, con boot/PID/START consistentes y progreso observado de mux/CRM; no es prueba de keepalive. Los procesos HA y ambos boots permanecen iguales. El receptor y la política HA no se modificaron. El ciclo ordinario de pmx51 iniciado13:32:44 terminó con salida0; a las13:34:15 el visor coincide con main (0aff4eac…). Una ventana adicional13:31:13–27 recoge15muestras completas con identidad estable: runtime de mux/LRM/CRM aumenta437.608/1.105.393/3.082.207ns, aunque utime/stime no avanzan ni un tick en ninguno. Valida la granularidad añadida, no un keepalive ni una causa. Recibo privado ~/.local/state/pulse-progress-live-20261021-10teuu5m/receipt.json, SHA256 <REDACTED>.

La PR101 está fusionada en main (0c53f95), tras peer y CI Python3.10/3.12 y contratos/promtool. El preflight LXC de PBS ahora rechaza recursos raw, binds, dispositivos, hooks y mapas no admitidos antes de restaurar, además de declarar start/onboot/HA0 desde el inicio. Las67pruebas offline pasan; los11casos sintéticos ejecutados con el parser nativo instalado también pasan, con boot y hashes del backend estables. No se ejecutó restore ni se leyeron payloads de copias. La protección posterior al restore llegaba tarde para la fase de montaje. La copia instalada en pmx50 a las13:25:16 ya coincide con main (dd30cf8e…); pmx51 también coincide a las13:34:15 tras el ciclo ordinario iniciado13:32:44, salida0. No se arrancaron ensayos ni se modificaron calendarios. Recibo privado de instalación/recepción: ~/.local/state/pulse-pbs-ordinary-convergence-20261021-ol5zt5yn/receipt.json, SHA256 <REDACTED>. El cierre de pmx51, con boot861estable antes/después, queda en ~/.local/state/pmx51-pbs-viewer-convergence-20261021-mqvq2rrf/completed-cycle.json, SHA256 <REDACTED>. CT217 y la recuperación completa de Immich siguen pendientes. Detalle de validación y límites.

La PR102, main e6f8db5, corrige otro riesgo del diagnóstico: lecturas RAM/swap incompletas ya no aparecen como demanda cero. Peer y23pruebas locales correctas, además de CI Python3.10/3.12 y lint. La fórmula, reserva y exclusiones no cambian. La copia instalada en pmx50 coincide con main a las13:42:55 (0b6ba01a…), tras el ciclo ordinario13:40:06 con salida0 y boot558estable. Esto no acredita por sí solo otra medida ni resuelve el déficit; no se ejecuta normalidad completo bajo el hold NAS. Recibo privado ~/.local/state/n1-reader-source-convergence-20261021-anvq3h1b/receipt.json, SHA256 <REDACTED>. La nueva captura estrecha de demanda posterior sí se completó y se detalla en el presupuesto N-1 de este informe; los UNKNOWN anteriores se preservan.

La PR103, main 91042b4, extiende el assembler existente para preparar referencias desde otra publicación inmutable formato2: exige SHA explícito del manifiesto y ambos recuentos revisados, valida nombre/tamaño/SHA/CRC del dump y liga el resultado a la identidad de publicación. Reutiliza el validador del publisher y conserva presupuestos;127pruebas locales y CI Python3.10/3.12/PBS-promtool correctos. Las referencias de originales siguen siendo contexto, no prueba de coherencia. El checker histórico rechaza el nuevo formato antes de acceder al NAS. No se procesó la generación20 ni se ejecutó restore; falta adquirir/admitir sus inputs y revisar el consumidor remoto antes de la recuperación completa. Receta y límites.

Revalidación de conectores, 13:43 CEST (histórico)

Los gauges nativos de esa ventana vuelven a acreditar 4+4 conexiones: CT219 a las 13:43:50 y CT123 a las13:43:51. Cada listener127.0.0.1:20241 se enlazó por socket al PID cloudflared correcto antes/después del único GET local de métricas; parent/guest/PID permanecieron estables. No se hicieron peticiones públicas o Sablier. Acredita conectividad nativa seleccionada, no autenticación/rutas E2E.

La autoridad de red identifica CT123 en 192.168.0.XXX, CT219 en.219 y el observador CT217 en.217: un VMID no permite deducir su IP. Prometheus usa modo host y comparte netns con CT217; ambas rutas seleccionan origen.217/eth0. Los conectores no tienen flag ni entorno de métricas explícitos; un candidato de entorno es viable con sus versiones, sin reescribir ExecStart/tokens. Las cadenas input observadas tienen policy ACCEPT sin reglas: no acreditan ACL. La métrica sigue en loopback; no se abrió ningún puerto ni se cambió firewall. La centralización continúa pendiente de ACL propia, persistencia/rollback y transición revisada de26a27jobs; no se instaló scrape ni alerta sin productor.

Recibos privados en ~/.local/state/cloudflared-metrics-authority-20261021-y1h9bq2d/: ct219-gauge.json SHA256 <REDACTED>; ct123-gauge.json SHA256 <REDACTED>.

Revalidación de conectores, 14:37 CEST

CT219 registra4 conexiones locales a las 14:37:54,830 y CT123 otras4 a las 14:37:57,173, con guardas de padres, huéspedes y procesos antes/después. CT219 está en el boot nuevo 61e19d74…, PID292/start2957, NRestarts1; CT123 conserva 1f77b833…, PID129/start3011, NRestarts0. NRestarts1 no identifica el desencadenante de ningún reset. El getter tipado confirma EnvironmentFiles vacío exacto en CT123 y count1 en CT219, sin leer el archivo ni exportar valores. CT219 sigue bloqueado para ACL; en ambos falta el entorno loopback explícito exigido por la recuperación del binding. No se ejecutó nft, no se admitieron mutaciones ni hubo peticiones públicas/producto. El gauge acredita conexiones del conector, sin prueba E2E de las aplicaciones.

Recibo privado: ~/.local/state/cloudflared-readmission-epoch74-20261021-1pkhr2ri/receipt.json, SHA256 <REDACTED>.

La lectura selectiva de 14:40:27 identifica ese EnvironmentFile de CT219 como /etc/cloudflared/tunnel.env, requerido, regular, root0600,198bytes y almacenamiento local. Contiene una asignación ajena a TUNNEL_METRICS; no se exportaron su nombre ni valor. No se debe resetear ni sobrescribir ese archivo para añadir métricas. En ese punto la fuente mantenía el rechazo; PR111 añadió después la admisión acotada ligada a identidad/hash y ausencia comprobada de esa variable, con rechazo de cualquier deriva. El hallazgo por sí solo no admitía mutaciones; las fases reales posteriores se fechan aparte. Recibo privado cloudflared-envfile-selected-20261021-a3ccahu9/ct219.json, SHA256 <REDACTED>.

Avance operativo histórico,15:07 CEST

La redundancia de entrada tiene evidencia de conmutación natural. En la ventana del fallo, el journal de CT271 registra MASTER a las13:58:50,869010 y BACKUP a las13:59:47,490190:56,621180s según el mismo reloj. CT270 registra FAULT al iniciar keepalived a las13:59:40,788, script sano a las13:59:44,757 y MASTER a las13:59:47,490064. No se infiere alineación submilisegundo entre huéspedes, ausencia de solapamiento, entrega de paquetes ni RTO E2E. MASTER271 precede al btime de pmx50; btime no fecha por sí solo el instante físico del fallo. A las15:07:32–33 la VIP está únicamente enCT270, con propietarios y boots comprobados. No se provocó ninguna caída ni se hicieron peticiones de producto. Recibo privado vip-natural-failover-20261021-48s1s247/receipt.json, SHA256 <REDACTED>.

CT123 yCT219 pertenecen al mismo túnel. A las14:51:52–55, los registros Starting tunnel de sus PID actuales producen el mismo hash de UUID; no se exportaron UUID, token ni mensajes. Ambos usan tunnel run con token, uno por argv y otro por entorno. Esto acredita la identidad del túnel, sin prueba de rutas, autenticación ni backend. Recibo cloudflared-same-tunnel-20261021-mwpzn8sk/receipt.json, SHA256 <REDACTED>.

PR111, main80c222d, preserva el EnvironmentFile de credenciales deCT219 mediante pins privados y prueba estrecha de ausencia deTUNNEL_METRICS;22 pruebas, CI de PR/postmain y nft -c nativo1.1.3 correctos. Una única aplicación real a las14:59:44 añade la tabla propia y su persistencia, sin flush ni llamadas a nftables.service. El primer verificador externo rechazó NeedDaemonReload=yes, que era esperado tras instalar el drop-in de orden. Se conserva ese resultado incierto; la lectura independiente de15:01:52 confirmó tabla/config/include/drop-in exactos, mismo PID292, listener loopback, archivo de credenciales intacto y ambos gauges4. No se repitió apply. Recibo de cierre cloudflared-ct219-rollout-20261021-7v5abjzl/closure-receipt.json, SHA256 <REDACTED>.

A las 15:06:50, una creación exclusiva del drop-in50 y una daemon-reload cargaron TUNNEL_METRICS=.219:20241 y BindsTo/After efectivos de nftables. En esa lectura el proceso292 seguía sin esa variable y mantiene socket loopback: cargar la unidad no reinicia el proceso. Reglas, persistencia y credenciales se revalidaron; ambos conectores conservaron4 conexiones. Esta fase no admite todavía exposición. Recibo phase2-closure.json en el mismo directorio privado, SHA256 <REDACTED>.

PR112, maind55cafe, añade transacción y retirada durables de únicamente las dos reglas Cloudflared, con CONFIG inmutable, CAS de RULES y verificación de dos evaluaciones sanas. 69 pruebas y tres checks correctos. La API real de Prometheus3.15.0 se comprobó a las 15:03:27:22grupos/92reglas de alerta, todas sin errores de evaluación; no hay grupo Cloudflared. El esquema y el formato de las dos expresiones candidatas son compatibles. Fueron cinco GET, sin evaluar consultas, cambiar configuración ni probar notificaciones. No acredita todavía comparación semántica de las92 reglas ni instalación del grupo. Recibo prometheus-rules-api-ro-20261021-twgkzko0/receipt.json, SHA256 <REDACTED>.

Próximos pasos con objetivo y criterio de cierre

Orden Trabajo concreto Se cierra cuando
P0 · estabilidad Resets del22oct a15:46,16:07 y16:21; causa cliente→mux→hardware abierta. Las capturas UNKNOWN quedan como antecedentes, sin repetir instrumentación a ciegas. La prueba del kernel -25 instalado espera respuesta sobre acceso físico y reinicio; no modificar el pin -19 mientras tanto Causa sustentada y corrección verificable; después una ventana representativa sin resets. La expiración hardware sola no identifica causa
P0 · datos Cuatro grupos y publicación con éxito; scheduler ya confirma ended/exit0 y próxima ejecución. Comprobar ahora la generación recuperable Manifiestos/dump/originales coherentes y prueba aislada de recuperación; no repetir la copia por un error del lector
P1 · N-1 Ventana22oct08:51–10:51:121/121 muestras, envolvente−3,81GiB tras reserva2GiB y comparación por mayor ronda−2,02GiB. El +681,37MiB del21oct es histórico. Resolver capacidad o acordar un perfil funcional concreto antes del ensayo de caída; Jellyfin se conserva y Vera es trabajo del usuario Reserva de 2 GiB sostenida y margen de crecimiento/arranque. RAG251/Homelable305 solos no acreditan solución; no tocar Vera ni recortar RAM a ciegas
P1 · configuración Aplicar la máscara de credencial heredada preparada para hunter/scanner cuando se admitan estabilidad y preservación de trabajo Máscara vacía sólo en esos dos servicios, demás credenciales/flags preservados y comportamiento comprobado; sin copiar claves ni recrear bajo el hold actual
P1 · continuidad de entrada Scrape de ambos conectores verificado; reglas aplicadas con validación completa previa y dos evaluaciones sanas exigidas. Readback independiente cerrado23:40. Revisar cobertura de avisos y drill Caddy con retorno Métricas/ausencia/cero conexiones vigiladas y evidencia acotada de reglas; VIP/TLS/auth/ruta funcional requieren sus pruebas propias
P1 · recuperación Ejercicio DATA-ONLY Jellyfin cerrado: extracción, SQLite y retirada comprobadas. No encadenar más restores; retomar prioridades globales. CT217 y las pruebas funcionales/DR restantes conservan su backlog propio; Immich3.3.5 no se reabre Cada ensayo futuro requiere priorización y alcance explícitos; el cierre de datos Jellyfin no acredita app, bibliotecas NAS o failover HA
P1 · energía Acreditar alimentación NAS/red, autonomía efectiva y parada nativa; completar guarda Meross por canal HA permitido Recibos actuales de la secuencia completa, reserva superior al presupuesto nativo más 60 s y validación del coordinador. No activar mientras falte evidencia
P2 · copias independientes Medir crecimiento de archive al menos tres días y comprobar generaciones buenas; diseñar copia con dominio independiente/offsite Retención preserva puntos restaurables, existe restore desde archive y copia independiente verificada; no basta un job verde
P2 · código retirado Mantener alerta146 de WP visible para revisar antes de una eventual reactivación; no ampliar ahora el proyecto retirado No dar por corregida la dependencia por apagar el servicio; recuperación requiere revisión explícita
P2 · funcionalidad y acceso Cerrar las 29 verificaciones pendientes de los 11 contratos con flujos específicos; resolver candidato Soularr Evidencia de función/login/recuperación por producto sin despertar indiscriminadamente servicios ni ampliar permisos para pasar checks

No ampliaría HA a más recursos ni levantaría afinidades estrictas antes de resolver estabilidad y presupuesto. La protección útil siguiente es garantizar un núcleo pequeño que realmente cabe y se recupera, y mantener una vía de observación/recuperación disponible cuando CT217 o PBS estén caídos. No hace falta añadir otra plataforma para documentar y comprobar esos procedimientos.

Evidencia, método y límites

La auditoría inicial usó lecturas nativas/metadatos, informes y Prometheus existentes: ningún failover, reinicio, migración, copia, restore, GC/prune, sondeo NAS, petición pública/Sablier dynamic ni acceso a Home Assistant. Los dueños y boots se comprobaron antes/después: pmx50 c4c64375… y pmx51 86184726… en aquella muestra. El nuevo epoch y la preparación posterior del frontend se documentan por separado; escribieron un directorio privado nuevo sin cambios de servicio, API o datos de producto. Las fases Cloudflared posteriores sí aplicaron una ACL, un drop-in, una daemon-reload y una orden de restart sólo en CT219; sus resultados y límites se registran arriba. Los errores iniciales de lectores Caddy y una opción no soportada de pvesr se conservan; lecturas posteriores válidas aportaron evidencia, sin convertir el error del lector en fallo del servicio.

Recibo privado local SHA256
~/.local/state/ha-coverage-20261021-x92_we4v/pmx.json <REDACTED>
Mismo directorio, pmx2.json <REDACTED>
Mismo directorio, pmx2-replication-native.json <REDACTED>
Mismo directorio, nminus-memory-existing-metrics.json <REDACTED>
~/.local/state/ha-access-review-20261021-w4cc1x89/receipt-index.json <REDACTED>
~/.local/state/ha-dns-fixed-20261021-b5wrj44f/projection.json <REDACTED>

Los recibos privados no se publican en Git; contienen proyecciones sin secretos. Los ensayos históricos conservan fecha y alcance en los documentos enlazados.

La revisión de backups/capacidad leyó Prometheus a las 10:38:09 y 10:39:00 CEST (resultados de herramienta, sesiones 36681/31151); no generó archivos de recibo ni hashes persistidos. Sus observaciones no se presentan como artefactos locales. Energía se contrastó documentalmente con los planes del 19 de octubre, sin nueva medición física hoy: coordinación SAI.

Evidencia adicional privada de las 11:03–11:06:

Proyección SHA256
~/.local/state/nminus-native-20261021-m008irxm/calculation.json <REDACTED>
Mismo directorio, degraded-candidates.json <REDACTED>
~/.local/state/cloudflared-live-metrics-20261021-9wqt_7_8/ct123.json <REDACTED>
Mismo directorio, ct219.json <REDACTED>
Mismo directorio, prometheus-coverage.json <REDACTED>

Los endpoints locales de métricas de cloudflared se acreditaron en el journal del PID actual antes de leerlos; no se adivinaron puertos ni se imprimieron argumentos/tokens. Prometheus conservaba 26 jobs/44 targets, con cero jobs, series o reglas de cloudflared. Cuatro conexiones por conector acreditan ese estado, no el acceso externo o el funcionamiento de cada backend.

Evidencia privada posterior al reset:

Recibo SHA256
~/.local/state/postreset-ha-20261021-x8q8l47m/receipt-index.json <REDACTED>
~/.local/state/originals-natural-20261021-61qeh4zb/recovery-epoch558-hrbuv0n9/recovery-assessment.json <REDACTED>
~/.local/state/runwisp-native-ro-epoch558-k5m27s33/receipt.json <REDACTED>

Las tablas del análisis inicial conservan observaciones previas a las11:56; la sección de recuperación al principio especifica qué se revalidó después.

Actualización de seguridad del frontend: fuente integrada

La PR97 se integró el 21oct a las 11:20:02 CEST, main <REDACTED>. Actualiza Next/eslint-config-next a 15.5.28; instalación frozen, lint, TypeScript y build pasan en Linux/Node22, también después del merge. Conserva React y overrides de main; corrige 16 entidades JSX sin cambiar texto visible. Braces sigue abierto, sin parche compatible acreditado. Véase la ficha de seguridad.

La web viva aún no está parcheada: lectura de archivos locales encuentra Next15.5.23/Sharp0.35.3/React19.1.0 y Node20, distintos de Git. De 370 archivos frontend comparados, 368 coinciden con la base; difieren manifiesto y lock. Se prepara entrega frontend-only Linux/Node22 sin reconstruir dentro del CT con poca memoria, y sin ejecutar el script de despliegue que también toca API y migraciones. No se presenta un build verde como actualización del servicio. Recibo privado ~/.local/state/wp-web-hash-review-20261021-1cp8niz1/receipt.json, SHA256 <REDACTED>.

La PR99, integrada a las 11:47:58 CEST, añade entrega Linux del frontend mediante el workflow existente. Main <REDACTED> pasó instalación frozen, lint, tipos, build, ocho pruebas del empaquetado y prueba nativa Sharp. El artefacto de Actions se descargó y verificó en el Mac: digest de Actions, hashes del tar/manifiesto, 374 archivos fuente y cierre de enlaces/rutas. Incluye Next15.5.28, Sharp0.35.5 y React19.3.0; el Node privado previsto es22.23.3, archivo oficial verificado por SHA256. En aquella fase sólo se verificó en Mac; la extracción privada posterior en el CT se describe abajo. Node sigue sin instalarse en su destino definitivo de servicio.

El helper original quedó sin ejecutar: el boot observado a las12:04 invalidó sus guardas. Se hizo una nueva admisión explícita para preparación privada, con guest 44de8787…, web PID886/API PID885 y filesystem local dev47, que había cambiado desde dev59. La unidad, procesos y los 370 archivos fuente se revalidaron: 368 siguen iguales a la base y sólo manifiesto/lock mantienen las diferencias anteriores. No se reutilizaron los PIDs, dispositivo o guardas del boot antiguo.

Candidato preparado en CT281, 21oct a las 12:42:54 CEST

El primer allocator abortó antes de mkdir porque Python de sistema carece de tarfile.data_filter; el readback confirmó que no había directorios de stage. No se retiró ese requisito. El Python 3.14.5 existente sí tiene el filtro, pero pertenece a wp: se ejecutó sólo como UID/GID 990, con grupos suplementarios vacíos, -I -B -S y entorno limpio. Nunca se ejecutó ese intérprete como root.

Root creó un sibling nuevo, modo0700, y transfirió siete entradas regulares EXCL0600 con hashes/fsync y entregó su propiedad a990 sólo al terminar. Dentro del stage, con nice10 e ionice idle, se extrajeron el frontend y Node a destinos nuevos con filtro seguro, inventario cerrado y enlaces internos. La prueba nativa PNG/JPEG de 2×2 pasó con Node 22.23.3, Next 15.5.28, Sharp 0.35.5, React/react-dom 19.3.0 y glibc 2.36 del CT; no se importó la aplicación.

Root verificó después los 34.097 elementos del frontend y 5.866 de Node usando código revisado y pinneado en RAM sobre Python de sistema. No ejecutó Node o el Python privado como root. Los inputs conservaron hashes/full9; los procesos, fuentes vivas y boots permanecieron iguales antes/después.

Stage guest /opt/wp-pulse-server/.wp-web-stage-c598-k60trahk. El candidato es modificable por UID990 y no está admitido para activación: requiere fijar su estado/propiedad de nuevo, preparar Node accesible, conservar íntegro el árbol viejo y la unidad/dropins, y revalidar el entorno efectivo. La web viva sigue con Next 15.5.23; no hubo stop/start, cambio de unidad ni migraciones. La prueba sintética no acredita E2E del producto.

Recibos privados en ~/.local/state/wp-web-delivery-20261021-f1ne0jey/epoch558-wp-stage-2aguvt_3/:

Recibo SHA256
guest-staging-result.json, mismo hash que el recibo del CT <REDACTED>
closure-index.json, incluye plan, transferencia, guardas y peer <REDACTED>

Admisión de recuperación y logout, 12:50–12:57 CEST

Unidad y entorno efectivo revalidados: web User/Group wp, directorio habitual, Type simple, KillMode control-group, enabled y NeedDaemonReload=no. No hay flags host/port explícitos ni prestart/poststart; API y sus procesos siguen sin cambios. La variable pública de logout está ausente de unidad, archivo de entorno y proceso. La prueba AST del candidato conserva exactamente la semántica acreditada en el chunk antiguo: undefined/null usan el default, vacío/otro valor se preservan y un solo href recibe ese binding. No se afirma un literal histórico embebido; se acredita compatibilidad semántica, sin ejecutar chunks ni importar la aplicación. Parser Acorn8.19.0 del candidato verificado contra el manifiesto, ejecutado como wp con Node22 privado.

La prueba sintética nativa de las 12:52:49 confirma intercambio RENAME_EXCHANGE e inverso entre dos directorios nuevos de ZFS dev47, con inodos/marcadores íntegros y fsync. El primer intento falló antes de mkdir por exigir erróneamente Python3.10: el sistema real es3.11.2. Se conserva ese fallo; no fue error del syscall. No se renombró web/candidato/Node reales.

Otra prueba sintética con el Node22 privado y las dependencias antiguas Next15.5.23/Sharp0.35.3 pasó PNG/JPEG como wp. Acredita compatibilidad nativa del estado intermedio, sin arrancar la aplicación. La receta revisada de entrega exige intercambio atómico y recuperación por fase, conservando íntegro el árbol viejo y el directorio de trabajo. No admite sustituirlo por dos renames. Faltan aún runtime definitivo accesible, fijación del candidato, respaldo privado de unidad/dropins y el cambio real del servicio; no son bloqueos de permisos ni requieren esperar14 días para preparar el parche.

Recibo privado local SHA256
~/.local/state/wp-web-cutover-admission-20261021-u_slu4yc/projection-v3.json <REDACTED>
~/.local/state/wp-candidate-ast-20261021-f1g5wdft/projection.json <REDACTED>
~/.local/state/wp-web-delivery-20261021-f1ne0jey/rename-exchange-probe-v2-nnfiws42/receipt.json <REDACTED>
epoch558-wp-stage-2aguvt_3/old-web-compat-result.json dentro de ese directorio de entrega <REDACTED>

Cierre de WP por prioridad del usuario, 13:01 CEST

El usuario indica que el proyecto sigue vigente, tiene poca actividad y pide mantenerlo funcional y pasar a otras áreas. No se despliega el candidato ni se continúan preparativos de cutover. Comprobación básica a las13:01:22, con padre/propietario/boots y procesos invariantes antes/después:

  • Web: HTTP200 en el manifiesto estático del build actual y SHA idéntico al archivo local, 2.353 bytes. No se solicitó el dashboard SSR.
  • API: liveness HTTP200/status ok y readiness HTTP200/ready true.
  • Base de datos: SELECT1 correcto; cuatro tareas de fondo vivas y ninguna registrada como fallida.

Se acredita funcionamiento básico, sin afirmar login, flujo completo de cliente o parche de la web viva. No se tocaron unidades ni hubo stop/start. Se conserva el candidato privado; el foco vuelve a estabilidad pmx50 y recuperación. Recibo epoch558-wp-stage-2aguvt_3/basic-functional-result.json dentro del directorio privado de entrega, SHA256 <REDACTED>.

Mejoras posteriores a la revisión: scheduler y readiness

La consulta de scheduler queda cerrada por la comparación UID de las12:22 descrita arriba: mismo handle terminado con salida0, próxima ejecución mañana. No se cambió RunWisp para corregir un defecto de contexto del lector.

La PR1 de homelab-stacks se integró en su rama principal master a las 12:31:47 CEST, commit <REDACTED>. Corrige un hueco de readiness de Hunter: ambas rutas de salud responderán503 hasta completar la inicialización, durante shutdown o al terminar el motor. El payload conserva sus campos y añade ready; no consulta Put.io si aún no está listo. Mantenimiento intencional, automático desactivado, esperas normales y un ARR degradado mantienen200.

Pasan46 pruebas en Python3.12/3.14 y14 solicitudes ASGI en memoria con FastAPI real, que acreditan la inyección de Response y los estados HTTP de ambas rutas. No hay workflow CI en Stacks; son pruebas locales, sin servidor, app startup, credenciales o solicitudes de producto. La imagen viva no se reconstruyó ni recreó. No reduce las29 verificaciones de función/acceso/imagen/restore. Recibo privado ~/.local/state/hunter-readiness-asgi-20261021-orqylp_l/receipt.json, SHA256 <REDACTED>.

Rchat: corrección integrada y acceso pendiente, 22 octubre 21:01 UTC

La PR6 de reddit-chat está integrada en main, commit <REDACTED>. Elimina el retorno de tokens caducados tras fallar la renovación y el guardado de respuestas caducadas; agrupa renovaciones concurrentes y aplica espera compartida de30 a600 segundos. Un401 tardío rechaza sólo el token utilizado en esa solicitud. Los cambios de credenciales invalidan resultados antiguos, y un fallo de escritura entra en espera sin divulgar excepciones o cuerpos del proveedor.

Pasan 17 pruebas aisladas en Python3.12 y3.14, incluidos Matrix.req real con HTTP simulado, carreras de credenciales y fallos de persistencia. Ambos jobs del run CI39853725383 terminaron SUCCESS sobre el head exacto. Los cinco archivos del merge coinciden con los revisados; el checkout canónico quedó actualizado y limpio.

El servicio real es Docker rchat de CT218, padre proxmox2; VM208:8791 sólo reenvía a192.168.0.XXX. El Docker antiguo de VM208 está apagado y no se arrancó. Caddy y el target Prometheus mantenidos ya usan personal.lan:8791. El contenedor activo lleva desde19oct20:00:22UTC, sin reinicios, y Docker lo marca unhealthy. Sus tres fuentes afectadas coinciden con main anterior normalizando saltos de línea; la corrección aún no está desplegada.

Un GET local de salud con salida filtrada confirmó HTTP503, token no válido, sync sin éxito durante8317s, cookie presente y último error clasificado HTTP403. No se exportaron cuerpos de error, tokens, cookies ni conversaciones. Esto acredita el fallo de acceso, sin demostrar que la cookie haya caducado ni que los defectos de reintentos lo causaran. El código corregido no acredita recuperación del403. Antes de entregar hay que comprobar las tareas que el reinicio pueda interrumpir; no se han enviado mensajes, cambiado credenciales o reiniciado el servicio.

Recibos privados locales: rchat-auth-source-proof-v2-4kbs0e5u/proof.json, SHA256 <REDACTED>; rchat-merged-review-7ezffys4/proof.json, SHA256 <REDACTED>. El portal local conserva la incidencia en progreso y distingue integración de fuente, entrega y recuperación funcional.

Entrega Rchat completada, 22 octubre 21:13–21:14 UTC

La corrección anterior ya está desplegada en CT218 desde21:13:46UTC. Se construyó una imagen derivada de la imagen existente, sin RUN, pull ni instalación de paquetes, copiando únicamente los tres archivos corregidos de main0640140. El manifiesto de entrega fija base, candidato, hashes, receta y retorno. Las capas base y la configuración de imagen se conservaron; sólo cambió la imagen del servicio en Compose y se comprobó la igualdad del resto de su configuración efectiva.

Antes de recrear únicamente Rchat se comprobaron dos veces: cero envíos en curso, cero pendientes para los cinco minutos siguientes y cero conexiones entrantes establecidas. Se conservaron la imagen anterior y la copia privada de Compose; no se restauraron datos ni cambiaron credenciales. La revisión independiente de las21:14:22UTC confirmó tres hashes exactos, proceso nuevo activo, cero reinicios, configuración Compose coincidente y cero envíos en curso o vencidos.

El acceso sigue pendiente: salud local HTTP503, token inválido, sincronización sin éxito y renovación rechazada HTTP403. El proceso nuevo había registrado dos intentos fallidos en32s; el contador reinicia con el proceso. No se atribuye el403 a una cookie caducada ni se presenta el despliegue como recuperación del proveedor. Docker seguía en health starting en esa lectura; no hay acreditación de login. No repetir este despliegue para intentar resolver el rechazo de autenticación.

Recibo independiente privado rchat-native-release-3lqtkt5c/independent.json, SHA256 <REDACTED>. El primer preparador falló tras construir por consultar un campo GraphDriver inexistente: no cambió runtime ni se repitió la construcción; se validó la imagen y sus archivos sin arrancarla antes de la entrega revisada.

Arranque nocturno de pmx50 detectado el 23 de octubre

Lectura OS a las 02:31 UTC / 04:31 CEST: pmx50 tiene boot <REDACTED_UUID>, kernel 7.0.14-19-pve y uptime 14191 segundos, que sitúa aproximadamente el arranque a las 00:35 CEST del 23oct. Es posterior al boot 51c5 acreditado a las 18:12 CEST del 22oct; no se atribuye un número exacto de reinicios intermedios no observados. pmx51 conserva boot <REDACTED_UUID>. Ambos informan quórum, tres votos y mínimo dos. No se cambió kernel, selección de arranque, BIOS ni watchdog.

Una lectura seleccionada del kernel actual devuelve una fila a las 22oct22:34:44.561582UTC / 23oct00:34:44.561582CEST: Previous system reset reason [0x02000800]: hardware watchdog timer expired. Es el motivo reportado por firmware/kernel al arrancar; esa marca no mide el instante físico del reset ni demuestra por qué dejó de alimentarse el contador.

Ventana conservada en pmx51

Se leyó únicamente journal existente de corosync, pve-ha-crm y pve-ha-lrm, 22oct22:33–22:36UTC. Devuelve 22 eventos seleccionados/9647 bytes, exit0 y stderr0; boot de pmx51 estable. Ningún mensaje de LRM pasó el filtro; no significa que el LRM estuviera inactivo o que no existieran otros eventos fuera de la ventana.

Hora UTC del22oct Registro
22:34:16.663581 KNET: enlace al nodo1 down; sin enlaces activos.
22:34:20.077587 TOTEM: token no recibido en7500ms.
22:34:22.577568 TOTEM: token timeout10000ms; nueva configuración.
22:34:34.578525 QUORUM: sync left nodo1.
22:34:36.473151 Miembros: sólo nodo2.
22:34:44.561582 Mensaje de razón de reset en el nuevo kernel de pmx50, de la lectura separada.
22:34:46.509272 CRM: proxmox online→unknown.
22:34:58.468860 KNET: enlace al nodo1 up.
22:35:00.711677 Miembros: nodos1 y2.
22:35:06.564713 CRM: proxmox unknown→online.

Estas marcas proceden de registros de hosts, no de un reloj externo del reset. La secuencia acredita pérdida y retorno de comunicación reportados por el peer; no distingue congelación global, pérdida de red, problema de driver o decisión local de fencing. No prueba recepción de KEEPALIVE ni eficacia física de un contador. No se activó instrumentación ni se repitieron capturas de línea base. El primer lector de la ventana quedó UNKNOWN por un import ausente; se conserva. Tras corregirlo y validar el lector con un pipe sintético, la segunda lectura acotada produjo la evidencia indicada, sin cambiar productores ni servicios.

Estado actual, con alcance limitado

A las 02:33:40 UTC / 04:33:40 CEST, la API HA muestra 14 servicios started, todos en pmx51. LRM de pmx50: idle/watchdog standby; LRM de pmx51: activo. Eso describe el momento de lectura, no el estado anterior al incidente ni una conmutación funcional demostrada. No se consultó configuración de huéspedes.

A las 02:39:54 UTC / 04:39:54 CEST, el inventario de control muestra 29 huéspedes: 28 running y 1 stopped, CT281/WP-Pulse retirado. VM208 y CT186/PBS figuran running en pmx50. No se ejecutó nada dentro de los huéspedes ni se consultaron sus aplicaciones; running no demuestra reproducción, montajes, dumps, copias ni recuperación integral. No se renueva con ello la admisión N−1.

La prueba controlada del kernel 25 ya instalado sigue pendiente de respuesta sobre disponibilidad física y autorización; no se altera el pin 19 ni se solicita reboot. Causa raíz abierta. Mantener observación ordinaria y conservación de estas evidencias, sin añadir carga para reproducir el incidente.

Recibos privados seleccionados:

  • proxmox-overnight-state-526zhtdh/selected.json, SHA256 <REDACTED>.
  • proxmox-reset-reason-independent-agioc5or/selected.json, SHA256 <REDACTED>.
  • proxmox-peer-reset-timeline-5r5gqmnn/selected-v2.json, SHA256 <REDACTED>.
  • proxmox-overnight-ha-mq9j9r_h/selected.json, SHA256 <REDACTED>.
  • proxmox-postboot-inventory-mpt6i92o/selected.json, SHA256 <REDACTED>.