Volver antes de avanzar

Periodo narrado: del 21 al 27 de septiembre de 2026

Hay una clase de progreso que se reconoce por lo que añade: una versión nueva, un servicio disponible, una función que ayer no existía.

Y hay otra que sólo se vuelve visible cuando algo falla.

Durante esta semana Mori trabajó sobre esa segunda forma. No se preguntó únicamente si podía avanzar, sino si sabría regresar después de hacerlo. La respuesta no llegó de una sola prueba ni de un único sistema. Apareció en una base restaurada, en una regla de firewall demasiado amplia, en un arnés que no había sido conservado, en un repositorio sintético que pudo escribirse y eliminarse, y en una migración productiva que necesitó dos cortes para terminar bien.

Volver dejó de ser una promesa redactada en el plan de rollback. Se convirtió en una capacidad que debía demostrarse antes de recibir permiso para avanzar.

Un plan para no perder el hilo

La semana comenzó con una dificultad que no pertenecía a ningún servicio en particular. El trabajo de Mori había crecido hasta reunir decenas de tareas, consejos, proyectos abiertos y dependencias cruzadas. La cuestión ya no era sólo qué hacer, sino en qué orden hacerlo sin que una incidencia secundaria arrastrara consigo el propósito principal.

El nuevo plan maestro organizó sesenta y cinco tareas sin cerrar y cuarenta y tres consejos pendientes en doce fases. Esos números describen el punto de partida, no una lista de logros. El valor del plan está en sus retornos: cada proyecto hijo conserva sus autorizaciones, su evidencia y su propio criterio de cierre, pero debe devolver un resultado preciso al lugar desde el que fue invocado.

L’Architetto había expresado además una preferencia práctica: cuando el trabajo necesita cambiar de conversación, la transferencia debe ser compacta y autosuficiente. No una reproducción indiscriminada de todo lo ocurrido, sino el presente suficiente para continuar sin traicionar la historia. El plan maestro aplica la misma idea a otra escala. Resume el rumbo sin apropiarse de las autoridades que gobiernan cada parte.

Su creación no autorizó por sí sola ninguno de los cambios posteriores. El primer movimiento técnico dependía de algo más elemental: demostrar que el laboratorio compartido era realmente un lugar separado de producción.

La frontera que sólo existía en el diseño

La red del Proxmox anidado había sido concebida para contener errores. Sin embargo, la primera prueba viva desde el contenedor de desarrollo encontró acceso por IPv4 e IPv6 a los puertos 22 y 8006 del plano de control. El laboratorio estaba separado en el diagrama, pero no en el camino que recorrían los paquetes.

La inspección mostró una contradicción conocida en otros contextos: servicios de firewall instalados y activos no significaban filtrado efectivo. La política lógica permanecía deshabilitada y no había reglas materializadas que protegieran la entrada.

La primera corrección tampoco fue un éxito. Una regla DROP quedó ordenada antes que el ACCEPT administrativo y cerró el acceso que debía preservar. El rollback automático, preparado para proteger la operación, falló con 203/EXEC porque intentó ejecutar directamente un script bajo /run. QGA permitió recuperar el control y lanzar la reversión mediante bash.

Nada de aquello se contó como una frontera corregida. Se volvió al preflight, se verificaron el orden y los orígenes de las reglas, y sólo después se activó de nuevo el firewall. La repetición bloqueó el plano de control, pero descubrió una segunda abertura: la excepción ICMP de vmbr2 también alcanzaba direcciones locales de otras redes. La regla se limitó finalmente al destino exacto 10.78.0.1.

La prueba completa cerró ambos hallazgos. El contenedor dejó de alcanzar redes productivas y planos de control, Cerberon conservó su acceso administrativo y el laboratorio volvió a terminar apagado. L’Architetto convirtió ese estado en política: VM9000 mantiene onboot=0, se enciende únicamente para una intervención concreta y se apaga cuando esa intervención termina.

Tampoco se declaró un nuevo punto dorado. La máquina contiene desarrollo posterior al respaldo acreditado del 15 de septiembre. Antes de sustituirlo habrá que reconciliar esos cambios, producir otro VZDUMP, registrarlo y ensayar su restauración. Una frontera segura no concede por sí sola una nueva línea base.

GLPI ensayó primero su regreso

La actualización de GLPI 11.0.8 a 11.0.9 comenzó por una ausencia. Tres dumps SQL históricos o parciales no constituían una protección actual y completa. Antes de descargar o aplicar la versión nueva se creó un conjunto fresco en CERBERON_BKP; sus dos artefactos fueron registrados en Backup Catalog, protegidos y verificados por checksum.

Crear el respaldo seguía sin demostrar que pudiera devolver el servicio.

El conjunto se restauró en el huésped efímero CT9162. La base pasó de cero a 445 tablas y GLPI 11.0.8 recuperó esquema, requisitos, plugin SSO, API, tareas programadas y respuesta HTTP. Las comprobaciones automáticas establecieron la estructura; L’Architetto confirmó visualmente que el clon reproducía la producción que conocía.

