id: ADR-012 título: La aplicación de configuración en vivo utiliza publicación y resultados con alcance de generación fecha: 2026-07-19 estado: propuesto relates-to:
- https://github.com/zeroclaw-labs/zeroclaw/issues/7897
- docs/book/src/architecture/config-lifecycle.md
- crates/zeroclaw-config/src/schema.rs
- crates/zeroclaw-gateway/src/api_config.rs
- crates/zeroclaw-channels/src/orchestrator/mod.rs
ADR-012: La aplicación de configuración en vivo utiliza publicación y resultados con ámbito de generación
Contexto
ZeroClaw puede guardar la configuración a través de las superficies CLI, RPC, TUI, Quickstart y gateway. Un guardado exitoso no significa que cada subsistema de larga duración haya adoptado el nuevo valor. El estado visible por el gateway puede cambiar de inmediato, mientras que los canales, sesiones, proveedores y otros componentes administrados por el daemon continúan usando su estado de ejecución anterior hasta que /admin/reload reconstruya el grafo de subsistemas.
RFC aceptado #7897 apunta a una mejora acotada: los cambios seleccionados de política de seguridad y de canal pueden aplicarse sin una recarga completa del daemon, mientras que los operadores reciben un resultado específico por objetivo para la generación que cada subsistema procesó efectivamente. La arquitectura aceptada requiere una configuración publicada canónica, resultados específicos por generación, superposiciones de seguridad estrechas y únicamente modos de transición de canal probados.
Este registro define ese objetivo y sus puertas de implementación. No afirma que la aplicación en vivo ya exista. Hasta que esas puertas se publiquen, el comportamiento actual de guardado versus aplicado y el fallback /admin/reload descritos en Config lifecycle siguen siendo autoritativos.
Decisión
Publicar una generación de configuración canónica
El proceso tiene una revisión de configuración publicada canónica. Los escritores dentro del proceso se serializan por separado de los lectores. Un escritor clona la revisión actual, aplica y valida sus cambios, persiste la configuración resultante dentro de la transacción de escritura serializada y solo entonces publica atómicamente la siguiente generación. La coordinación entre procesos independientes que editan config.toml queda fuera de esta decisión.
El bloqueo de configuración orientado al lector no se mantiene durante las operaciones de E/S de disco asíncronas. La publicación no crea una segunda caché de configuración de larga duración ni retiene una instantánea de configuración anterior para una reversión general.
Los eventos Apply identifican la generación publicada y las rutas modificadas. No incluyen otra copia completa de la configuración ni un valor de configuración anterior. Cada destino lee la revisión canónica actual y la aplica solo cuando su generación coincide con la del evento. Un evento reemplazado se omite y no puede sobrescribir el resultado de una generación más reciente.
Registrar los resultados de la generación que realmente se aplicó
Cada objetivo de aplicación registra su propio resultado específico de generación:
AppliedLivesignifica que el destino adoptó la generación identificada sin recargar el daemon.QueuedForReloadsignifica que el cambio se guardó, pero ese destino requiere/admin/reload; el resultado incluye un motivo concreto.Rejectedsignifica que el objetivo rechazó la aplicación en vivo para esa generación; el resultado incluye un motivo concreto.
Una finalización de objetivo para una generación anterior no puede sobrescribir el estado de una más reciente. Las interfaces de estado de configuración informan de los resultados del objetivo en lugar de inferir un único estado aplicado global a partir de prefijos de rutas modificadas.
Mantén la superposición de seguridad aprobada de forma restringida
El límite de aplicación en vivo de seguridad aprobado cubre únicamente allowed_commands y forbidden_paths. Conserva el SecurityPolicy existente y su rastreador de límite de tasa en lugar de reconstruir la política cuando esos campos cambian.
La ejecución recibe una superposición tipada para la generación aplicable. La superposición se propaga explícitamente a las tareas generadas y al trabajo de JoinSet; el estado local de tarea puede ser una conveniencia, pero no es la única autoridad de seguridad. La ausencia de ámbito de ejecución o una discrepancia de generación falla de forma cerrada en lugar de recurrir a una política obsoleta.
La reasignación más amplia del perfil de riesgo y otros cambios en la política de seguridad permanecen en cola para la recarga, a menos que una decisión de arquitectura posterior demuestre que existe un límite seguro para aplicarlos en caliente.
Limitar los cambios de canal a modos de transición comprobados
El límite de aplicación en vivo del canal aprobado solo admite cambios con un límite InPlace o Handover comprobado. Un cambio in situ lo resuelve el adaptador en ejecución en el momento de uso. Un handover construye y comprueba el reemplazo antes de desacoplar la instancia de canal existente.
Los cambios que no pueden probar ninguno de los límites permanecen como QueuedForReload con un motivo concreto. Esta decisión no añade un mecanismo genérico de reversión con parada y arranque porque eso requeriría conservar el estado de configuración previo o aceptar una interrupción que el contrato de transferencia pretende evitar.
Mantén la recarga completa como alternativa de reserva
/admin/reload sigue siendo el mecanismo de respaldo compatible para cualquier cambio de configuración fuera de los límites comprobados de aplicación en caliente. Esta decisión no modifica la autenticación, la autorización ni el comportamiento de la puerta de enlace independiente relacionados con la recarga.
Controles de aceptación
Este ADR permanece propuesto hasta que se cumplan todas estas condiciones:
- la publicación de configuración canónica y el registro de estado aplicado con alcance de generación se distribuyen sin habilitar el nuevo comportamiento de aplicación en vivo;
- cada resultado de destino nombra la generación que procesó, y las completaciones obsoletas no pueden sobrescribir un estado más reciente;
allowed_commandsyforbidden_pathsutilizan una superposición de ejecución tipada y propagada explícitamente que preserva el rastreador de límite de tasa existente y falla de forma cerrada ante la ausencia de ámbito o discrepancia de generación;- los canales probados con rutas de actualización en sitio y de transferencia preservan el servicio existente hasta que el reemplazo esté listo, mientras que los cambios no compatibles informan un motivo de recarga concreto; y
- Las API de configuración y la documentación para operadores informan de los resultados en vivo, en cola y rechazados por cada objetivo con motivos concretos y mantienen
/admin/reloadcomo alternativa.
La publicación canónica y el registro de resultados deben entregarse sin nuevo comportamiento en vivo antes de que se habiliten los consumidores de seguridad y de canales. La aplicación en vivo de seguridad precede a la aplicación en vivo de canales.
Consecuencias
Consecuencias positivas:
- El estado de la configuración puede distinguir lo que se guardó de lo que cada subsistema aplicó realmente.
- Las escrituras concurrentes en proceso no pueden publicar silenciosamente desde revisiones de inicio obsoletas.
- La finalización lenta de un intento de aplicación anterior no puede hacer que una generación más reciente parezca aplicada.
- Los consumidores de seguridad y de canal aprobados tienen límites de seguridad estrechos y verificables.
- Los cambios no compatibles conservan una ruta de recarga completa clara y familiar.
Consecuencias negativas:
- La publicación necesita serialización del escritor y seguimiento de generaciones, además del identificador de configuración destinado al lector.
- Cada objetivo de aplicación en vivo debe tener un manejador de resultados y pruebas con conocimiento de generación.
- El estado de seguridad con ámbito de ejecución debe propagarse explícitamente a través de los límites de las tareas asíncronas.
- Muchas rutas de configuración seguirán requiriendo una recarga; la aplicación en caliente se limita a comportamientos comprobados, no constituye una promesa general.
Referencias
- RFC #7897: Aplicar actualizaciones de política de seguridad y configuración de canal sin recarga completa del daemon
- Ciclo de vida de la configuración
crates/zeroclaw-config/src/schema.rscrates/zeroclaw-gateway/src/api_config.rscrates/zeroclaw-channels/src/orchestrator/mod.rs