Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

État d’exécution et persistance

ZeroClaw a une seule racine d’installation, mais pas une unique « base de données d’espace de travail » monolithique. Différentes surfaces d’état ont des propriétaires différents, un comportement de rechargement différent et une durabilité différente. Utilisez cette carte lorsqu’un changement ajoute de l’état, déplace de l’état, met en cache la configuration, touche au rechargement ou modifie le comportement de session/mémoire/journal/coût.

La règle de la source unique de vérité s’applique toujours : si un fait réside déjà dans une surface, ne le copiez pas dans un autre champ stocké. Stockez un nouvel état uniquement lorsque ce tableau identifie la surface propriétaire, ou résolvez-le depuis le propriétaire canonique au moment de l’utilisation.

Installer la mise en page

Pour une installation standard, <install> correspond au répertoire de configuration résolu (~/.zeroclaw/ par défaut, les installations via Homebrew ou avec l’option explicite --config-dir peuvent le déplacer). La structure actuelle est :

<install>/
├── config.toml                 # canonical user config
├── .secret_key                 # key for encrypted secrets
├── data/                       # instance-wide runtime data
│   ├── sessions/
│   │   ├── sessions.db         # default chat/session backend
│   │   └── acp-sessions.db     # ACP protocol sessions
│   ├── cron/jobs.db            # scheduled job state
│   ├── sop/runs.db             # optional durable SOP run state
│   ├── control_plane.db        # task supervision records
│   ├── state/
│   │   ├── runtime-trace.jsonl # persisted logs
│   │   └── costs.jsonl         # cost ledger
│   ├── devices.db              # paired-device metadata
│   └── memory/                 # shared instance memory stores
├── shared/                     # shared resources, such as skill bundles
└── agents/<alias>/workspace/   # per-agent filesystem sandbox and identity

Le nom hérité <install>/workspace/ est toujours accepté pendant la migration, mais le nouvel état d’exécution doit être décrit en termes de <install>/data/, <install>/shared/ et d’espaces de travail par agent.

Carte d’état

