Cycle de vie de la configuration
La configuration est à la fois une interface opérateur et un contrat d’exécution. Traitez-la comme un état ayant un propriétaire clair, et non comme des paramètres dispersés copiés dans le sous-système qui en a besoin.
La source canonique est zeroclaw_config::schema::Config, chargée depuis config.toml. Les surfaces de configuration destinées aux utilisateurs, la référence de configuration générée, l’éditeur de configuration de la gateway, les surcharges par variables d’environnement, zeroclaw config set, zeroclaw config patch, Quickstart et les méthodes de configuration RPC passent tous par ce même schéma typé.
Pour l’ordre de construction, les règles de sortie suivies et les vérifications de dérive qui transforment le schéma typé en référence de configuration, consultez Pipeline de documentation générée.
Qui possède quoi
| Surface | Propriétaire | Limite de persistance | Limite d’application à l’exécution |
|---|---|---|---|
| Schéma de configuration | crates/zeroclaw-config/src/schema.rs plus les derives Configurable | Code, pas de documentation générée | Nouveau build binaire |
| Référence générée | cargo mdbook refs / markdown-schema | docs/book/src/reference/config.md au moment de la compilation | Documentation uniquement |
| Emplacement de Bootstrap | ZEROCLAW_CONFIG_DIR, ZEROCLAW_DATA_DIR, déprécié ZEROCLAW_WORKSPACE | Environnement uniquement | Avant l’existence de Config |
| Surcharges de miroir de schéma | ZEROCLAW_<lowercase_path> avec __ pour les points | Uniquement en mémoire | Chaque Config::load_or_init() |
| écritures de configuration CLI | zeroclaw config set, config patch, alias, helpers de modèle | save_dirty() dans config.toml | Prochain chargement/rechargement sauf si la commande actuelle utilise la nouvelle valeur en mémoire |
| Écritures de configuration RPC et TUI | config/* méthodes RPC utilisées par zerocode | save_dirty() dans config.toml | Le contexte RPC se met à jour immédiatement ; les sous-systèmes appartenant au démon nécessitent un rechargement |
| Démarrage rapide appliquer | Chemin d’application partagé pour le web, la CLI et zerocode | save_dirty() dans config.toml | Web et RPC peuvent signaler le rechargement du démon ; le CLI autonome s’applique au prochain chargement/rechargement |
| Écritures de configuration de la passerelle | Gestionnaires de l’API Config et persist_and_swap() | save_dirty() dans config.toml | Les mises à jour d’état visibles par la passerelle s’appliquent immédiatement ; les sous-systèmes du daemon prennent effet après rechargement. |
| Rechargement du daemon | /admin/reload, RPC config/reload, ou le canal de rechargement en processus | Relit config.toml | Recrée les sous-systèmes du démon dans le même PID |
Ne modifiez pas manuellement la référence de configuration générée. Si un champ, une enum, une section des alias, un marqueur de secret ou une description est incorrect, corrigez le schéma ou le générateur et régénérez la référence.
Ordre de chargement
Le chargement de la configuration se déroule en plusieurs phases distinctes :
- Résoudre la racine d’installation à partir des variables d’environnement de bootstrap. Cela se produit avant qu’aucune
Confign’existe, donc les noms bootstrap conservent leur forme majuscule et n’utilisent pas la grammaire schema-mirror. - Lire
config.toml, exécuter la migration de schéma en mémoire, déchiffrer les secrets configurés et enregistrer toute section critique pour la sécurité malformée comme sécurité dégradée. - Appliquez les overrides du schéma miroir à la configuration en mémoire. Dans les variables d’environnement,
__est mappé sur., doncZEROCLAW_providers__models__openai__api_keycibleproviders.models.openai.api_key. - Valider et avertir sans verrouiller l’opérateur hors de l’éditeur de passerelle.
Lors d’une installation fraîche, les valeurs par défaut sont enregistrées avant l’application des surcharges d’env. Cela maintient les secrets injectés par l’env et les valeurs CI locales hors du nouveau fichier.
Les surcharges d’environnement ne sont pas sauvegardées
Les variables d’environnement Schema-mirror sont des injections à l’exécution. Elles aboutissent sur le Config en mémoire au chargement et sont suivies dans env_overridden_paths afin que le CLI, le tableau de bord et le quickstart puissent afficher le marqueur de surcharge.
La sauvegarde doit masquer ces chemins pour les ramener à leur valeur disque pré-override ou par défaut avant le chiffrement. Cela importe surtout pour les secrets : si un opérateur a une clé API chiffrée sur le disque et démarre temporairement avec un override d’env pour le même chemin, une sauvegarde de configuration non liée ne doit pas remplacer le véritable identifiant par la valeur d’env ou par une chaîne d’affichage masquée.
Examinez les modifications de configuration en gardant cet invariant à l’esprit :
- Les valeurs de schéma miroir
ZEROCLAW_*affectent le processus en cours d’exécution après le chargement. - Ils ne deviennent pas une config durable.
- Les chemins de sauvegarde doivent préserver les secrets chiffrés et les références de secrets externes sauf si le même chemin a été modifié intentionnellement.
Les entrées d’identifiants restent typées
Les valeurs d’exécution de type identifiant restent des valeurs de configuration. Les clés API, les jetons OAuth, les URL de point de terminaison et autres identifiants de fournisseur/canal doivent transiter par le schéma de configuration typé, la gestion des secrets de configuration ou les surcharges ZEROCLAW_* en miroir du schéma avant qu’un constructeur d’exécution ne les voie.
N’ajoutez pas de lectures ad hoc de std::env::var("PROVIDER_API_KEY") dans les constructeurs de fournisseurs, de canaux, d’outils, de transcription, de TTS, de mémoire ou de passerelle. Cela crée une seconde source d’identifiants en dehors de Config, contourne la prise en compte des remplacements par les variables d’environnement et peut rendre incohérents les comportements de la CLI, de la passerelle, de RPC/TUI, du démarrage rapide et du rechargement.
Si ZeroClaw prend en charge intentionnellement un pont d’environnement natif pour une famille d’intégrations, documentez ce pont à la frontière de l’intégration et mappez-le dans la même valeur de configuration typée avant la construction. Sinon, les noms de shell par défaut de l’écosystème tels que ANTHROPIC_API_KEY, OPENROUTER_API_KEY ou QDRANT_URL doivent être pontés par les opérateurs vers la variable de miroir de schéma ZEROCLAW_* correspondante ; voir Variables d’environnement.
Chemins modifiés et écritures incrémentales
La plupart des surfaces d’édition utilisent Config::mark_dirty() et save_dirty(), et non une réécriture complète. save_dirty() n’écrit que les chemins en notation pointée modifiés, préserve les entrées non modifiées et les commentaires dans la mesure du possible, marque la schema_version actuelle, et effectue l’écriture via un remplacement atomique de fichier temporaire.
Ce chemin est également responsable des sections de clés de map. La création d’un alias tel qu’un fournisseur de modèle, un serveur MCP, un bundle de compétences ou un bundle de connaissances doit salir la bonne section afin que l’alias survive à une sauvegarde et un rechargement. Une modification de configuration qui ne met à jour que l’état du tableau de bord en mémoire n’est pas complète.
Lors de la revue d’une écriture de configuration, vérifiez que :
- le chemin édité est marqué dirty avant la persistance ;
- les créations, renommages et suppressions de map-key salissent la section parente ou la clé naturelle ;
- les chemins secrets et surchargés par l’environnement conservent leur comportement de masquage à la sauvegarde ;
schema_versionreste à jour après des écritures incrémentielles ;- la valeur modifiée survit à
save_dirty()suivi d’un rechargement.
Enregistré vs appliqué
Un enregistrement réussi signifie que le fichier a été modifié. Cela ne signifie pas toujours que chaque composant d’exécution a pris en compte la modification.
Le démon possède le graphe de sous-systèmes de longue durée : passerelle, écouteurs de canaux, planificateur, écouteur MQTT, câblage de session, backend mémoire, fabriques de fournisseurs et câblage des coûts. POST /admin/reload signale la boucle du démon, qui relit config.toml et réinstancie ces sous-systèmes dans le même processus. Le PID reste le même, mais les écouteurs se rattachent brièvement.
Les écritures dans la configuration de la passerelle appellent persist_and_swap() : écriture sur disque, puis remplacement de la configuration en mémoire visible par la passerelle et définition de pending_reload. Cela permet à l’éditeur de configuration de refléter l’écriture immédiatement, tandis que la bannière de rechargement indique à l’opérateur que les canaux, les fournisseurs, le planificateur ou d’autres composants gérés par le daemon peuvent encore s’exécuter à partir de l’instance précédente du sous-système.
Le mode autonome zeroclaw gateway start n’a pas de superviseur de démon. Son endpoint de rechargement renvoie une réponse indiquant qu’un redémarrage est requis car il n’y a pas de boucle de démon externe à signaler.
Recharger l’accès
Le rechargement local est autorisé depuis loopback. Le rechargement distant nécessite les deux :
gateway.allow_remote_admin = true- appairage activé et un jeton Bearer appairé valide
L’activation de l’administration à distance lorsque l’appairage est désactivé est rejetée plutôt que traitée comme un accès anonyme de rechargement à distance.
Les sections de configuration malformées critiques pour la sécurité ne sont autorisées à se dégrader que lorsque l’opérateur opte explicitement pour un service dégradé. Sinon, le processus refuse de servir car la posture de sécurité de réinitialisation aux valeurs par défaut peut être plus faible que celle prévue par le fichier.
Restauration et réparation
Les écritures de configuration utilisent un remplacement atomique par fichier temporaire et des permissions uniquement pour le propriétaire. Lors du remplacement d’un fichier existant, l’écriture crée un config.toml.bak dans le même répertoire pendant l’opération et le supprime après une écriture réussie. Les écritures de Gateway effectuent également une copie du fichier avant écriture et tentent de le restaurer en cas d’échec de la persistance avant de remplacer l’état en mémoire.
Il n’existe pas de rollback transactionnel général pour une modification de configuration valide mais indésirable après qu’elle a été enregistrée et appliquée. Restaurez le précédent config.toml à partir de la sauvegarde, rétablissez le champ via la CLI ou le tableau de bord, puis rechargez ou redémarrez selon la frontière de runtime ci-dessus.
Config-visible n’est pas toujours pris en charge à l’exécution
Un champ peut être visible dans le schéma avant que chaque chemin d’exécution ne le consomme. Cela n’est acceptable que si la documentation et les notes de revue l’indiquent clairement.
Par exemple, knowledge_bundles est visible dans le schéma et apparaît dans les sections de configuration des API. Une PR qui ajoute ou modifie une telle surface doit préciser si elle stocke uniquement la configuration, branche le comportement d’exécution ou couvre les deux.
Lors de la revue d’une PR qui touche un champ visible dans le schéma mais pas encore consommé au runtime, exiger que la description de la PR indique si le câblage runtime est différé, hors périmètre ou réalisé par le même changement.
Liste de contrôle du relecteur
Pour les modifications de config-schema, env-var, default ou reload, demandez :
- Quelle est la source de vérité pour la nouvelle valeur ?
- Cela crée-t-il un état dupliqué, ou résout-il directement depuis
Configà l’utilisation ? - La référence générée provient-elle du code plutôt que d’un texte rédigé manuellement ?
- Les remplacements de variables d’environnement sont-ils uniquement appliqués lors du chargement et masqués lors des sauvegardes ?
- Les interfaces CLI, gateway, RPC/TUI et quickstart utilisent-elles le même chemin ponctué ?
- Les identifiants sont-ils résolus via une configuration typée ou des passerelles documentées vers un miroir de schéma, plutôt que par des lectures ad hoc des variables d’environnement natives du fournisseur ?
- Une sauvegarde persiste-t-elle après un rechargement du processus, et pas seulement au rendu immédiat en mémoire ?
- Le PR indique-t-il si les utilisateurs doivent recharger, redémarrer, effectuer une migration ou un retour arrière manuel ?
- Si le champ est uniquement visible en configuration, la PR évite-t-elle de prétendre à une prise en charge à l’exécution ?
Pointeurs source
- Schéma et persistance de la configuration :
crates/zeroclaw-config/src/schema.rs - Syntaxe de remplacement d’environnement :
crates/zeroclaw-config/src/env_overrides.rs - Commandes CLI de configuration :
src/main.rs - Méthodes de configuration RPC et TUI :
crates/zeroclaw-runtime/src/rpc/dispatch.rs - Chemin d’application Quickstart partagé :
crates/zeroclaw-runtime/src/quickstart/mod.rs - Signalisation de rechargement Web Quickstart :
crates/zeroclaw-gateway/src/api_quickstart.rs - API de configuration de la passerelle et bandeau de rechargement :
crates/zeroclaw-gateway/src/api_config.rs - Endpoint de rechargement et porte d’accès :
crates/zeroclaw-gateway/src/lib.rs - Utilitaire d’authentification Bearer Gateway : `crates/zeroclaw-gateway/src/api.rs`
- Pipeline de référence généré :
xtask/src/cmd/mdbook/refs.rs