Fini les blocages d'approbation de 5 minutes pour les Hermes sans surveillance : la nouvelle clé approvals.unattended_mode


À 3 heures du matin, votre job webhook de surveillance mémoire tombe sur une « commande dangereuse » — et stagne pendant 300 secondes entières, parce que l’invite d’approbation part vers personne pour y répondre. Pire, cette session coincée a retenu un drain de gateway hermes update ultérieur pendant plus de cinq minutes. C’est l’incident (issue #37284) derrière un correctif fusionné le 30 août (PR #98558) : Hermes gagne une clé de config approvals.unattended_mode, par défaut deny, pour que les sessions sur les plateformes programmatiques sans surveillance (webhook, msgraph_webhook, api_server) échouent instantanément sur une commande dangereuse au lieu d’attendre une approbation que personne ne peut approuver. Le changement vit actuellement sur main, pas encore dans une release.

Le problème : des approbations envoyées à quelqu’un qui n’existe pas

Le système d’approbation de Hermes intercepte les commandes dangereuses (pensez rm -rf, DROP DATABASE) et lève une invite /approve en attente d’un humain. Ça fonctionne bien sur les plateformes de chat — quelqu’un est devant l’écran. Mais webhook, msgraph_webhook et api_server lient HERMES_SESSION_PLATFORM de la même façon que les gateway de chat, donc la logique d’approbation les a prises pour des sessions gateway interactives — sauf que ces adaptateurs n’ont aucun canal pour envoyer une approbation ou recevoir une réponse. Résultat : la session bloquait 60 à 300 secondes puis échouait en mode fermé de toute façon. Du temps perdu, et personne n’a jamais eu la chance de dire oui.

Le correctif : unattended_mode, deny par défaut

Le correctif s’articule autour d’une nouvelle clé de config qui reflète la sémantique existante de cron_mode :

approvals:
  mode: smart              # smart | manual | off
  timeout: 300
  cron_mode: deny          # cron jobs hitting a dangerous command: deny | approve
  single_query_mode: deny  # hermes chat -q one-shot sessions: deny | approve
  unattended_mode: deny    # webhook/API unattended sessions: deny | approve (new)
  • deny (défaut) : une session sans surveillance qui tombe sur une commande dangereuse est refusée instantanément (0,04 s mesurées) avec un message actionnable — « cette session tourne sur une plateforme sans surveillance (webhook) sans utilisateur présent pour l’approuver ; trouvez une approche alternative qui évite cette action ; pour autoriser les actions signalées, définissez approvals.unattended_mode: approve dans config.yaml ».
  • approve : opte explicitement pour l’auto-approbation de toutes les commandes dangereuses sur les plateformes sans surveillance (l’ancien comportement du PR #37317, désormais opt-in au lieu d’être le défaut).

Le changement couvre les trois chemins de garde : _run_approval_gate (commandes ordinaires), check_all_command_guards (contrôles de sécurité tirith) et check_execute_code_guard (l’outil execute_code) — ce qui referme aussi la faille #87509 où api_server execute_code déclenchait une approbation gateway one-shot que personne ne pouvait répondre.

Comment le configurer

Restez sur le défaut (recommandé) : rien à faire, il prend effet après la mise à jour. Pour autoriser un scénario sans surveillance précis (disons, un webhook privé entièrement de confiance) :

# Via the CLI (equivalent to editing config.yaml)
hermes config set approvals.unattended_mode approve
# Or edit ~/.hermes/config.yaml directly
approvals:
  unattended_mode: approve

Bonus : le même correctif a aussi livré single_query_mode — les sessions hermes chat -q "...", qui tournent un tour puis sortent sans utilisateur pour répondre aux invites, stagnaient de la même façon et passent désormais par défaut à un deny instantané. Pour le tableau complet de la politique d’approbation, voir notre guide de configuration Smart Approvals et le guide anti-fatigue d’approbation.

Ce que cela signifie pour votre automatisation

Si vous faites tourner de l’automatisation via webhook ou API, l’effet est le suivant : l’échec passe de « timeout de 5 minutes » à « refus instantané avec une raison claire ». L’agent reçoit le refus immédiatement et peut essayer une autre voie au lieu de rester suspendu. Une note comportementale : l’ancien comportement implicite « les commandes dangereuses sont auto-approuvées dans ces sessions » a disparu — si vous comptiez dessus, définissez explicitement approvals.unattended_mode: approve. La stratégie d’approbation côté cron est couverte dans notre guide d’automatisation cron, et la mise en place webhook dans le guide de notifications métier.

Quand vous pouvez l’utiliser

Le PR #98558 a été fusionné le 30 août et n’est pas dans v0.20.6 (taggé le 27 août). Tirez le dernier main pour l’essayer maintenant, ou attendez la prochaine release. Si vous avez déjà eu un job webhook silencieusement coincé sur une approbation, celui-ci vaut le coup de mettre à jour.