FND-001 : Architecture intentionnelle : transition vers le micronoyau ZeroClaw
À partir de v0.7.0 · Type : Architecture · Rév. 10
Référence canonique · Ratifiée par l’équipe · Rév. 10 Discussion et historique des brouillons du RFC original : #5574
Une note à l’équipe avant que vous lisiez ceci.
Ce document a été rédigé pour nous aider à passer d’une base de code qui a grandi de manière réactive à une base de code construite avec intention. Si certains des concepts présentés ici sont nouveaux pour vous, ce n’est pas un problème. Cela signifie que ce document remplit sa mission. Chaque ingénieur senior avec qui vous travaillerez a appris ces leçons à ses dépens, sur une base de code devenue trop grande pour être comprise. Nous avons la rare opportunité de reconnaître ce schéma tôt et de corriger le cap avant que cela ne devienne douloureux. C’est une bonne chose. Prenez votre temps pour le lire.
Table des matières
- Une philosophie de développement : la vision d’abord
- La Vision : Ce qu’est ZeroClaw
- Évaluation honnête : où nous en sommes aujourd’hui
- Architecture cible
- Standards que nous devrions adopter
- Feuille de route par phases : v0.7.0 → v1.0.0
- Métriques de code et de complexité
- Ce que cela signifie pour les contributeurs
Historique des révisions
| Rév | Date | Résumé |
|---|---|---|
| 1 | 2026-04-09 | Brouillon initial |
| 2 | 2026-04-09 | Ajout de la section 4.4.1 Politique de versionnement (héritage unifié de l’espace de travail, niveaux de stabilité, définition des changements incompatibles au niveau du produit) ; ajout de la section 4.4.2 Artéfacts de publication (destin des indicateurs de fonctionnalité, profil binaire de publication canonique, matrice des artéfacts de publication) ; ajout de questions de discussion sur la stratégie de versionnement et les valeurs par défaut d’observabilité |
| 3 | 2026-04-10 | Correction de terminologie suite aux retours d’implémentation du PR #5559 : « kernel » → « runtime » pour la couche d’orchestration de l’agent dans tout le document ; « kernel » désigne désormais spécifiquement le fondement irréductible (build --no-default-features) ; §4.1 mis à jour pour décrire l’architecture explicite à deux couches (fondation + runtime) ; diagramme de dépendances et carte des composants des §4.2–§4.3 mis à jour pour afficher zeroclaw-runtime ; Phase 2 renommée de « The Kernel » à « The Runtime » ; les objectifs de taille binaire sont reformulés comme des étoiles du nord aspirationnelles avec un suivi mesuré des progrès plutôt que comme des seuils stricts ; §7 mis à jour avec la mesure réelle de la Phase 1 (build de fondation de 6,6 Mo) et une note explicite indiquant que la décomposition architecturale permet l’optimisation, mais que celle-ci constitue une deuxième passe dédiée. |
| 4 | 2026-06-02 | Mise à jour du §5.2 pour cibler wasm32-wasip2 afin de prendre en charge les fichiers WIT. Mise à jour de la Phase 2 §D2 pour remplacer Extism par wasmtime afin de prendre en charge les cibles ARM32 et les fichiers WIT |
| 5 | 2026-06-29 | Modifié la §4.4.2 pour remplacer la ligne unique plugins-wasm toujours activée par la taxonomie des backends d’exécution à trois indicateurs (plugins-wasm hôte, plus les backends plugins-wasm-cranelift / plugins-wasm-pulley), finalisant la résolution des conflits de la RFC #6943. |
| 6 | 2026-06-30 | Suppression de l’installeur de bureau de la matrice des artefacts de publication, de l’architecture cible, de la feuille de route et des critères de réussite (#8544) |
| 7 | 2026-07-04 | Restauration de l’installateur de bureau et de ses engagements en matière de publication, d’architecture, de feuille de route et de critères de réussite (#8565) |
| 8 | 2026-07-20 | A fait du fichier racine AGENTS.md le contrat compact du projet, a redirigé les détails maintenus vers la cartographie de l’architecture et les directives destinées aux agents de codage, et a empêché la politique de la crate d’affaiblir les exigences du projet en matière de sécurité, de confidentialité ou d’autorisation (#9050). |
| 9 | 2026-08-11 | WATI a été retiré de l’inventaire actuel des passerelles et de la cible de migration des plugins v0.9.0 après le retrait du canal dans #9571 ; la frontière générique webhook/plugin reste inchangée |
| 10 | 2026-08-19 | Suppression de aardvark-sys et zeroclaw-robot-kit des recommandations relatives à l’héritage de l’espace de travail et aux publications indépendantes, après le retrait des deux crates dans #9853 ; les versions 0.1.0 publiées restent sur crates.io et ne sont pas concernées |
Les numéros de révision de ce document de référence suivent l’historique validé du dépôt. L’issue RFC liée qualifie également une modification relative à la discipline de configuration de brouillon de la rév. 4, mais ce texte n’a pas été inclus lors de la ratification de ce document fondateur dans #5911. La source actuelle faisant autorité pour la configuration ainsi que le comportement des remplacements par l’environnement sont documentés dans Cycle de vie de la configuration et Variables d’environnement.
1. Une philosophie de développement : la vision d’abord
Chaque décision que nous prenons en matière de logiciel — quoi construire, comment le construire, quoi laisser de côté — devrait découler d’une hiérarchie d’intentions :
Vision
└── Architecture
└── Design
└── Implementation
└── Testing
└── Documentation
└── Release
Il ne s’agit pas d’un processus en cascade. C’est une hiérarchie de décisions. Cela signifie que lorsque vous écrivez une fonction, vous devez pouvoir tracer une ligne droite vers le haut : cette fonction existe en raison de cette décision de conception, qui existe en raison de ce choix architectural, qui existe en raison de cette vision. Si vous ne pouvez pas tracer cette ligne, le code ne devrait probablement pas exister.
Ce que chaque couche signifie en pratique :
| Couche | La question à laquelle il répond | Ce qui se passe sans cela |
|---|---|---|
| Vision | Pourquoi ce projet existe-t-il ? À qui s’adresse-t-il ? À quoi ressemble le succès ? | Vous créez des choses dont personne n’a besoin, ou vous vous contredisez d’une version à l’autre. |
| Architecture | Quelles sont les décisions structurelles qui rendent la vision possible ? | Vous vous retrouvez avec une « Big Ball of Mud » (grosse boule de boue) : du code qui fonctionne mais qui ne peut pas être modifié sans casser autre chose |
| Conception | Comment les composants sont-ils liés ? Quelles sont les interfaces entre eux ? | Vous obtenez un couplage fort : des composants qui en savent trop sur les détails internes les uns des autres |
| Implémentation | Comment construisons-nous ce composant spécifique ? | Bugs, problèmes de performance, failles de sécurité |
| Tests | L’implémentation correspond-elle au design ? Le design sert-il l’architecture ? | Vous livrez des produits défectueux et ne savez pas pourquoi. |
| Documentation | Comment transférer cette connaissance à la personne suivante ? | Chaque contributeur doit tout redécouvrir depuis le début. |
| Version | Comment pouvons-nous fournir cela aux utilisateurs de manière sûre et durable ? | Les utilisateurs obtiennent des logiciels cassés ou déroutants |
Le problème avec le saut du haut
ZeroClaw a été initialisé à l’aide d’outils d’IA travaillant à partir de la base de code TypeScript d’OpenClaw. La génération de code par l’IA opère au niveau de l’Implémentation. Elle écrit des fonctions, des structures et des modules qui réalisent des actions. Elle ne définit pas la Vision. Elle ne prend pas de décisions architecturales. Elle ne définit pas les contrats de conception.
Le résultat est une base de code remarquablement fonctionnelle mais architecturalement accidentelle. Le code fait ce qu’il doit faire aujourd’hui, mais il n’a pas été conçu. Il s’est accumulé. Ce schéma porte un nom dans notre industrie : le Big Ball of Mud (la grosse boule de boue). C’est l’architecture la plus courante en informatique, non pas parce que quelqu’un l’a choisie, mais parce que c’est ce que l’on obtient quand on saute le sommet de la hiérarchie.
Cette RFC est notre opportunité de corriger cela, non pas en jetant ce qui fonctionne, mais en faisant croître une architecture intentionnelle autour de l’existant grâce à une technique appelée le Strangler Fig Pattern : nous construisons la nouvelle structure autour des bords de l’ancienne, en migrant vers l’intérieur au fil du temps, jusqu’à ce que l’ancienne structure ait disparu. Pas de réécriture « big bang ». Pas de code fonctionnel jeté à la poubelle. Juste une amélioration régulière et intentionnelle.
2. La vision : ce qu’est ZeroClaw
Avant d’aborder l’architecture, il faut préciser ce que nous construisons. Il s’agit de la couche Vision. Tout ce qui suit doit servir cet objectif.
ZeroClaw est un environnement d’exécution d’assistant IA personnel que chacun peut exécuter sur n’importe quel matériel, d’une carte embarquée à 10 $ à un serveur cloud, sans aucune charge de configuration, sans aucune dépendance à des services externes et sans aucun compromis sur les capacités ou la sécurité.
En décomposant cela en engagements concrets :
Zéro surcharge. L’agent principal démarre en quelques millisecondes et utilise moins de mémoire qu’un onglet de navigateur. Ce n’est pas un argument marketing. C’est une contrainte architecturale. Chaque décision que nous prenons doit être évaluée à l’aune de celle-ci.
Aucune exigence externe. Un utilisateur qui télécharge ZeroClaw et dispose d’un fournisseur LLM configuré doit obtenir un assistant IA fonctionnel et utile sans rien installer d’autre. Les canaux, tableaux de bord et intégrations sont des éléments que vous ajoutez quand vous le souhaitez, et non des prérequis pour que cela fonctionne.
Zéro compromis. Lean ne signifie pas faible. ZeroClaw doit disposer d’un modèle de sécurité rigoureux, d’une observabilité réelle et d’une extensibilité authentique. La tension entre « petit binaire » et « pleine capacité » est résolue par la composition : un noyau léger, étendu par des composants que vous choisissez.
Pour tous les niveaux de compétence. Un étudiant sur un Raspberry Pi à 10 $ et une équipe gérant un déploiement en production doivent tous deux avoir l’impression que ZeroClaw a été conçu pour eux. Cela signifie que l’expérience par défaut doit être simple, et l’expérience avancée doit être puissante, et non deux produits différents.
Propriété de l’utilisateur. Vos données, votre matériel, votre configuration. ZeroClaw ne nécessite pas de compte, ne se connecte pas à distance et ne vous enferme pas dans une plateforme.
3. Évaluation honnête : Où nous en sommes aujourd’hui
Cette section ne constitue pas une critique du travail de quiconque. Il s’agit d’un diagnostic, et vous ne pouvez pas corriger ce que vous ne nommez pas.
3.1 Le problème structurel
L’ensemble du code source de ZeroClaw réside actuellement dans un seul crate Rust. Cela signifie :
- Un canal Telegram et la boucle principale de l’agent sont compilés à partir du même arbre de sources, que vous utilisiez Telegram ou non.
- Le tableau de bord web (une application React complète) est intégré dans le binaire à l’aide de
rust-embed, ce qui fait que chaque binaire inclut l’interface utilisateur web, même pour les utilisateurs qui n’utilisent que l’interface CLI. - Le serveur HTTP de la passerelle contient des gestionnaires de webhooks pour WhatsApp, Linq, Nextcloud Talk et Gmail, ce qui signifie que des intégrations de canaux spécifiques sont intégrées au serveur web
- Chacun des 70+ outils est compilé dans le binaire, indépendamment des outils qu’un utilisateur pourrait appeler.
- Le seul mécanisme pour exclure du code est un indicateur de fonctionnalité Cargo, ce qui nécessite que les utilisateurs disposent d’un environnement de développement Rust et recompilent à partir des sources.
La conséquence pour les utilisateurs : L’objectif annoncé est un binaire léger pour du matériel à 10 $. Mais le binaire est livré avec du code pour 27 canaux de messagerie, plus de 70 outils, un serveur web complet, une application React, et des intégrations avec Jira, Notion, Google Workspace, LinkedIn, et bien d’autres, dont la plupart ne seront jamais utilisées par un utilisateur donné.
La conséquence pour les contributeurs : Lorsqu’un fichier fait 9 500 lignes, il est impossible de le comprendre. Lorsque toutes les fonctionnalités sont regroupées dans un seul crate, toucher n’importe quel élément risque de tout casser.
3.2 Les preuves
Ce sont des faits mesurés issus de la base de code actuelle, et non des estimations :
| Fichier | Lignes | Ce qu’il fait | Ce qu’il devrait faire |
|---|---|---|---|
src/agent/loop_.rs | ~9 500 | Analyse des appels d’outils, streaming, historique, suivi des coûts, routage des modèles, mémoire, nettoyage des informations d’identification, construction du contexte | Orchestrer un seul tour d’agent |
src/gateway/mod.rs | ~2 260 | Serveur web + serveur d’application React + webhooks WhatsApp + webhooks Linq + webhooks Nextcloud + webhooks Gmail + appairage + limitation du débit + WebAuthn | Servir l’API du tableau de bord web |
src/providers/mod.rs | ~3 750 | Factory + 40+ implémentations de providers + flux OAuth + résolution des credentials + nettoyage des erreurs | Acheminer vers un fournisseur |
src/tools/mod.rs | all_tools_with_runtime() aux lignes 387–1066 | Instancier tous les 70+ outils de manière inconditionnelle | Enregistrer les outils que l’utilisateur a configurés |
Un fichier de 9 500 lignes n’est pas un module. C’est un monolithe qui arrive à avoir une extension .rs.
3.3 Ce qui est déjà bien
Ce diagnostic ne doit pas occulter ce qui est véritablement bien conçu :
- La couche de traits est excellente.
Provider,Channel,Tool,Memory,Observer,RuntimeAdapteretPeripheralsont des traits Rust propres et bien documentés. Ce sont les bonnes interfaces. Le problème est qu’elles ne correspondent pas aux limites de crate, donc le compilateur ne peut pas imposer la hiérarchisation des couches. - Le système de plugins WASM est partiellement implémenté.
PluginHost,WasmTool,WasmChannel,PluginManifestet la vérification des signatures Ed25519 sont tous présents danssrc/plugins/. Le pont d’exécution est un stub, mais la structure est correcte. - Le système d’observabilité est mature. OpenTelemetry, Prometheus et les métriques DORA sont tous implémentés en fonction d’un trait
Observerpropre. Il s’agit d’un travail de qualité de production. - Le modèle de sécurité est bien pensé. L’association des codes d’appariement, des niveaux d’autonomie, du sandboxing et de l’application des politiques démontre une réelle intention de conception.
Nous ne réécrivons pas ZeroClaw. Nous donnons à ses bonnes idées existantes une structure qui leur permet de se développer.
4. L’architecture cible
4.1 Le modèle du micro-noyau
Une architecture micro-noyau sépare un cœur minimal et stable des sous-systèmes optionnels qui l’étendent. Dans les systèmes d’exploitation, l’exemple classique est un noyau qui ne gère que la mémoire et l’ordonnancement, tout le reste, systèmes de fichiers, pilotes de périphériques, piles réseau, s’exécutant sous forme de processus distincts qui communiquent via une interface bien définie.
Pour un runtime d’agent IA, la révélation montre deux couches internes distinctes que l’analogie avec le système d’exploitation confond :
| Concept du micro-noyau du système d’exploitation | Équivalent ZeroClaw |
|---|---|
| Noyau | Couche fondation : traits d’API, config, providers, backends mémoire, infra, parseur d’appels d’outils. Le noyau irréductible : compile avec --no-default-features. Peut échanger des messages avec un LLM et stocker de la mémoire. Rien de plus. |
| Système d’initialisation / d’exécution | Couche d’exécution de l’agent : Boucle d’orchestration, application des politiques de sécurité, hôte de plugins, outils principaux, API IPC. Le crate zeroclaw-runtime, conditionné par la fonctionnalité agent-runtime. C’est ce qui fait de ZeroClaw un agent, et non une simple bibliothèque. |
| IPC | API de socket local / IPC entre l’exécution et les composants externes |
| Pilotes de périphérique | Plugins de canaux (Telegram, Discord, etc.) |
| Pilotes Filesystem | Plugins de backend de mémoire (SQLite, Markdown) |
| Processus utilisateur | Binaire de passerelle, application de bureau Tauri |
La distinction est importante : la base est le minimum requis pour qu’un binaire ZeroClaw puisse fonctionner. Le runtime est le minimum requis pour qu’il puisse fonctionner en tant qu’agent. Tout le reste est composé.
Cette séparation en deux couches a été identifiée lors de la décomposition de l’espace de travail de la Phase 1 (PR #5559) et est reflétée dans la dénomination des crates : zeroclaw-runtime (la crate) est conditionnée par agent-runtime (la fonctionnalité). Les versions antérieures de cette RFC utilisaient le terme « kernel » de manière imprécise pour désigner ce qui est désormais correctement nommé la couche runtime. Cette révision corrige cette terminologie dans tout le document.
4.2 La règle de dépendance
La règle architecturale la plus importante de cette conception, celle qui, si elle est enfreinte, fait s’effondrer toute la structure, est la suivante :
Les dépendances s’écoulent vers l’intérieur. Le runtime ne sait rien des plugins. Les plugins connaissent l’API. Rien ne sait tout.
zeroclaw-api ← defines all traits (Provider, Channel, Tool, ...)
▲ no implementations, no heavy dependencies
│ depends on
foundation crates ← zeroclaw-config, zeroclaw-providers, zeroclaw-memory,
▲ zeroclaw-infra, zeroclaw-tool-call-parser
│ depends on all depend on zeroclaw-api; no cross-dependencies
zeroclaw-runtime ← implements the agent loop (agent-runtime feature)
▲ depends on zeroclaw-api + foundation crates
│ depends on knows nothing about specific channels or tools
plugin crates ← zeroclaw-channel-discord, zeroclaw-tools-web, ...
▲ depend on zeroclaw-api (not the runtime)
│ depends on
zeroclaw binary ← thin wiring layer
reads config, registers plugins, starts runtime
Si zeroclaw-runtime importe jamais TelegramChannel, l’architecture a été violée. Le compilateur imposera cela une fois les limites des crates définies.
4.3 Carte des composants
┌─────────────────────────────────────────────────────────────────────┐
│ zeroclaw (binary crate) │
│ Reads config → registers only configured components → starts │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ zeroclaw-runtime (agent-runtime feature) │ │
│ │ │ │
│ │ Agent Loop · CLI Channel · Security Policy │ │
│ │ Plugin Host · Local IPC API │ │
│ │ Core Tools: shell, file, git, memory recall/store │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ Foundation (--no-default-features) │ │ │
│ │ │ │ │ │
│ │ │ zeroclaw-api · zeroclaw-config · zeroclaw-infra │ │ │
│ │ │ zeroclaw-providers · zeroclaw-memory │ │ │
│ │ │ zeroclaw-tool-call-parser │ │ │
│ │ │ │ │ │
│ │ │ Vision target: <5 MB RAM at runtime │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ ▲ │
│ zeroclaw-api (traits only) │
│ ▲ │
│ ┌──────────────┐ ┌────────┴────────┐ ┌─────────────────────┐ │
│ │ zeroclaw-gw │ │ Channel plugins│ │ Tool plugins │ │
│ │ (opt-in │ │ │ │ │ │
│ │ binary) │ │ channel-discord│ │ tools-web │ │
│ │ │ │ channel-slack │ │ tools-integrations │ │
│ │ HTTP/WS/SSE │ │ channel-tg │ │ tools-hardware │ │
│ │ Web UI │ │ channel-email │ │ tools-mcp │ │
│ │ REST API │ │ ... │ │ ... │ │
│ └──────┬───────┘ └─────────────────┘ └─────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ zeroclaw-desktop│ ← Tauri app (already exists in apps/tauri) │
│ │ System tray app │ bundles zeroclaw-gw as a sidecar │
│ │ Native GUI │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
4.4 Le modèle de distribution
L’architecture permet une distribution propre qui ne nécessite pas de toolchain Rust de la part des utilisateurs finaux :
| L’utilisateur souhaite | Ce qu’ils téléchargent | Ce que fait zeroclaw onboard |
|---|---|---|
| CLI uniquement | zeroclaw binaire d’exécution | Configurer le fournisseur, terminé |
| CLI + Discord | zeroclaw binaire d’exécution | Télécharger + installer channel-discord.wasm |
| Interface utilisateur web locale | zeroclaw + zeroclaw-gw | Configurez les deux, ouvrez le navigateur |
| Application de bureau | zeroclaw-desktop installateur | Bundles runtime + gateway + UI |
| Tout | zeroclaw-desktop ou zeroclaw --profile full | Télécharge tous les plugins |
La commande zeroclaw plugin install (prise en charge par PluginHost, qui existe déjà) devient le gestionnaire de paquets. L’assistant zeroclaw onboard l’intègre pour que les utilisateurs non techniques ne voient jamais cargo.
4.4.1 Politique de versionnement
Alors que ZeroClaw passe d’un seul crate à un espace de travail multi-crate, deux préoccupations doivent être séparées dès le départ :
- La version du produit : ce que rapporte
zeroclaw --version, ce que suivent les GitHub Releases, les changelogs et les gestionnaires de paquets (Homebrew, apt, cargo-binstall). C’est la version sur laquelle raisonnent les opérateurs et les utilisateurs. - Stabilité des composants : indique le degré de maturité et de fiabilité d’un composant donné. Un numéro de version ne peut pas, à lui seul, véhiculer cette information.
Ces éléments sont orthogonaux. Les confondre crée du bruit sémantique dans les versions semver et érode la confiance dans le numéro de version. Cette politique définit les deux.
Versionnage des crates : unifié avec des exceptions intentionnelles
Tous les crates applicatifs, le noyau, la passerelle, les crates de plugins d’outils, les crates de plugins de canaux et la CLI utilisent l’héritage de paquet du workspace Cargo : une version unique dans le Cargo.toml racine constitue la version de produit faisant autorité. C’est le bon modèle car :
- Les utilisateurs, les opérateurs et les packagers gèrent une seule version, pas douze.
- L’automatisation des versions via
release-plzest simple : une PR, une incrémentation, une entrée dans le journal des modifications. - Cela reflète l’identité de ZeroClaw en tant que produit, et non en tant qu’écosystème de bibliothèques.
- La version de l’interface WIT, et non la version de la crate Rust, constitue le véritable contrat ABI du plugin (voir §5.2)
Deux classes de crates sont intentionnellement exclues de l’héritage du workspace et conservent des versions indépendantes selon leur propre rythme :
| Crate | Raison de l’indépendance |
|---|---|
zeroclaw-api | Commence à 0.1.0 ; sa version 1.0.0 est une étape formelle de livraison de la v1.0.0, signalant une surface de trait Rust stable pour les auteurs de SDK de plugins. |
Fichiers d’interface WIT (wit/*.wit) | Versionné via les annotations @since et @unstable conformément à la spécification du modèle de composants WASI ; ce sont les principaux contrats d’ABI des plugins et sont indépendants du semver de Cargo. |
Ce que signifie « breaking » pour la version du produit
Étant donné que les crates d’application partagent une version unifiée, l’équipe a besoin d’une définition d’un changement cassant au niveau du produit, distincte d’un changement cassant au sein de l’implémentation interne d’un seul crate. Un changement cassant dans un crate de plugin qui ne franchit aucune des limites ci-dessous n’est pas un changement cassant au niveau du produit et ne justifie pas une incrémentation MAJOR.
| Bump | Garanti lorsque |
|---|---|
| MAJEUR | Modifications incompatibles de l’interface WIT (les plugins existants doivent être recompilés) ; modifications incompatibles de l’API IPC du noyau (la passerelle ou les clients externes sont interrompus) ; le schéma du fichier de configuration nécessite une migration ; les commandes ou indicateurs CLI sont supprimés ou renommés. |
| MINEUR | De nouvelles fonctionnalités n’importe où dans l’espace de travail ; nouveaux plugins disponibles dans le registre ; nouvelles API stables ; promotions de niveau de stabilité ; annonces de dépréciation (pas de suppression) |
| PATCH | Corrections de bugs ; correctifs de sécurité ; corrections de la documentation ; aucune nouvelle fonctionnalité et aucune dépréciation |
Niveaux de stabilité
La version du produit répond à la question « quelle est cette version ? » Un niveau de stabilité répond à « dans quelle mesure puis-je me fier à ce composant ? » Chaque composant, noyau, passerelle, crate de plugin et interface WIT porte l’un des trois niveaux. Les fichiers AGENTS.md locaux aux composants et les manifestes du registre de plugins constituent le modèle de propriété cible. Jusqu’à la fin de cette migration, les assignations actuelles canoniques se trouvent dans Coding agent guidelines.
| Niveau | Signification | Implication |
|---|---|---|
| Stable | Couvert par la politique de changement majeur du produit. Aucun changement majeur sans une augmentation de la version MAJEURE et un guide de migration publié. | Noyau (cible : v0.8.0), interface WIT zeroclaw-api (cible : v0.9.0), API IPC du noyau (cible : v1.0.0) |
| Bêta | Fonctionnel et testé. Des modifications incompatibles sont autorisées dans les versions MINEURES, mais elles sont annoncées dans le journal des modifications avec des notes de mise à jour. | zeroclaw-gw (v0.9.0 → v1.0.0), plugins de canal et d’outils matures |
| Expérimental | Aucune garantie de stabilité. Peut être modifié dans les versions PATCH. Doit être clairement marqué comme expérimental dans la documentation et les manifestes du registre de plugins. | Nouvelles intégrations d’outils, nouvelles implémentations de canaux, plugins matériels précoces |
Les niveaux de stabilité sont promus, jamais rétrogradés, par une décision délibérée de l’équipe. Les promotions sont consignées dans le journal des modifications et, pour les composants architecturaux, dans un ADR. Un composant doit conserver son niveau actuel pendant au moins un cycle de version complet avant qu’une promotion ne soit envisagée.
Automatisation des versions
Les versions utilisent release-plz, qui ouvre une PR de publication lors d’un push vers master, incrémente la version de l’espace de travail et génère un journal des modifications à partir des titres des commits conventionnels. release-plz comprend nativement l’héritage de l’espace de travail et gère automatiquement l’ordre de publication des crates. La crate zeroclaw-api, dont la version est gérée indépendamment, est gérée séparément à l’aide de la configuration par crate du même outil.
4.4.2 Artéfacts de la version
La transition vers le microkernel modifie la nature fondamentale de la question « quelles fonctionnalités sont compilées ? ». Aujourd’hui, cette question n’a qu’une seule réponse : toutes les fonctionnalités que vous avez passées via les indicateurs (feature flags) à cargo build. Après la transition, elle se divise en deux préoccupations distinctes :
- Ce que contient le binaire du noyau : figé à la compilation, déterminé par plateforme, publié sur GitHub Releases
- Quelles capacités sont disponibles : déterminé à l’exécution selon les plugins installés via
zeroclaw plugin install
Ce ne sont plus les mêmes questions, et la section [features] actuelle de Cargo.toml doit être interprétée à la lumière de cela.
Devenir des indicateurs de fonctionnalités actuels définis à la compilation
Les plus de 20 indicateurs de fonctionnalité dans le Cargo.toml actuel se répartissent en trois catégories à mesure que l’architecture évolue :
| Seau | Drapeaux | Résultat |
|---|---|---|
| Retirer → plugin | channel-nostr, channel-matrix, channel-lark, whatsapp-web, browser-native | Retiré du noyau. Chaque élément devient un crate de plugin WASM publié dans le registre des plugins. Aucune décision au moment de la compilation n’est requise. |
| Toujours actif | plugins-wasm, skill-creation | Compilé dans chaque binaire du noyau de manière inconditionnelle. plugins-wasm est le mécanisme central du noyau ; skill-creation est un chemin de code à surcharge nulle. Aucun ne doit être placé derrière un indicateur. |
| Stay → drapeau plateforme/infrastructure | peripheral-rpi, hardware, sandbox-landlock, sandbox-bubblewrap, voice-wake, probe | Restez en tant que drapeaux de compilation, car ils nécessitent la liaison de bibliothèques natives ou un accès au niveau du système d’exploitation qui ne peut pas être fourni par un plugin WASM. peripheral-rpi et hardware n’apparaissent que dans les cibles de version spécifiques à la plateforme. |
plugins-wasm est toujours activé, mais ce n’est pas un flag unique : c’est une taxonomie à trois flags. Le mécanisme hôte est inconditionnel ; le backend d’exécution est une décision au niveau de la plateforme prise à la compilation. plugins-wasm sans sous-flag de backend ne produit pas de runtime de plugins utilisable, car wasmtime a besoin soit d’un compilateur, soit d’un interpréteur pour exécuter un composant.
| Indicateur | Par défaut | Objectif |
|---|---|---|
plugins-wasm | Toujours actif | Active l’hôte de composants WASM ; charge et exécute les fichiers de composants .wasm |
plugins-wasm-cranelift | Activé (lorsque pris en charge) | Compilation JIT Cranelift; utilisé sur x86_64, aarch64 et autres cibles prises en charge par Cranelift |
plugins-wasm-pulley | Activé (lorsque Cranelift est indisponible) | Interpréteur Pulley ; utilisé sur ARM 32 bits et toute autre cible où Cranelift ne peut pas être utilisé |
Chaque cible de version active exactement un backend : cranelift lorsqu’il est pris en charge, pulley dans le cas contraire. Le principe de toujours être activé reste valable : chaque binaire embarque le hôte de plugin et peut exécuter des plugins sur sa plateforme.
Deux indicateurs nécessitent une décision délibérée de l’équipe avant la version v0.8.0 et sont présentés ici plutôt que résolus de manière unilatérale :
observability-prometheus: actuellement dansdefault. Les métriques Prometheus ajoutent une surcharge mesurable de la taille du binaire. La question est de savoir si un runtime de production doit livrer l’observabilité activée par défaut, ou si les opérateurs doivent l’activer explicitement. Recommandation : conserver dansdefaultpour la version standard ; les opérateurs ciblant des environnements fortement contraints en taille peuvent compiler avec--no-default-features.observability-otel: l’export OTLP entraîne une empreinte de dépendances plus importante (opentelemetry + client bloquant reqwest). Recommandation : reste optionnel, non inclus dansdefault. Les déploiements en production qui nécessitent l’export de traces l’activent explicitement.
Le méta-fonctionnalité ci-all se simplifie considérablement à mesure que les indicateurs de canal et d’outil sont retirés. À la version 1.0.0, elle ne couvre plus que les indicateurs de plateforme et d’infrastructure restants.
Le binaire canonique du noyau de la version
Le binaire publié sur GitHub Releases pour chaque cible de plateforme est construit avec le profil suivant :
| Compilé dans | Non compilé |
|---|---|
| Boucle principale de l’agent | Toute implémentation de canal |
| 10 à 12 outils principaux (voir Phase 2 D2) | Tout outil non essentiel |
| Backends de mémoire SQLite + Markdown | Automatisation du navigateur |
Hôte de plugins (plugins-wasm, toujours actif) | observability-otel (activation par l’opérateur) |
observability-prometheus | voice-wake (dépendance libasound2) |
skill-creation (zéro surcoût) | probe (débuggage matériel spécialisé) |
| Serveur IPC | Actifs Web (déplacés vers zeroclaw-gw) |
| Sandbox de plateforme pris en charge | peripheral-rpi (construction matérielle distincte) |
Il n’y a plus de binaire « build with everything ». Ce modèle mental est remplacé par zeroclaw plugin install --profile full, qui télécharge le catalogue complet des plugins après l’installation du binaire du noyau léger.
Matrice des artefacts de version
Chaque version GitHub publie les artefacts suivants :
| Artefact | Cibles | Notes |
|---|---|---|
zeroclaw binaire du noyau | x86_64-unknown-linux-musl, aarch64-unknown-linux-gnu, armv7-unknown-linux-gnueabihf, x86_64-apple-darwin, aarch64-apple-darwin, x86_64-pc-windows-msvc | Compilation statique de musl pour Linux x86_64 ; GNU pour les cibles ARM |
zeroclaw noyau binaire (matériel) | aarch64-unknown-linux-gnu, armv7-unknown-linux-gnueabihf | Mêmes cibles, compilées avec les indicateurs peripheral-rpi et hardware pour les déploiements sur Raspberry Pi |
zeroclaw-gw binaire de passerelle | Même matrice de plateforme que le noyau | Publié en même temps que le noyau ; les utilisateurs l’installent séparément |
| Fichiers de plugin WASM | wasm32-wasip2 | Publié dans le registre des plugins (et non dans les versions GitHub) ; installable via zeroclaw plugin install |
zeroclaw-desktop installateur | x86_64 et aarch64 pour macOS, Windows, Linux (AppImage/deb) | Ensembles noyau + passerelle + ensemble complet de plugins ; construit par le workflow Tauri |
Les builds du plugin wasm32-wasip2 s’exécutent dans une tâche CI séparée et sont publiés dans le registre de plugins selon leur propre cadence. Une publication de plugin ne nécessite pas de publication du noyau.
4.5 La séparation de la passerelle
La passerelle actuelle confond deux éléments qui doivent être séparés :
Current (wrong):
zeroclaw binary
└── gateway
├── Web UI server (serves React app)
├── REST/WS/SSE API
├── WhatsApp webhook handler ← this is a channel, not a web server
├── Linq webhook handler ← this is a channel, not a web server
├── Nextcloud webhook handler ← this is a channel, not a web server
└── Gmail push handler ← this is a channel, not a web server
Target (correct):
zeroclaw-kernel
└── Local IPC API (Unix socket / 127.x HTTP)
zeroclaw-gw (separate binary, optional)
└── Connects to kernel IPC API
└── Web UI server
└── REST/WS/SSE API
└── Generic webhook proxy → routes to channel plugins
channel-whatsapp.wasm
└── Registers its own webhook route with the gateway
└── Handles WhatsApp-specific message parsing
Pourquoi c’est important : Lorsque la passerelle est un processus séparé, elle peut planter, redémarrer ou être absente sans affecter l’agent. Le noyau continue de fonctionner. C’est particulièrement important pour le cas d’usage du matériel en périphérie : un Raspberry Pi exécutant le noyau peut avoir son interface web servie depuis un VPS, le noyau se connectant en sortie via un plugin de canal. Aucune règle de pare-feu entrante n’est nécessaire.
5. Les normes que nous devrions adopter
Les normes sont des accords élaborés par de nombreuses personnes compétentes au fil des années. Les adopter signifie bénéficier gratuitement de ces années de réflexion, et cela permet également à notre logiciel de s’intégrer naturellement au reste de l’écosystème. Voici celles qui s’appliquent directement à ZeroClaw.
5.1 Observabilité : OpenTelemetry
Ce que c’est : OpenTelemetry (OTel) est la norme de l’industrie pour la collecte de traces, de métriques et de journaux à partir de systèmes logiciels. Il est maintenu par la Cloud Native Computing Foundation et pris en charge par tous les principaux fournisseurs de cloud et outils de surveillance.
Pourquoi c’est important pour ZeroClaw : Nous avons déjà implémenté OtelObserver à partir de notre trait Observer. Nous disposons de métriques Prometheus et de métriques DORA. Le problème est que celles-ci ne sont pas encore standardisées dans l’ensemble du code : certains modules journalisent avec tracing::info!, d’autres émettent des ObserverEvents, et les deux ne sont pas connectés.
Ce que nous devons faire :
- Adopter OpenTelemetry comme interface d’observabilité unique pour tous les composants
- Assurez-vous que chaque plugin émet des spans OTel lors de son exécution, afin qu’un utilisateur puisse voir une trace complète allant de « message reçu sur Discord » à « agent a appelé l’outil shell » jusqu’à « réponse envoyée ».
- Adopter le contexte de traçage W3C (en-têtes
traceparent/tracestate) pour la propagation des identifiants de traçage à travers la frontière noyau ↔ passerelle ↔ plugin. - La sortie des journaux structurés doit être au format JSON lorsque
ZEROCLAW_LOG_FORMAT=jsonest défini (utilise déjà le cratetracing, il suffit d’ajouter un abonné JSON).
Normes : Spécification OpenTelemetry · W3C Trace Context (REC) · RFC 5424 (Syslog, pour l’intégration des journaux système)
5.2 Interface des plugins : WASI et WIT
Ce que c’est : WASI (WebAssembly System Interface) est l’API standard que les modules WebAssembly utilisent pour interagir avec le système hôte. WIT (WebAssembly Interface Types) est le langage de définition d’interfaces permettant de décrire ce qu’un composant WASM exporte et importe : considérez-le comme un fichier .proto, mais pour les plugins WASM.
Pourquoi c’est important pour ZeroClaw : Nos ponts WasmTool et WasmChannel n’ont actuellement aucun contrat formel concernant les exports requis par un binaire WASM de plugin. Cela signifie qu’un auteur de plugin doit deviner. Les fichiers WIT définissent ce contrat avec précision et permettent la génération automatique de code pour les auteurs de plugins dans n’importe quel langage.
Ce que nous devons faire :
- Définir les fichiers d’interface WIT pour les types de plugins
Tool,ChanneletMemory(un répertoirewit/à la racine de l’espace de travail) - Utilisez
wit-bindgenpour générer les liaisons côté hôte Rust à partir de ces fichiers WIT. - Documenter les interfaces WIT en tant que SDK officiel des plugins
- Un auteur de plugin écrit du Rust (ou du Go, du C, ou du Python) en s’appuyant sur l’interface WIT et exécute
cargo build --target wasm32-wasip2: le résultat se dépose dans~/.zeroclaw/plugins/
Normes : WASI 0.2 · Modèle de composants W3C WebAssembly · WIT IDL
5.3 API locale : OpenAPI 3.1
Ce que c’est : OpenAPI est la norme pour décrire les API HTTP. La version 3.1 est alignée sur JSON Schema Draft 2020-12.
Pourquoi c’est important pour ZeroClaw : L’API IPC locale du noyau (la socket à laquelle la passerelle et les autres composants se connectent) nécessite un contrat stable et documenté. Sans une spécification formelle, la passerelle et le noyau divergeront silencieusement au fil du temps.
Ce que nous devons faire :
- Rédiger une spécification OpenAPI 3.1 pour l’API IPC locale du noyau avant de l’implémenter
- Générez les stubs de serveur Rust à partir du spécification en utilisant
utoipaouaide. - Publiez la spécification dans
docs/reference/api/kernel-ipc-api.yaml - L’API externe de la passerelle doit également disposer d’une spécification OpenAPI.
Normes : OpenAPI 3.1 · JSON Schema Draft 2020-12
5.4 Sécurité : OWASP ASVS
Ce que c’est : Le OWASP Application Security Verification Standard est une liste de contrôle des exigences de sécurité, organisée par niveau de risque (L1 basique, L2 standard, L3 avancé).
Pourquoi c’est important pour ZeroClaw : La passerelle gère les webhooks provenant de services externes, traite des entrées utilisateur non fiables et gère des secrets. Le système d’appairage, la prise en charge de WebAuthn et la limitation de débit existent tous, mais il n’y a aucun cadre permettant de vérifier qu’ils sont complets ou corrects.
Ce que nous devons faire :
- Ciblez le niveau ASVS 2 pour la passerelle et le module de sécurité.
- Parcourez la liste de contrôle de niveau 2 et documentez les exigences que nous respectons entièrement, celles que nous partiellement respectons, et celles qui sont hors périmètre.
- Utilisez ceci comme base pour les problèmes et les PR liés à la sécurité.
Normes : OWASP ASVS 4.0 · OWASP Top 10
5.5 Modèle de qualité : ISO/IEC 25010
Ce que c’est : ISO/IEC 25010 définit un modèle pour la qualité des produits logiciels, avec huit caractéristiques principales : l’adéquation fonctionnelle, l’efficacité des performances, la compatibilité, l’utilisabilité, la fiabilité, la sécurité, la maintenabilité et la portabilité.
Pourquoi c’est important pour ZeroClaw : Lorsqu’on se demande « est-ce que c’est suffisamment bon pour être fusionné ? », la réponse est actuellement subjective. ISO 25010 nous fournit un vocabulaire pour cette discussion. Les engagements de vision correspondent directement : « zéro surcharge » → efficacité des performances ; « sur tout matériel » → portabilité ; « aucun compromis » → sécurité + fiabilité.
Ce que nous devons faire :
- Utilisez les huit caractéristiques de qualité comme filtre lors des revues de code (PR) pour les modifications significatives.
- Ajoutez une brève déclaration sur l’impact qualité dans le modèle de PR pour les modifications architecturales (par exemple, « Cette modification améliore la maintenabilité en réduisant le couplage entre les implémentations de la passerelle et des canaux, sans impact sur l’efficacité des performances »).
Normes : ISO/IEC 25010:2023
5.6 Déjà adopté : à conserver
Ces éléments sont déjà en place et doivent être maintenus :
| Standard | Statut | Où |
|---|---|---|
| Versionnage sémantique 2.0.0 | ✅ Adopté | Cargo.toml, versions |
| Conventional Commits | ✅ Adopté | AGENTS.md, historique des commits |
| Horodatages RFC 3339 / ISO 8601 | ✅ Adopté | MemoryEntry, toutes les horodatages |
| Spécification des répertoires de base XDG | ✅ Adopté | directories crate utilisé |
| Conserver un journal des modifications | ✅ Adopté | CHANGELOG.md |
| Règles de l’API Rust | ✅ Partiellement | La configuration de Clippy impose de nombreuses |
6. Feuille de route par phases : v0.7.0 → v1.0.0
Chaque phase suit la hiérarchie Vision → Architecture → Conception → Implémentation → Tests → Documentation → Mise en production. Aucune phase ne commence l’implémentation tant que sa conception n’a pas été examinée et approuvée.
La stratégie de migration globale repose sur le Strangler Fig Pattern : nous développons la nouvelle architecture autour des bords du code existant, en migrant progressivement vers l’intérieur, jusqu’à ce que l’ancienne structure soit entièrement remplacée. Nous n’effectuons jamais de réécriture « stop the world ». L’application reste toujours livrable.
Phase 1 · v0.7.0 : « The Seams »
Thème : Rendre l’architecture visible sans modifier le comportement. Tracez les lignes en premier.
Pourquoi cette phase : Vous ne pouvez pas migrer vers une architecture en couches tant que les couches n’existent pas comme de véritables frontières. Actuellement, les traits définissent des jointures logiques mais le compilateur ne les applique pas : tout se trouve dans un seul crate, donc n’importe quoi peut importer n’importe quoi. Cette phase rend les jointures réelles.
Alignement de la vision : Aucune des propriétés de la vision ne change pour les utilisateurs. Cela est entièrement interne. La valeur réside dans le fait que chaque contribution future dispose désormais d’un emplacement structurel, et que les nouveaux contributeurs peuvent comprendre la base de code par parties plutôt que dans son intégralité.
Livrables de la phase 1
D1 : Extraire le crate zeroclaw-api
Créez un nouveau crate crates/zeroclaw-api contenant uniquement les définitions de traits et leurs types associés. Aucune implémentation. Aucune dépendance lourde. Ce crate doit se compiler en moins de deux secondes.
Déplacez-vous dans ce crate :
src/providers/traits.rs→Provider,ChatMessage,ChatResponse,ToolCall,StreamChunk,ProviderCapabilitiessrc/channels/traits.rs→Channel,ChannelMessage,SendMessagesrc/tools/traits.rs→Tool,ToolResult,ToolSpecsrc/memory/traits.rs→Memory,MemoryEntry,MemoryCategorysrc/observability/traits.rs→Observer,ObserverEvent,ObserverMetricsrc/runtime/traits.rs→RuntimeAdaptersrc/peripherals/traits.rs→Périphérique
Chaque autre crate de l’espace de travail qui a besoin de ces types ajoute zeroclaw-api en tant que dépendance. Le compilateur impose désormais qu’aucune crate d’implémentation ne puisse importer une autre crate d’implémentation sans passer par la couche API.
D2 : Extraire la crate zeroclaw-tool-call-parser
La logique d’analyse des appels d’outil dans src/agent/loop_.rs représente environ 1 400 lignes de transformation de texte pur : elle prend une chaîne provenant du LLM et renvoie une liste d’appels d’outils structurés. Elle ne dépend pas de l’état de l’agent, de la mémoire, des fournisseurs ou des canaux. Elle gère une douzaine de formats de sortie différents des LLM (JSON, XML, style GLM, MiniMax, style Perl, barres de code Markdown, et plus encore).
Cette logique est :
- Autonome : parfait pour sa propre crate
- Le code le plus adapté au fuzzing dans le projet : les tests basés sur les propriétés ont leur place ici
- Une véritable contribution à l’écosystème Rust : aucune autre crate ne le fait de manière aussi complète
Créez crates/zeroclaw-tool-call-parser avec une API publique approximativement :
#![allow(unused)]
fn main() {
pub fn parse(text: &str, specs: &[ToolSpec]) -> ParseResult
pub struct ParseResult {
pub calls: Vec<ParsedToolCall>,
pub remaining_text: Option<String>,
}
pub struct ParsedToolCall {
pub name: String,
pub arguments: serde_json::Value,
pub tool_call_id: Option<String>,
}
}
Les ~300 tests d’analyse actuellement présents dans loop_.rs sont déplacés vers ce crate. loop_.rs est réduit d’environ 1 400 lignes.
D3 : Adopter OpenTelemetry comme standard d’observabilité
Formaliser ce qui est déjà implémenté : documenter que ObserverEvent et ObserverMetric constituent le bus d’événements interne, et que OtelObserver est le backend de production canonique. Adopter un abonné de journalisation structurée en JSON pour ZEROCLAW_LOG_FORMAT=json. Adopter le contexte de traçage W3C pour la traçabilité inter-composants à venir.
D4 : Écrire les fichiers d’interface WIT
Avant de mettre en œuvre l’exécution des plugins WASM, définissons les contrats. Créez un répertoire wit/ à la racine de l’espace de travail avec les définitions d’interface pour :
zeroclaw:tool/tool.wit: l’interface du plugin Toolzeroclaw:channel/channel.wit: l’interface du plugin Channel
Ces fichiers deviennent le SDK officiel du plugin. L’implémentation dans la version 0.8.0 sera générée à partir de ces fichiers.
Indicateurs de succès pour v0.7.0
zeroclaw-apise compile en < 2 secondes avec zéro dépendance d’implémentationzeroclaw-tool-call-parsera ≥ 95 % de couverture de tests (la logique est entièrement testable de manière isolée)loop_.rsfait moins de 8 000 lignes- Aucun changement de comportement visible pour l’utilisateur
- Aucune régression de performance (la suite de tests de performance passe)
Phase 2 · v0.8.0 : « The Runtime »
Thème : Formaliser l’exécution de l’agent comme une unité propre et déployable de manière indépendante. Tout ce qui n’est pas l’exécution devient un invité.
Pourquoi cette phase : Une fois les points de jonction en place (v0.7.0), nous pouvons tracer explicitement la frontière du runtime. Cette phase extrait zeroclaw-runtime en tant que crate autonome, finalise le pont d’exécution des plugins WASM et connecte le client du registre de plugins : le mécanisme par lequel tout ce qui est extérieur au runtime s’y connecte.
Alignement avec la vision : C’est ici que le modèle de composition devient concret pour les utilisateurs. Un utilisateur qui souhaite uniquement un agent CLI télécharge un seul binaire, exécute zeroclaw onboard, et c’est terminé : pas de chaîne d’outils Rust, pas de compilation. L’assistant zeroclaw onboard acquiert la capacité de télécharger des composants de plugin à la demande.
Livrables de la phase 2
D1 : Formaliser le crate zeroclaw-runtime
Extrayez la boucle d’orchestration de l’agent, le canal CLI, la politique de sécurité, l’hôte de plugin et l’API IPC dans crates/zeroclaw-runtime, en les conditionnant par la fonctionnalité agent-runtime. Ce crate dépend de zeroclaw-api et des crates de base. Il n’a aucune connaissance de Telegram, Discord, Anthropic ou de toute implémentation d’outil spécifique.
Le runtime expose une API publique propre :
#![allow(unused)]
fn main() {
pub struct Runtime { ... }
pub struct Registry {
pub fn register_channel(&mut self, ch: Arc<dyn Channel>);
pub fn register_tool(&mut self, t: Box<dyn Tool>);
pub fn set_provider(&mut self, p: Arc<dyn Provider>);
pub fn set_memory(&mut self, m: Arc<dyn Memory>);
pub fn set_observer(&mut self, o: Arc<dyn Observer>);
}
pub async fn run(runtime: Runtime, registry: Registry) -> anyhow::Result<()>;
}
Le crate binaire devient une fine couche de câblage qui lit la configuration et appelle run.
D2 : Compléter le pont d’exécution WASM
La dépendance extism est incompatible avec le WASM Component Model (fichiers .wit) et nécessite la fonctionnalité cranelift de wasmtime, ce qui empêche la compilation pour les cibles ARM32. Supprimez Extism et remplacez-le par une utilisation directe de wasmtime. Pendant la transition, Extism doit être conservé comme option jusqu’à la PR de dépréciation finale.
Intégrer wasmtime dans zeroclaw-plugins avec des dépendances optionnelles sur cranelift (pour la plupart des cibles de compilation) ou pulley (pour ARM32). Avec les interfaces WIT définies dans la v0.7.0, utiliser wit-bindgen pour générer les liaisons côté hôte.
Une implémentation complète du pont d’exécution WASM définit les fonctions hôtes WASI que les plugins WASM peuvent appeler (requêtes HTTP, accès mémoire, journalisation) dans le cadre du modèle de permissions déjà défini dans PluginPermission. Dans la mesure du possible, les API WASI Preview 2 doivent être utilisées (wasi:io, wasi:http, wasi:filesystem, etc.) afin de fournir aux plugins une API cohérente et conforme aux standards.
D3 : Client du registre de composants
Ajoutez une sous-commande zeroclaw plugin prise en charge par un client de registre simple :
zeroclaw plugin list # list installed plugins
zeroclaw plugin search <query> # search the component registry
zeroclaw plugin install <name> # download, verify, and install a plugin
zeroclaw plugin remove <name> # remove an installed plugin
zeroclaw plugin update # update all installed plugins
Le registre est un fichier d’index JSON diffusé depuis une URL connue (par ex. https://plugins.zeroclaw.com/index.json). Chaque entrée inclut le nom, la version, l’URL de téléchargement, la somme de contrôle SHA-256 et la clé publique Ed25519 de l’éditeur. La vérification de signature de PluginHost gère déjà le modèle de sécurité.
D4 : Intégrer zeroclaw onboard au système de plugins
L’assistant de prise en main doit demander à l’utilisateur quels canaux et intégrations il souhaite, puis appeler PluginRegistry::install pour chacun. Aucune compilation n’est nécessaire. L’utilisateur télécharge un binaire, exécute zeroclaw onboard, et dispose d’un agent configuré et fonctionnel en moins de deux minutes.
D5 : Réduire all_tools_with_runtime aux outils principaux uniquement
Le noyau inclut exactement les outils nécessaires à un agent utile sans aucun plugin installé : shell, file_read, file_write, file_edit, git_operations, glob_search, content_search, memory_recall, memory_store, memory_forget et web_fetch. Tout le reste est enregistré par les plugins installés.
Indicateurs de succès pour v0.8.0
zeroclaw-runtimese compile indépendamment, sans code d’implémentation de canal ou d’outil.zeroclaw plugin install channel-discordfonctionne de bout en bout.zeroclaw onboardinstalle des plugins sans nécessiter de chaîne d’outils Rust.- La taille binaire à l’exécution est suivie et rapportée dans les notes de version ; l’objectif est une progression vers la cible de vision (voir §7).
- Un plugin d’outil WASM écrit en Rust à l’aide de l’interface WIT s’exécute correctement.
Phase 3 · v0.9.0 : « La Passerelle »
Thème : Séparer la surface web du noyau de l’agent.
Pourquoi cette phase : La passerelle constitue actuellement le plus grand couplage structurel du codebase. Elle intègre une application React compilée, gère la logique de webhook spécifique aux canaux, et est compilée dans chaque binaire, y compris les binaires destinés à du matériel edge à 10 $ qui ne servira jamais de page web.
Alignement de la vision : Cette phase réalise pleinement la promesse des « zéro exigences externes ». Un utilisateur sur un Raspberry Pi obtient un binaire du noyau sans serveur web, sans application React et sans écouteur HTTP. Un utilisateur souhaitant le tableau de bord web installe zeroclaw-gw séparément.
Livrables de la phase 3
D1 : Définir l’API IPC du noyau
Avant d’extraire la passerelle, définissez la spécification OpenAPI 3.1 pour l’API locale exposée par le noyau via un socket Unix ou un port en boucle locale. Cette API est celle à laquelle la passerelle, l’application Tauri et tout futur client se connectent. Elle constitue le contrat stable entre le noyau et l’extérieur.
Les points de terminaison incluent : envoyer un message, recevoir une réponse en streaming, lister les sessions actives, lister les plugins installés, obtenir le statut de l’agent, gérer la mémoire, déclencher des tâches cron. Il s’agit avant tout d’un document de conception : la spécification doit être examinée et approuvée avant d’écrire la moindre ligne d’implémentation.
D2 : Implémenter le serveur IPC du noyau
Ajoutez le serveur IPC à zeroclaw-kernel derrière un indicateur de fonctionnalité (--features ipc). Sur les plateformes qui le prennent en charge, le noyau écoute sur un socket Unix à l’emplacement ~/.zeroclaw/kernel.sock. Sous Windows, utilisez un pipe nommé. La commande zeroclaw gateway (l’entrée actuelle du serveur web) devient zeroclaw-gw et se connecte à ce socket.
D3 : Extraire zeroclaw-gw en tant que binaire séparé
Déplacez src/gateway/ vers un nouveau crate crates/zeroclaw-gw/ avec son propre binaire. Il dépend de zeroclaw-api et se connecte au noyau via l’API IPC. L’application React embarquée via rust-embed est entièrement déplacée dans ce crate : le binaire du noyau ne contient plus aucune ressource web.
D4 : Migrer les gestionnaires de webhooks de canal hors de la passerelle
Les gestionnaires de webhooks WhatsApp, Linq, Nextcloud Talk et Gmail actuellement présents dans gateway/mod.rs sont déplacés vers leurs plugins de canal respectifs. La passerelle fournit une API générique d’enregistrement des webhooks : lors de son chargement, un plugin de canal enregistre le préfixe du chemin de ses webhooks et sa fonction de traitement. La passerelle achemine les webhooks entrants vers le gestionnaire enregistré. La passerelle ne connaît plus WhatsApp.
D5 : Formaliser la relation sidecar de Tauri
Mettez à jour apps/tauri/ pour inclure zeroclaw-gw en tant que binaire sidecar Tauri. L’application Tauri devient la distribution « expérience complète » : elle démarre automatiquement le noyau et la passerelle, puis ouvre l’interface web. Les utilisateurs qui téléchargent l’application Tauri obtiennent tout fonctionnel sans avoir à toucher au terminal.
Indicateurs de succès pour v0.9.0
- Le binaire du noyau (version de release) ne contient aucun actif web ni code de serveur HTTP.
zeroclaw-gwdémarre, se connecte au noyau via IPC et sert le tableau de bord web.- La suppression de
zeroclaw-gwne casse pas le noyau ni aucun des plugins de canal. - Le code des canaux WhatsApp, Linq, Nextcloud Talk et Gmail a été déplacé vers des crates de plugins
- Les bundles d’applications de bureau Tauri démarrent correctement les deux binaires.
Phase 4 · v1.0.0 : « La Plateforme »
Thème : ZeroClaw devient une plateforme composable, et non une application monolithique.
Pourquoi cette phase : Avec le noyau stable, la passerelle séparée et le système de plugins fonctionnel, la version 1.0.0 est la release où l’architecture devient le produit. Les développeurs externes peuvent écrire et publier des plugins. Les utilisateurs peuvent assembler exactement le ZeroClaw qu’ils souhaitent. Le binaire peut légitimement revendiquer le profil léger que la vision promet.
Livrables de la phase 4
D1 : Migrer tous les canaux restants vers des plugins
Chaque implémentation des 27+ canaux devient un crate de plugin WASM autonome. Ils sont publiés dans le registre de composants avec des versions signées. Le binaire du noyau ne contient aucune implémentation de canal, sauf pour la CLI.
D2 : Migrer les outils de longue traîne vers des plugins
Environ 60 des 70+ outils sont déplacés vers des crates de plugins, regroupés par domaine : zeroclaw-tools-web (navigateur, recherche, capture d’écran, PDF), zeroclaw-tools-integrations (Jira, Notion, Google Workspace, MS365, LinkedIn), zeroclaw-tools-hardware (informations sur la carte, GPIO), zeroclaw-tools-cloud (opérations cloud, opérations de sécurité). Le noyau ne conserve que les 10 à 12 outils principaux identifiés dans la version v0.8.0.
D3 : SDK de plugin et documentation pour les développeurs
Publiez un guide de développement de plugins. Un développeur devrait pouvoir écrire un nouveau plugin d’outil en un après-midi :
- Ajoutez
zeroclaw-plugin-sdken tant que dépendance - Implémentez le trait généré par WIT
cargo build --target wasm32-wasip2zeroclaw plugin install ./my-plugin/
Le SDK gère les liaisons des fonctions hôtes, le format du manifeste et le modèle de permissions.
D4 : Stabiliser l’API IPC du noyau en version 1.0
L’API IPC du noyau reçoit un préfixe de version (/v1/) et une garantie de stabilité. Des modifications incompatibles ne sont pas autorisées pour cette API dans la version v1.x. C’est le contrat sur lequel les clients tiers et la passerelle s’appuient.
D5 : Extraire la politique de versionnage et les définitions des niveaux de stabilité vers docs/book/src/maintainers/stability-tiers.md
La politique de versionnement et le tableau des niveaux de stabilité définis dans la section 4.4.1 de cette RFC deviennent un document de référence permanent pour les contributeurs, situé à docs/book/src/maintainers/stability-tiers.md. Ce document sert de référence quotidienne aux contributeurs lors de l’attribution d’un niveau à un nouveau crate de plugin, et est consulté par les mainteneurs lors de la prise de décisions de publication. La RFC elle-même reste le registre historique expliquant pourquoi ces décisions ont été prises ; le document extrait constitue ce que les contributeurs consultent.
Indicateurs de succès pour la version 1.0.0
- La taille binaire à l’exécution est suivie par rapport à l’objectif visé (voir §7) ; un passage d’optimisation dédié à chaque crate est attendu dans le cadre du flux de travail v1.0.0.
- Un développeur tiers peut publier un plugin fonctionnel en utilisant uniquement la documentation publique.
- Toutes les implémentations de plus de 27 canaux sont disponibles en tant que plugins téléchargeables dans le registre.
zeroclaw onboardeffectue une configuration complète en moins de 2 minutes sur un Raspberry Pi Zero 2W sans aucun outilchain Rust installé.- Le catalogue complet des plugins est installable avec
zeroclaw plugin install --profile full
7. Métriques de code et de complexité
Il s’agit d’estimations basées sur une analyse directe du code de la base de code actuelle. Elles visent à donner une idée de l’échelle, et non à être des prédictions exactes.
Lignes de code qui sortent du runtime
| Qu’est-ce qui bouge | Lignes approximatives | Destination |
|---|---|---|
Analyseur d’appel d’outil (de loop_.rs) | ~1 400 | crate zeroclaw-tool-call-parser |
| Plus de 60 implémentations d’outils non essentiels | ~30 000 | Bibliothèques de plugins |
| 24+ implémentations de canaux non principaux | ~7 200 | Bibliothèques de plugins |
| Serveur HTTP de passerelle | ~2 260 | crate zeroclaw-gw |
| Application React intégrée (poids binaire) | N/A | crate zeroclaw-gw |
| Gérer les webhooks de canal depuis la passerelle | ~500 | Crate de plugin de canal |
| Total estimé retiré du runtime | ~41 000 lignes | N/A |
Réduction de la complexité au niveau des fichiers
| Fichier | Lignes actuelles | Cible après la migration | Réduction |
|---|---|---|---|
src/agent/loop_.rs | ~9 500 | ~5 000 | ~47% |
src/gateway/mod.rs | ~2 260 | Déplace vers zeroclaw-gw | 100 % |
src/tools/mod.rs | all_tools_with_runtime fait environ 680 lignes | ~80 lignes (outils de base uniquement) | ~88 % |
src/providers/mod.rs | ~3 750 | ~1 200 (les fournisseurs s’enregistrent eux-mêmes) | ~68 % |
src/channels/mod.rs | ~200 + 44 fichiers de canaux | Seulement via l’interface CLI | ~90 % |
Taille du binaire : progrès mesurés et objectif de la vision
La vision du projet est exprimée en termes d’exécution : <5 MB RAM sur du matériel à 10 $. La taille du binaire sur disque et l’empreinte mémoire à l’exécution (RSS) sont liées mais pas identiques : la pagination à la demande signifie que seuls les chemins de code exécutés sont résidents en mémoire. Les deux sont suivis.
Modèle en deux passes : La décomposition architecturale (Phases 1 à 3) et l’optimisation de la taille des binaires sont des flux de travail distincts. La décomposition permet l’optimisation en isolant les dépendances vers leurs crates propriétaires. Maximiser l’efficacité crate par crate constitue la seconde passe attendue, et non une livraison du travail structurel lui-même.
| Configuration | Pré-décomposition (v0.6.x) | Résultat de la phase 1 (v0.7.0) | Cible de vision |
|---|---|---|---|
| Binaire monolithique complet | ~8,8 Mo | N/A (remplacé par le modèle de plugin) | N/A |
Fondation uniquement (--no-default-features) | N/A | 6,6 Mo (mesuré, épuré) | À déterminer après la passe d’optimisation |
Binaire d’exécution (fondation + agent-runtime) | N/A | suivi | aspiration : ≤ 5 Mo de RAM en cours d’exécution |
| Runtime + passerelle | N/A | suivi | ~5–7 Mo sur le disque |
| Runtime + passerelle + 5 premiers canaux | N/A | suivi | ~8–10 Mo (les plugins sont des fichiers séparés) |
| Application de bureau Tauri (regroupe tout) | N/A | suivi | ~20–25 Mo d’installateur |
La build de fondation Phase 1 de 6,6 Mo représente un progrès réel par rapport au monolithe de 8,8 Mo et prouve que la décomposition fonctionne. Atteindre l’objectif visé nécessite une passe dédiée d’audit des dépendances et d’optimisation à travers chaque crate une fois la décomposition structurelle terminée : examiner le Cargo.toml de chaque crate pour détecter les dépendances inutiles ou sur-dotées en fonctionnalités, valider les profils LTO et strip, et auditer quels feature flags de tokio/serde sont réellement nécessaires.
Le changement structurel clé : la taille binaire n’est plus une fonction des « fonctionnalités compilées au moment de la construction » mais devient une fonction des « plugins installés au moment de l’exécution », que l’utilisateur contrôle. Ce changement est l’objectif architectural des phases 1 à 3. Les chiffres de taille sont l’objectif d’optimisation de la phase suivante.
Amélioration du temps de compilation
Actuellement, une compilation complète cargo build --release de cette base de code compile tous les canaux, tous les outils, tous les fournisseurs et l’application React intégrée dans une seule unité de compilation. La décomposition des crates signifie :
- Le noyau se compile de manière indépendante et sa sortie compilée est mise en cache.
- Une modification apportée à
channel-discordne recompilera pas le noyau. - Les contributeurs travaillant sur un plugin ne recompilent que leur plugin.
- Le CI peut paralléliser la compilation des crates entre les jobs.
Amélioration estimée du temps d’exécution pour les builds incrémentaux : réduction de 60 à 75 % pour les modifications qui ne touchent pas au noyau.
8. Ce que cela signifie pour les contributeurs
Pour les nouveaux contributeurs
La plainte la plus courante des nouveaux contributeurs aux grands projets de code est : « Je ne sais pas par où commencer. » Avec l’architecture actuelle, la réponse à la question « où va un message Discord ? » nécessite de suivre le flux à travers channels/discord.rs → channels/mod.rs → gateway/mod.rs → agent/loop_.rs → des dizaines d’autres fichiers.
Avec l’architecture micro-noyau, la réponse est : « cela va au récepteur Channel du noyau, via le plugin channel-discord ». Un nouveau contributeur peut comprendre complètement le canal Discord en lisant un seul crate de plugin. Il peut comprendre la boucle complète de l’agent en lisant zeroclaw-kernel, sans avoir besoin de connaître le code des canaux ou des outils.
Une bonne règle empirique pour les nouveaux contributeurs : si vous pouvez décrire votre modification en une phrase sans mentionner plus d’un composant, vous travaillez au bon niveau. « Corriger un bug dans la façon dont le canal Discord gère les réponses aux fils de discussion » correspond à un seul composant. « Refactoriser la boucle de l’agent, mettre à jour le canal Discord et corriger aussi le backend de mémoire » correspond à trois composants : cela devrait faire l’objet de trois PR.
Pour les mainteneurs
Chaque rapport de bug aura un emplacement clair. « L’agent appelle les outils de manière incorrecte » → zeroclaw-tool-call-parser ou zeroclaw-runtime. « L’intégration Discord est cassée » → plugin channel-discord. « Le tableau de bord web ne se charge pas » → zeroclaw-gw. Actuellement, n’importe lequel de ces bugs pourrait se trouver n’importe où dans plus de 50 000 lignes de code.
Pour le processus de publication
Le modèle de plugins permet aux canaux et aux outils d’avoir des cycles de publication indépendants. Une correction de bug dans le canal Telegram ne nécessite pas de nouvelle version du noyau. La stabilité du noyau devient le fondement sur lequel tout le reste s’appuie. Des itérations rapides sur les plugins ne mettent pas en danger la stabilité du noyau.
Pour la communauté
Une interface WIT publiée et un SDK de plugin signifient que n’importe qui peut étendre ZeroClaw sans avoir à le fork. Une entreprise ayant besoin d’une intégration spécifique peut écrire un plugin en se basant sur l’interface publique. C’est ainsi que les écosystèmes se construisent.
Annexe A : Glossaire
Termes utilisés dans ce document qui peuvent être inconnus :
Big Ball of Mud (grosse boule de boue) : Une architecture (ou son absence) dans laquelle la base de code a grandi de manière organique sans planification structurelle. Le nom provient d’un article de 1997 de Brian Foote et Joseph Yoder. C’est l’architecture la plus courante en logiciel, non pas parce que quelqu’un la choisit, mais parce que c’est ce que l’on obtient par défaut.
Loi de Conway : « Toute organisation qui conçoit un système produira une conception dont la structure est le reflet de la structure de communication de l’organisation. » (Mel Conway, 1968) Si les contributeurs travaillent dans des silos isolés sans se parler, le code en sera le reflet. Si les contributeurs collaborent avec des interfaces claires entre leurs travaux, le code le reflétera également.
Principe d’inversion des dépendances : Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau. Les deux doivent dépendre d’abstractions. C’est pourquoi zeroclaw-runtime dépend de zeroclaw-api (abstractions) et non de channel-discord (une implémentation spécifique).
Micronoyau : Une architecture dans laquelle le système central ne contient que les fonctionnalités minimales nécessaires, et toutes les autres capacités sont fournies par des composants distincts qui communiquent avec le noyau via des interfaces bien définies.
Strangler Fig Pattern : Une stratégie de migration dans laquelle vous remplacez de manière incrémentale des parties d’un système existant en construisant de nouveaux composants en parallèle des anciens. Nommé d’après le figuier étrangleur, une plante qui pousse autour d’un arbre existant jusqu’à ce que l’arbre d’origine ait été entièrement remplacé. La propriété clé : le système reste toujours en fonctionnement et toujours déployable pendant la migration.
Dette technique : Le coût accumulé des raccourcis pris dans la conception logicielle. Comme une dette financière, un faible montant peut être productif (vous livrez plus rapidement maintenant). Un montant élevé devient paralysant (vous passez tout votre temps à payer les intérêts, c’est-à-dire les corrections de bugs et les solutions de contournement, au lieu de développer de nouvelles fonctionnalités).
WIT (WebAssembly Interface Types) : Un langage de définition d’interface permettant de décrire ce que les composants WASM exportent et importent. Considérez-le comme un contrat : « un plugin Tool doit exporter une fonction appelée execute qui prend du JSON et retourne du JSON. » WIT rend ce contrat précis et lisible par machine.
Annexe B : Lectures complémentaires
Voici des ressources que l’équipe peut trouver utiles. Elles ne constituent pas une lecture obligatoire, mais chacune a directement influencé cette proposition.
-
“A Philosophy of Software Design” : John Ousterhout. Le meilleur livre court sur la gestion de la complexité logicielle. Son concept de « modules profonds » (interfaces simples, implémentations puissantes) correspond exactement à ce que vise le modèle micronoyau.
-
“Clean Architecture” : Robert C. Martin. La règle de dépendance décrite dans la section 4.2 de ce document provient de ce livre.
-
“Release It!” : Michael Nygard. Des patrons pratiques pour créer des logiciels qui restent opérationnels en production. Les patrons de séparation par passerelle et de disjoncteur (circuit-breaker) abordés ici sont tirés de ce livre.
-
The Rust API Guidelines : le guide officiel pour concevoir des bibliothèques Rust idiomatiques. Nos interfaces de traits doivent suivre ces conventions.
-
The WebAssembly Component Model : la base technique du système de plugins proposé dans cette RFC.
-
Spécification OpenTelemetry : la spécification complète du standard d’observabilité que nous adoptons.
Cette proposition a été élaborée à partir d’une analyse détaillée de la base de code ZeroClaw en version 0.6.8. Les métriques de code citées sont basées sur une mesure directe des fichiers source. Les recommandations architecturales reflètent des modèles éprouvés dans la conception de logiciels systèmes, appliqués aux contraintes et objectifs spécifiques du projet ZeroClaw.
Les retours, corrections et contre-propositions sont les bienvenus. La meilleure architecture est celle que l’équipe comprend et en laquelle elle croit, pas celle dictée par une seule personne.