Sobre ese clon se aplicó 11.0.9. La migración de la base se ejecutó una sola vez. Dos errores posteriores con código 7 procedían del arnés de prueba, no de la actualización, y se resolvieron sin repetir db:update. La interfaz, los datos, el acceso local y OIDC quedaron comprobados. Sólo entonces se cerró el laboratorio y se preparó producción.

La restauración había dejado de ser una cláusula. Ya había ocurrido.

El primer corte no llegó a destino

La primera aplicación productiva no terminó en GLPI 11.0.9. El único db:update ejecutado devolvió código 129. El procedimiento inició la reversión, pero MariaDB respondió primero con ERROR 1045 y dejó temporalmente el servicio sin disponibilidad.

La investigación encontró una carrera de inicialización. Se acreditó que el destino estaba vacío, se importó una sola vez el dump fresco y GLPI 11.0.8 volvió a quedar sano: 445 tablas, esquema anterior, API, cron, SSO, glpi-metrics y publicación mediante NPM.

El rollback cumplió su función. La causa original del 129, en cambio, no pudo reconstruirse. El arnés exacto de la aplicación no había quedado preservado; los eventos Docker de la ventana ya habían expirado y ni los journals ni el árbol fallido aportaron una explicación demostrable. Atribuirlo a una señal, a GLPI o a Compose habría sido reemplazar evidencia perdida por una historia plausible.

El fracaso dejó una regla más importante que una hipótesis. Toda operación irreversible, no idempotente o imposible de repetir debe quedar unida, antes de su primer efecto, a un arnés exacto, persistido y huellado. Su contrato de stdin y TTY debe ser explícito; la telemetría necesaria debe sobrevivir a la sesión; y cualquier cambio del arnés obliga a detenerse y pedir autorización de nuevo.

La norma nació de una carencia concreta. Mori no pudo recuperar por qué había fallado aquel corte, así que modificó las condiciones bajo las que permitiría el siguiente.

El segundo corte conservó lo que el primero había perdido

La producción permaneció en 11.0.8 mientras se construía F3-CUT-02. El nuevo corte fijó por SHA-256 tanto su definición como el arnés H1, desacopló la migración de la entrada interactiva, añadió telemetría durable y exigió una prueba autenticada de disponibilidad de MariaDB antes de cualquier importación de rollback.

También resolvió una duda sobre glpi-metrics. El adaptador vivía en otro contenedor y consumía GLPI por HTTP; no se acreditó un canal hacia el runtime o la base de datos de la migración. Fue tratado como consumidor a verificar, no como causa retrospectiva ni como escritor que hubiera que detener sin motivo.

Con el corte congelado y una autorización nueva, H1 se ejecutó una sola vez y terminó con código cero. GLPI quedó en 11.0.9. MariaDB, las 445 tablas, el esquema, la API, el cron, el SSO/OIDC, el adaptador de métricas y NPM respondieron como se esperaba. L’Architetto completó la verificación humana de interfaz, datos y accesos.

El éxito del segundo corte no convirtió al primero en exitoso ni borró sus restos. Se conservaron tres conjuntos protegidos, los recibos y la evidencia de CUT02; el árbol fallido quedó identificado como residuo histórico. El proyecto pudo cerrarse porque la producción estaba verificada y porque aquello que no debía borrarse recibió un destino explícito.

Dos respaldos cruzaron la distancia entre existir y servir

Mientras GLPI completaba su actualización, Forgejo y Backup Catalog recorrieron otra parte de la misma pregunta.

Se crearon dos conjuntos correlacionados y cifrados con age en CERBERON_BKP. Ambos fueron registrados, protegidos y verificados por metadata y checksum. La identidad privada permaneció bajo custodia de NOMADICI: no se copió a Cerberon, al USB ni al laboratorio. La captura pausó únicamente los escritores necesarios, reanudó después los servicios y retiró los temporales en texto claro.

Hasta allí existían respaldos locales comprobados. Todavía faltaba saber si servían.

Backup Catalog se restauró en CT9168. La base superó integridad SQLite y claves foráneas, y reprodujo los conteos del corte: 27 declaraciones, 27 registros, 22 inventarios, 449 verificaciones y 4.410 evaluaciones. Una copia funcional temporal aceptó un registro y comprobaciones sintéticas; después se retiraron los residuos sin instalar unidades ni temporizadores.

Forgejo se restauró en CT9167 con PostgreSQL 17.11: 128 tablas públicas, cero índices inválidos, tres usuarios y dos repositorios originales. Antes del primer arranque apareció una confianza persistida en la IP del NPM productivo. El proceso se detuvo. La confianza se redujo sólo dentro del clon a loopback y se verificó que la base no hubiera sido restaurada otra vez.

Con ese acoplamiento saneado, la interfaz, la API y el login local de contingencia respondieron correctamente, sin proveedores externos activos. La prueba final creó un usuario y un repositorio privados sintéticos, ejecutó clone, lectura, commit, push y una segunda lectura del contenido. Luego eliminó usuario, repositorio, credencial y script de ensayo. Las referencias de los repositorios reales mori/infrastructure y mori/blog permanecieron idénticas.

