Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help


id : ADR-012 titre : L’application de la configuration à chaud utilise une publication et des résultats à portée de génération date : 2026-07-19 statut : proposé en lien avec :

  • 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: L’application de la configuration en direct utilise une publication et des résultats à portée de génération

Contexte

ZeroClaw peut enregistrer la configuration via les interfaces CLI, RPC, TUI, Quickstart et gateway. Un enregistrement réussi ne signifie pas que chaque sous-système de longue durée a adopté la nouvelle valeur. L’état visible par la gateway peut changer immédiatement, tandis que les canaux, sessions, fournisseurs et autres composants gérés par le démon continuent d’utiliser leur état d’exécution précédent jusqu’à ce que /admin/reload reconstruise le graphe des sous-systèmes.

La RFC acceptée #7897 vise une amélioration limitée : certaines modifications de stratégie de sécurité et de canal peuvent s’appliquer sans rechargement complet du démon, tandis que les opérateurs reçoivent un résultat spécifique à la cible pour la génération que chaque sous-système a réellement traitée. L’architecture acceptée exige une seule configuration publiée canonique, des résultats propres à chaque génération, des surcouches de sécurité restreintes et uniquement des modes de transition de canal éprouvés.

Cet enregistrement définit cette cible et ses portes d’implémentation. Il n’affirme pas que l’application en production existe déjà. Jusqu’à ce que ces portes soient livrées, le comportement actuel de sauvegarde/application et le mécanisme de repli /admin/reload décrits dans Config lifecycle font autorité.

Décision

Publier une seule génération de configuration canonique

Le processus dispose d’une révision de configuration publiée canonique. Les writers in-process sont sérialisés séparément des readers. Un writer clone la révision courante, applique et valide ses modifications, persiste la configuration résultante au sein de la transaction d’écriture sérialisée, puis seulement publie de manière atomique la génération suivante. La coordination entre processus indépendants qui éditent config.toml sort du cadre de cette décision.

Le verrou de configuration côté lecteur n’est pas maintenu pendant les opérations d’E/S disque asynchrones. La publication ne crée pas de second cache de configuration à longue durée de vie et ne conserve pas d’instantané de configuration précédent à des fins de restauration générale.

Les événements Apply identifient la génération publiée et les chemins modifiés. Ils ne transportent pas une copie complète de la configuration ni une valeur de configuration précédente. Chaque cible lit la révision canonique courante et l’applique uniquement lorsque sa génération correspond à l’événement. Un événement supplanté est ignoré et ne peut pas écraser le résultat d’une génération plus récente.

Enregistrer les résultats de la génération réellement appliquée

Chaque cible d’application enregistre son propre résultat spécifique à sa génération :

  • AppliedLive signifie que la cible a adopté la génération identifiée sans rechargement du démon.
  • QueuedForReload signifie que la modification a été enregistrée mais que cette cible nécessite /admin/reload ; le résultat inclut une raison concrète.
  • Rejected signifie que la cible a refusé l’application en direct pour cette génération ; le résultat inclut une raison concrète.

Une complétion cible pour une génération plus ancienne ne peut pas écraser le statut d’une génération plus récente. Les rapports de statut de configuration exposent les résultats cibles plutôt que d’inférer un état appliqué global à partir des préfixes de chemin modifiés.

Maintenez la surcouche de sécurité approuvée restreinte

La limite de sécurité approuvée pour l’application à chaud couvre uniquement allowed_commands et forbidden_paths. Elle préserve la SecurityPolicy existante ainsi que son suivi de limitation de débit au lieu de reconstruire la stratégie lorsque ces champs changent.

L’exécution reçoit un overlay typé pour la génération applicable. L’overlay est propagé explicitement aux tâches créées et au travail JoinSet ; l’état local à la tâche peut être une commodité, mais il n’est pas la seule autorité de sécurité. Une portée d’exécution manquante ou une incompatibilité de génération échoue en mode fermé plutôt que de revenir à une stratégie obsolète.

La réaffectation plus large des profils de risque et les autres modifications de la politique de sécurité restent en file d’attente pour rechargement, à moins qu’une décision d’architecture ultérieure ne démontre une limite de mise à jour à chaud sûre.

Limiter les changements de canal aux modes de transition éprouvés

La limite d’application à chaud du canal approuvé prend uniquement en charge les modifications avec une limite InPlace ou Handover prouvée. Une modification sur place est résolue par l’adaptateur en cours d’exécution au moment de l’utilisation. Un transfert construit et prouve le remplacement avant de détacher l’instance de canal existante.

Les modifications qui ne peuvent confirmer ni l’une ni l’autre des limites restent QueuedForReload avec une raison concrète. Cette décision n’ajoute pas de mécanisme générique de restauration par arrêt et redémarrage, car cela nécessiterait de conserver l’état de configuration précédent ou d’accepter une interruption que le contrat de transfert est justement censé éviter.

Préserver le rechargement complet comme solution de repli

/admin/reload reste la solution de repli prise en charge pour toute modification de configuration en dehors des limites d’application à chaud établies. Cette décision ne modifie pas l’authentification de rechargement, l’autorisation, ni le comportement de la passerelle autonome.

Critères d’acceptation

Cet ADR reste proposé jusqu’à ce que toutes ces conditions soient remplies :

  • la publication de configuration canonique et le registre d’état appliqué à portée de génération sont livrés sans activer de nouveau comportement d’application en direct ;
  • chaque résultat cible nomme la génération qu’il a traitée, et les complétions obsolètes ne peuvent pas écraser un statut plus récent ;
  • allowed_commands et forbidden_paths utilisent une couche d’exécution typée et propagée explicitement qui préserve le tracker de limite de débit existant et échoue en mode sécurisé en cas de portée manquante ou de discordance de génération ;
  • Les chemins de mise à jour en place et de transfert d’un canal éprouvé préservent le service existant jusqu’à ce que le remplacement soit prêt, tandis que les modifications non prises en charge signalent une raison de rechargement concrète ; et
  • Les API de configuration et la documentation destinée aux opérateurs rapportent, pour chaque cible, les résultats en direct, mis en file d’attente et rejetés avec des raisons concrètes, et conservent /admin/reload comme solution de repli.

La publication canonique et le registre des résultats doivent être livrés sans nouveau comportement en direct avant que les consommateurs de sécurité et de canal ne soient activés. L’application en direct de la sécurité précède l’application en direct du canal.

Conséquences

Conséquences positives :

  • Le statut de configuration peut distinguer ce qui a été sauvegardé de ce que chaque sous-système a réellement appliqué.
  • Les écritures concurrentes intra-processus ne peuvent pas publier silencieusement à partir de révisions initiales obsolètes.
  • Une fin d’exécution lente issue d’une tentative d’application plus ancienne ne peut pas faire apparaître une génération plus récente comme appliquée.
  • Les consommateurs de sécurité et de canal approuvés ont des limites de sécurité étroites et testables.
  • Les modifications non prises en charge conservent un chemin de rechargement complet clair et familier.

Conséquences négatives :

  • La publication nécessite la sérialisation de l’écrivain et le suivi de génération en plus du handle de configuration destiné au lecteur.
  • Chaque cible live-apply doit disposer de son propre gestionnaire de résultats et de tests tenant compte de la génération.
  • L’état de sécurité limité à l’exécution doit être propagé explicitement à travers les limites des tâches asynchrones.
  • De nombreux chemins de configuration continueront de nécessiter un rechargement ; l’application à chaud repose sur une liste d’autorisation de comportements éprouvés plutôt que sur une promesse générale.

Références