Config rot : hermes config check alerte désormais sur les sélections renommées, désinstallées et désactivées


Vous avez transféré un vieux config.yaml sur une nouvelle machine, ou bien vous avez désinstallé un plugin il y a quelques semaines et renommé un toolset. Hermes démarre, discute, et semble en parfaite santé — jusqu’au jour où un bot de plateforme cesse de répondre, ou où toute une catégorie d’outils manque simplement à l’appel. Vous ouvrez le fichier de config et tous les noms que vous attendiez sont toujours là.

C’est la config rot : les noms de toolsets enregistrés dans platform_toolsets correspondent à ce que Hermes croyait exister au moment de l’enregistrement. Une fois un plugin supprimé ou un toolset renommé, ces noms ne pointent vers rien, et le runtime les ignore en silence. Un patch fusionné le 2026-09-29 (PR #127782, qui récupère #127392 en conservant la paternité d’origine) fait en sorte que hermes config check signale les sélections obsolètes et aligne son jugement sur celui du runtime.

Un seul resolver, trois points d’appel

Le cœur structurel du patch consiste à regrouper la question ce nom enregistré correspond-il encore à un vrai toolset ? dans une seule fonction :

# hermes_cli/toolset_validation.py
def saved_toolset_resolver(config: dict) -> Callable[[str], bool]:
    """is_valid_toolset for a saved platform_toolsets list, mirroring what
    tools_config._get_platform_tools lets through."""

hermes config check comme hermes config migrate passent désormais par elle. Pourquoi est-ce important ? Parce qu’avant le correctif, migrate émettait des avertissements sur des noms de serveurs MCP et des ensembles plugin-plateforme pourtant correctement configurés — au point de vous suggérer de remplacer 'hermes-teams' par 'hermes-teams'. Une vérification de migration qui se contredit elle-même n’est que du bruit.

Les nouvelles règles valent la peine d’être retenues, car elles expliquent pourquoi votre config a cessé de crier :

  • Un serveur MCP configuré est considéré comme connu, même lorsqu’il déclare enabled: false. Il est inactif, pas mal orthographié. L’ancien code traitait inactif comme non reconnu et produisait un inutile unknown toolset — did you mean hermes-cli?.
  • known_plugin_toolsets ne prouve plus qu’un toolset existe. Cette structure enregistre ce qui avait été proposé à une plateforme au moment de l’enregistrement ; elle masquait donc exactement le cas pour lequel cette vérification existe : les noms laissés derrière par des plugins désinstallés.
  • La recherche de plugin et le scan du manifeste de plateforme ne s’exécutent que pour les noms que les vérifications moins coûteuses ne savent pas placer. Une config propre ne déclenche jamais la découverte de plugins : la vérification elle-même ne coûte donc rien.

Les plateformes désactivées : jugées comme le runtime les voit

La deuxième famille de fausses alertes venait de plugins.disabled. Le runtime se montre indulgent sur la forme — il n’honore qu’une liste — mais l’ancienne vérification jugeait la valeur YAML brute, si bien que cette ligne :

plugins:
  disabled: platforms/telegram   # a string, ignored by the runtime

était signalée comme platform disabled alors que le runtime continuait allègrement à la charger. La vérification passe désormais par le propre lecteur du runtime (_get_disabled_plugins()), donc une valeur qui n’est pas une liste n’est plus signalée comme désactivant quoi que ce soit.

Et lorsqu’elle signale quelque chose, elle vérifie si les identifiants requis de la plateforme sont réellement configurés :

platform plugin 'platforms/telegram' is disabled while its required credentials are configured.
Run `hermes plugins enable platforms/telegram` if you want it active.

Notez bien required : le critère est _platform_manifest_env_entries(optional=False), donc les variables optionnelles ne comptent jamais. Une plateforme désactivée sans token n’est pas signalée, et une variable d’environnement optionnelle ne peut pas être confondue avec un vous vouliez manifestement l’utiliser.

Un crash corrigé, et une vérification supprimée

Deux autres points qui semblent sans rapport, mais qui en ont un :

  • Un mcp_servers malformé ne fait plus planter la commande. Écrivez-le par accident sous forme de liste (mcp_servers: [a]) et l’ancien code levait une trace AttributeError ; désormais il s’exécute et rapporte le problème comme un diagnostic ordinaire. Une commande de diagnostic qui meurt est le genre d’échec le moins utile qui soit.
  • La vérification du toolsets de premier niveau a disparu. La PR d’origine validait aussi la clé toolsets de premier niveau, mais la CLI résout les toolsets à partir de --toolsets ou de platform_toolsets, et ne lit la clé de premier niveau que pour l’ancien opt-in kanban. Vérifier une clé que le runtime ne lit jamais ne fait que vous inventer du travail.

Le tableau ci-dessous provient de la propre campagne de validation du patch (vrai hermes config check, HERMES_HOME temporaire), l’ancien comportement à gauche :

Cas Avant Maintenant
platform_toolsets.cli liste un nom supprimé signalé signalé
toolset d’un plugin désinstallé, mémorisé dans known_plugin_toolsets silencieux signalé
serveur MCP avec enabled: false listé dans platform_toolsets unknown toolset, did you mean hermes-cli? silencieux
mcp_servers: [a] (mauvaise forme) trace AttributeError s’exécute
plugins.disabled: platforms/telegram (chaîne) avec un token configuré signalé comme désactivé (le runtime le charge toujours) silencieux
plugins.disabled: [platforms/telegram] avec un token configuré signalé signalé

Pourquoi votre ancienne config se lit toujours

Un vestige historique est facile à manquer : les premières versions de hermes config set enregistraient un argument de tableau JSON nu sous forme de chaîne, une config peut donc contenir ceci :

platform_toolsets:
  cli: '["browser", "terminal"]'    # a string, not a list

Le runtime, hermes doctor et hermes plugins enable lisent désormais tous cette section via un seul parser, ils s’accordent donc sur ce que vous avez configuré. Quand un lecteur isolé applique sa propre couche de compatibilité, les deux autres finissent par voir une configuration différente.

Quand la lancer

En bref : après avoir changé de machine, désinstallé un plugin, renommé un toolset, ou mis à jour depuis une version plus ancienne.

hermes config check      # signale les sélections enregistrées qui ne se résolvent plus
hermes config migrate    # migre et répare avec le même resolver
hermes tools             # choisir à nouveau les toolsets de façon interactive
hermes plugins enable platforms/telegram   # activer une plateforme signalée par la vérification

Trois jugements pratiques :

  1. Face à disabled while its required credentials are configured, demandez-vous si vous l’avez désactivée volontairement. La vérification prévoit ce cas — un identifiant configuré n’est qu’une raison de le mentionner. Si vous la voulez active, lancez le hermes plugins enable suggéré.
  2. Face à un nom de toolset qui ne se résout plus, ne le supprimez pas tout de suite. Vérifiez s’il appartenait à un plugin désinstallé ; si vous voulez toujours cette capacité, réinstallez le plugin. Supprimer le nom signifie simplement devoir le reconfigurer plus tard.
  3. Un config check propre n’est pas une config parfaite. Il juge seulement si les sélections enregistrées peuvent être honorées par le runtime — pas si votre modèle est un bon choix ni si vos clés sont à jour. Pour ce type de question, utilisez hermes doctor.

Et cette vérification ne devient utile que si la config elle-même reste propre : le guide de configuration MCP et l’article sur le catalogue de plugins disent la même chose — ajouter ou retirer des plugins ou des serveurs MCP doit s’accompagner d’un nettoyage de la config. Ce patch sort cette étape de votre mémoire pour en faire une commande.

En résumé

  • hermes config check signale désormais les noms de platform_toolsets enregistrés qui ne se résolvent plus, ainsi que les plateformes désactivées alors que leurs identifiants requis sont configurés.
  • Il partage un même resolver avec hermes config migrate, ce qui met fin aux avertissements qui se contredisent, comme suggérer 'hermes-teams' pour 'hermes-teams'.
  • Le jugement suit celui du runtime : un serveur MCP désactivé est connu, known_plugin_toolsets ne fait pas office de preuve, un plugins.disabled qui n’est pas une liste ne ment plus, les variables d’environnement optionnelles ne sont jamais comptées comme requises.
  • La découverte de plugins ne s’exécute qu’en cas de besoin : une config propre ne paie rien ; un mcp_servers malformé ne fait plus planter la commande.
  • La vérification de la clé toolsets de premier niveau a été supprimée parce que la CLI ne la lit jamais (ancien kanban uniquement).
  • Lancez-la après un changement de machine, la suppression de plugins ou une mise à jour, puis réparez avec hermes config migrate et hermes tools.

Utilisation complète sur hermes config et hermes plugins.