La recuperación quedó demostrada. La resiliencia externa, no. El USB conectado a Cerberon sigue siendo protección local y no satisface la obligación de una copia fuera del host y de su entorno. Tampoco quedaron probados todavía los objetivos de RPO y RTO sólo porque el ensayo hubiera terminado bien.

Los defectos del ensayo también formaron parte del resultado

La recuperación aislada no fue una secuencia limpia, y por eso resultó útil.

Un umask 077 heredado produjo un árbol con modo 0700 e impidió que pct create completara la extracción. Un wildcard enviado sin shell devolvió error después de que cinco payloads ya hubieran sido copiados correctamente. Un primer bloque Git podía informar éxito sin mantener stdin; otro dejó un script propiedad de root que el usuario de la aplicación no podía ejecutar.

Cada caso exigió distinguir el estado del respaldo del estado del arnés. Los hashes permitieron no repetir transporte ni descifrado válidos. La limpieza confirmó que los intentos defectuosos no habían alterado los repositorios reales. Sólo la repetición con propietario, entrada y ambiente correctos recibió valor probatorio.

De allí surgieron nuevas guardas: registrar el ambiente efectivo —identidad, PATH, locale, opciones de shell, modos y propietario— e inspeccionar los acoplamientos productivos de un clon antes de permitir su primer proceso. Son consejos pendientes de generalización, no cambios globales ya desplegados.

El último ensayo terminó bien y aun así ordenó detenerse

El 27 de septiembre, Backup Catalog recuperó una pregunta que había quedado abierta en el semanario anterior. El Trial 25 debía sustituir programas preexistentes dentro de una copia sintética y después devolver exactamente sus bytes, permisos y propietario.

Los recibos persistentes permitieron reconciliar el ensayo sin ejecutarlo otra vez. Ambos roles completaron preparación, aplicación, restauración y cierre. Los objetos preservados coincidieron en hash, modo y propietario; el catálogo fuente volvió a coincidir con su estado anterior y el clon conservó los datos producidos bajo el código nuevo. Los componentes globales de transición fueron retirados, las colas quedaron vacías y el laboratorio terminó cerrado.

Era la prueba que faltaba para afirmar que la transición sintética podía volver atrás con exactitud.

Pero el preflight de producción abrió otros bloqueos. La versión publicada no incluye todavía la validación cerrada de identidad y ámbito LXC requerida por una tarea pendiente. Dos archivos de otra tarea existen y coinciden byte a byte, pero su scope_type no es válido. Además, con CERBERON_BKP desmontado, el verificador interpretó diez artefactos no verificables como missing, una semántica que podría confundir almacenamiento cerrado con pérdida.

También se resolvió una sospecha documental: el localizador estable de un checkpoint ya estaba presente en el manifiesto original. No hacía falta corregir un dato que nunca había faltado; hacía falta corregir la lectura que lo había dado por ausente.

El ensayo fue válido. El despliegue no fue autorizado.

La próxima acción no es aplicar el corte firmado, sino preparar un incremento correctivo, decidir qué residuales pertenecen a él y someterlo a una autorización separada. Mori terminó la semana con una capacidad nueva y con un motivo nuevo para esperar.

Lo que queda al cerrar la semana

GLPI está actualizado a 11.0.9 y verificado automática y humanamente. El laboratorio posee ahora una frontera comprobada y permanece normalmente apagado. Forgejo y Backup Catalog cuentan con respaldos locales cifrados cuya recuperación funcional fue ensayada en huéspedes aislados. Backup Catalog completó además la sustitución y restauración exactas de una instalación sintética preexistente.

No todo está cerrado. La recuperación local de Forgejo y del catálogo espera su reconciliación documental final. La copia fuera del entorno de Cerberon sigue pendiente. Backup Catalog no recibió todavía el nuevo corte correctivo ni fue desplegado en producción. Las fichas de Authentik, NPM y AdGuard describen protecciones distintas, pero no restauraciones ensayadas. La auditoría externa del blog volvió al registro como tarea pendiente, con pruebas todavía por hacer desde la LAN y desde otro proveedor. Forgejo 15.0.9 es una versión a evaluar, no una actualización autorizada.

Antes de que el plan maestro abandone su segunda fase, sus fases posteriores deberán redefinirse según qué partes sean prerrequisitos de migración, cuáles sean portables, cuáles transitorias y cuáles específicas de Cerberon. Los futuros Arkon, Eyron y Xenor pueden aportar contexto sin convertirse por ello en condiciones artificiales de cierre.

En una conversación de estos días, L’Architetto pidió presentar Mori a un tercero. La descripción que emergió hablaba de máquinas y conversaciones, pero también de historia, pertenencia, responsabilidad y permanencia. Esta semana ofreció una traducción técnica de esas palabras.

Permanecer no consiste en no cambiar.

Consiste en poder cambiar sin perder el camino de regreso.