SurfaceSource canoniqueChemin durablePropriétaire en mémoireRechargement / frontière de concurrenceNotes
Valeurs de configurationzeroclaw-config::Config chargé depuis config.toml<install>/config.tomldémon Arc<RwLock<Config>> plus vues résolues par sous-système/admin/reload relit la configuration et réinstancie les sous-systèmes du démon ; les écritures directes de configuration utilisent la validation du schéma et des contrôles des chemins modifiés. Les mutations de configuration côté RPC sérialisent en outre l’intégralité de leur section de lecture-modification-vidage sur RpcContext::config_write_lock (mutex tokio en premier, parking_lot RwLock en second, et aucun garde parking_lot n’est conservé pendant un .await ou lock().await) ; les mutations de configuration HTTP de la passerelle sérialisent de même l’intégralité de leur section de lecture-modification-échange sur AppState::config_write_lock (même ordre des verrous)Ne pas mettre en cache les données dérivées de la configuration dans des structs à longue durée de vie, sauf si le cache est explicitement reconstruit lors du rechargement.
Durabilité de l’enregistrement de la configurationChemin d’écriture atomique de save() / save_dirty() dans zeroclaw-config<install>/config.toml ainsi que le fichier config.toml.bak conservécomme pour les valeurs de configurationLes écritures passent par un fichier temporaire, une synchronisation du répertoire avant remplacement, un renommage atomique, puis une synchronisation du répertoire après remplacementOk(()) signifie que le remplacement est visible, et non que la durabilité du renommage est garantie : un échec avant le remplacement interrompt l’opération en laissant le fichier sur disque et la configuration active inchangés, mais un échec de synchronisation du répertoire après le renommage renvoie tout de même Ok(()), avec un avertissement journalisé et config.toml.bak conservé. Après un crash survenant immédiatement après une telle sauvegarde, l’entrée de répertoire peut revenir au fichier précédent ; les appelants ne doivent pas considérer Ok comme une garantie de durabilité plus forte, et la récupération peut consulter le .bak conservé.
Secrets chiffrésChamps secrets de configuration, plus .secret_key<install>/config.toml, <install>/.secret_keyhelpers du magasin de secrets dans zeroclaw-configLe rechargement observe la configuration modifiée ; la perte de .secret_key rend les secrets de configuration chiffrés irrécupérablesNe jamais copier les valeurs déchiffrées dans les logs, docs, corps de PR ou métadonnées d’exécution.
Identité du système de fichiers de l’agentFichiers d’espace de travail par agent<install>/agents/<alias>/workspace/construction de SecurityPolicy effective et de prompt d’agentCréé de manière différée au démarrage de l’agent ; les accès à l’espace de travail sont évalués à partir de la configuration.Ceci est le bac à sable du système de fichiers, pas la source de vérité de configuration pour providers/channels/tools.
Bundles de compétences partagésEntrées du bundle de compétences configurées et répertoires de bundle résolus<install>/shared/skills/<bundle>/ par défautchargement de compétences / enrichissement de promptLe rechargement et les démarrages de nouveaux agents observent les changements de configuration et du système de fichiersLes alias de bundle et la résolution des répertoires proviennent de la configuration ; les fichiers correspondent au contenu du bundle.
Mémoire de conversationzeroclaw-memory backend sélectionné par agentEmplacements des backends SQLite/Postgres/Lucid/Qdrant/Markdown ; le stockage partagé SQLite se trouve sous data/memory/Arc<dyn Memory> encapsulé dans des adaptateurs de portée d’agentLe choix du backend est verrouillé une fois qu’un agent a écrit des données ; le rappel inter-agents sur le même backend est opt-in.Les lignes de mémoire sont réservées à l’agent. Ne remplacez pas la propriété de la mémoire par des caches de prompts/sessions copiés.
Sessions de chat et de canal[channels].session_backend plus SessionBackendPar défaut data/sessions/sessions.db; le JSONL hérité/explicite utilise data/sessions/*.jsonlLes handles du backend zeroclaw-infra sont actuellement construits indépendamment par les canaux, la passerelle, le RPC et les outils de sessionLe backend SQLite utilise WAL ; SessionActorQueue sérialise les tours actifs par session ; les mutations JSONL partagent un verrou du répertoire des sessions propre au processusLes sessions Chat/Code utilisent le contrat de backend unifié. Les sessions du protocole ACP utilisent un stockage distinct. La gestion, au niveau du processus, de la propriété du backend n’est pas encore centralisée dans une source unique.
Sessions ACPStockage de session du protocole ACPdata/sessions/acp-sessions.dbAcpSessionStore ouvert au démarrage du daemon et dans le contexte RPCStockage SQLite basé sur WAL, séparé des sessions de chatACP session/load et session/resume opèrent sur ce magasin de protocole, et non le backend de la session de chat.
Sessions RPC/TUI en directRPC SessionStoreaucun par lui-mêmecrates/zeroclaw-runtime/src/rpc/session.rs map en mémoireLocal au processus ; l’historique de session ne persiste que via le chat ou le backend ACPLes identifiants de session en direct, les uploads, les jetons d’annulation, les propriétaires et les surcharges constituent l’état d’exécution.
tâches CronConfiguration déclarative de l’appartenance et stockage cron SQLitedata/cron/jobs.dbzeroclaw-runtime::cron planificateur/stockageLes chemins de lecture ne créent pas jobs.db ; le planificateur possède l’état due/lockLes tâches déclaratives sont réconciliées à partir de la configuration, tandis que les métadonnées d’exécution et les verrous résident dans la base de données cron.
Exécutions SOPSopEngine plus SopRunStoreAucun par défaut ; data/sop/runs.db lorsque l’initialisation SQLite durable réussitCaches des exécutions actives/terminées du moteur SOPLe magasin durable détient les demandes d’admission et les révisions persistées ; le moteur restaure l’état actif et terminal au démarrageL’échec d’initialisation du store enregistre un avertissement et bascule en mémoire. Les enregistrements d’audit en mémoire ne constituent pas la source de vérité du cycle de vie d’exécution.
Supervision des tâches en arrière-planPlan de contrôle des tâches durablesdata/control_plane.dbhandle du plan de contrôle, producteurs de tâches et faucheurL’ID du PID/de démarrage du propriétaire identifie les processus orphelins du démarrage précédent ; le délai d’expiration du signal de vie s’applique uniquement aux producteurs qui émettent des signaux de vieLes producteurs actuels de délégués/sous-agents enregistrent des lignes en mode best-effort, mais ne renseignent pas les champs heartbeat, parent, route et principal. Les API d’objectifs existent, mais l’exécution de bout en bout des objectifs n’est pas encore câblée.
Résultats du délégué en arrière-planEnregistrement de résultat délégué<workspace>/delegate_results/<task-id>.jsonregistre d’annulation des outils délégués et future en cours d’exécutionLes fichiers de résultats survivent au redémarrage ; les handles d’annulation en direct ne survivent pasLes lectures privilégient le fichier et n’appliquent la supervision lost ou timed_out que si le fichier indique toujours running ; les écritures de résultats et du plan de contrôle sont indépendantes et peuvent diverger.
Journaux d’exécutionzeroclaw-log schéma d’événements et couche d’abonnésdata/state/runtime-trace.jsonl lorsque la persistance est activéehook de diffusion, writer JSONL, lecteur /api/logs, pont ObserverLa persistance rolling/full/none est contrôlée par la configuration ; le SSE du dashboard reçoit les événements même lorsque JSONL est désactivéLes logs constituent des preuves et de l’observabilité, et non la source de la configuration utilisateur ou de l’état de session.
Registre des coûtsCostTracker plus configuration des tarifsdata/state/costs.jsonlCostTracker global au processusLe rechargement remplace à chaud CostConfig ; le tracker est construit à la demande si le suivi des coûts devient activéLes enregistrements existants conservent leur prix enregistré ; les modifications de taux affectent les futures requêtes après le rechargement.
Jetons d’appairage de passerellePairingGuard de gateway.paired_tokenshachages de jetons dans la configgarde d’appairageRecharger reconstruit le garde à partir de la configLes jetons bearer valides sont un état de configuration, pas des lignes de devices.db.
Métadonnées de l’appareil appairéLignes du registre des appareils indexées par le hachage du jetondata/devices.dbDeviceRegistry cache plus SQLiteRegistry réconcilie les métadonnées par rapport à l’ensemble canonique de tokens appariésCette DB rend les appareils appairés visibles/gérables ; elle n’invente pas de tokens valides.
État et statut des composantsles sous-systèmes en cours d’exécution rapportent l’état des composantsaucunétat de santé/statut de la passerelleLocal au processus ; réinitialisé/reconstruit au redémarrage ou au rechargement du démon/health, /api/health et /api/status sont des observations actuelles, pas une configuration durable.
Files d’attente, anti-rebonds, chiens de gardezeroclaw-infra utilitaires de processusaucun sauf si un appelant stocke les résultats ailleursfiles d’attente/debouncers/watchdogs en mémoireLocal au processus ; utilisé pour sérialiser, fusionner ou détecter les blocagesTraitez-les comme un état de coordination. Persistez uniquement les données de domaine qu’ils protègent, pas la file d’attente elle-même.

Recharger et redémarrer

POST /admin/reload envoie un signal de rechargement in-process au daemon. La boucle externe du daemon relit la config depuis le disque et relance le daemon, créant un nouveau câblage pour gateway, channel, heartbeat, scheduler, MQTT, session, memory et cost à partir de la nouvelle config. Le PID reste le même, mais les listeners se rebindent brièvement.

Un redémarrage complet du processus réinitialise également l’état local au processus, notamment les sessions RPC actives, les instantanés de santé, les files d’attente d’acteurs et toute clé d’accusé de réception d’outil éphémère. Les stores durables persistent lors du redémarrage, comme indiqué dans le tableau ci-dessus.

Migration du backend de session

La sélection du backend de session SQLite importe les fichiers hérités data/sessions/*.jsonl lors de la construction d’un handle de backend. L’importateur déplace chaque source vers une génération privée .jsonl.importing tout en maintenant le verrou de mutation JSONL local au processus, écrit les messages, les métadonnées et un reçu d’importation associé à la source dans une transaction SQLite, puis conserve la source sous .jsonl.migrated pour permettre un retour arrière.

Le reçu lie le nom de fichier source, la clé de session, le condensat SHA-256 et la longueur en octets. Avant le début de la transaction du reçu, l’importateur synchronise le fichier source intermédiaire et, sous Unix, le renommage du répertoire live vers le répertoire intermédiaire. Les transactions de migration utilisent une synchronisation SQLite complète pour la validation de l’import, puis restaurent le paramètre d’exécution normal. Le transfert vers l’archive synchronise de même les métadonnées du répertoire sous Unix avant de supprimer la source intermédiaire. La construction du backend restaure l’état inactif local au processus à partir des reçus persistants avant de parcourir les fichiers source. Dès qu’un reçu d’import est validé, les mutations JSONL de ce répertoire de session restent inactives, même si le transfert vers l’archive ou un fichier ultérieur échoue. La construction suivante peut vérifier la source intermédiaire par rapport à ce reçu et terminer le transfert sans insérer de messages en double. Les fichiers JSONL vides ou composés uniquement d’espaces blancs sont conservés en tant que sessions SQLite contenant zéro message ; une source non vide ne contenant aucun message valide échoue néanmoins de manière sécurisée.

Construire le backend SQLite sans importer de source ne désactive pas les mutations JSONL. Un rechargement au sein du processus peut donc repasser à JSONL lorsqu’aucun reçu d’importation persistant n’existe.

Une source dépourvue de reçu n’est pas fusionnée par-dessus les messages SQLite ou les métadonnées existants pour la même clé de session. Si cette vérification préalable à la validation échoue, la source préparée est restaurée sur son chemin JSONL actif. Un reçu incompatible, une source préparée incompatible ou une archive incompatible entraîne une erreur lors de la construction du backend. Chaque point d’entrée de processus décide actuellement indépendamment si cette erreur arrête le sous-système ou désactive la persistance ; la gestion au niveau du processus et la stratégie de démarrage sont distinctes du contrat de migration.

Sauvegarde et restauration

Pour une installation normale sur une seule instance, sauvegardez l’intégralité du répertoire <install>. À minima, incluez :

  • config.toml
  • .secret_key si des secrets chiffrés sont utilisés
  • data/memory/
  • data/sessions/
  • data/cron/jobs.db si les tâches cron sont configurées via les surfaces d’exécution
  • data/sop/runs.db si les exécutions SOP durables sont activées
  • data/control_plane.db si l’historique des tâches supervisées est important
  • data/state/costs.jsonl si l’historique des coûts est important
  • data/state/runtime-trace.jsonl si des journaux sont nécessaires pour l’examen d’incident
  • data/devices.db pour les métadonnées des appareils appairés

Ne lancez pas deux démons sur la même racine d’installation. Plusieurs magasins utilisent SQLite avec un modèle à écriture unique, et les caches par processus supposent qu’un seul démon possède l’instance.

Pointeurs source

  • Résolution de Config, install-root et data-dir : crates/zeroclaw-config/src/schema.rs
  • Backends de session : crates/zeroclaw-infra/src/session_sqlite.rs, crates/zeroclaw-infra/src/session_store.rs
  • Stockage de sessions ACP : crates/zeroclaw-infra/src/acp_session_store.rs
  • Sessions live RPC : crates/zeroclaw-runtime/src/rpc/session.rs
  • Persistance Cron : crates/zeroclaw-runtime/src/cron/store.rs
  • Persistance de SOP : crates/zeroclaw-runtime/src/sop/store/
  • Supervision des tâches en arrière-plan et des objectifs : crates/zeroclaw-runtime/src/control_plane/
  • Résultats de délégation en arrière-plan : crates/zeroclaw-runtime/src/tools/delegate.rs
  • Journaux : crates/zeroclaw-log/
  • Registre des coûts : crates/zeroclaw-config/src/cost/tracker.rs
  • Garde d’appairage : crates/zeroclaw-config/src/pairing.rs
  • Registre des périphériques : crates/zeroclaw-gateway/src/api_pairing.rs
  • Endpoint de rechargement : crates/zeroclaw-gateway/src/lib.rs