Se acabaron los bloqueos de 5 minutos esperando aprobaciones en Hermes desatendido: la nueva clave approvals.unattended_mode

A las 3 de la madrugada, tu trabajo webhook de vigilancia de memoria se topa con un “comando peligroso” — y entonces se bloquea durante 300 segundos enteros, porque la petición de aprobación sale hacia nadie que pueda responderla. Para colmo, esa sesión atascada retuvo durante más de cinco minutos un drenaje de gateway de un hermes update posterior. Ese es el incidente (issue #37284) que está detrás de una corrección integrada el 30 de agosto (PR #98558): Hermes gana una clave de config approvals.unattended_mode, con deny por defecto, de modo que las sesiones en plataformas programáticas desatendidas (webhook, msgraph_webhook, api_server) fallan al instante ante un comando peligroso en lugar de esperar a una aprobación que nadie puede aprobar. El cambio vive actualmente en main, aún sin publicar en una release.
El problema: aprobaciones enviadas a alguien que no existe
El sistema de aprobaciones de Hermes intercepta los comandos peligrosos (piensa en rm -rf, DROP DATABASE) y muestra una petición /approve esperando a un humano. Eso funciona bien en las plataformas de chat — alguien está delante de la pantalla. Pero webhook, msgraph_webhook y api_server vinculan HERMES_SESSION_PLATFORM igual que los gateways de chat, así que la lógica de aprobación los confundía con sesiones de gateway interactivas — salvo que estos adaptadores no tienen canal alguno para enviar una aprobación ni recibir una respuesta. Resultado: la sesión se bloqueaba 60-300 segundos y luego fallaba de todos modos con cierre forzado. Tiempo perdido, y nadie tuvo nunca la oportunidad de decir que sí.
La corrección: unattended_mode, deny por defecto
La corrección gira en torno a una nueva clave de config que replica la semántica de la cron_mode existente:
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(por defecto): una sesión desatendida que se topa con un comando peligroso se deniega al instante (0.04s medidos) con un mensaje accionable: “esta sesión se ejecuta en una plataforma desatendida (webhook) sin ningún usuario presente que pueda aprobarla; busca un enfoque alternativo que evite esta acción; para permitir acciones marcadas, defineapprovals.unattended_mode: approveen config.yaml”.approve: opta explícitamente por autoaprobar todos los comandos peligrosos en plataformas desatendidas (el comportamiento antiguo del PR #37317, ahora opt-in en lugar de por defecto).
El cambio cubre las tres rutas de guardia: _run_approval_gate (comandos normales), check_all_command_guards (comprobaciones de seguridad de tirith) y check_execute_code_guard (la herramienta execute_code) — lo que además tapa el agujero #87509, en el que execute_code de api_server disparaba una aprobación de gateway one-shot que nadie podía responder.
Cómo configurarlo
Quédate con el valor por defecto (recomendado): no hay nada que hacer, surte efecto después de actualizar. Para permitir un escenario desatendido concreto (pongamos un webhook privado de total confianza):
# 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
Extra: la misma corrección trajo también single_query_mode — las sesiones de hermes chat -q "...", que ejecutan un turno y salen sin ningún usuario esperando para responder a las peticiones, antes se atascaban de la misma manera y ahora deniegan al instante por defecto. Para el panorama completo de la política de aprobaciones, consulta nuestra guía de configuración de Smart Approvals y la guía contra la fatiga de aprobaciones.
Qué significa esto para tu automatización
Si ejecutas automatizaciones por webhook o API, el efecto es: el fallo pasa de “timeout de 5 minutos” a “denegación instantánea con un motivo claro”. El agente recibe la denegación de inmediato y puede intentar otra vía en lugar de quedarse colgado. Un apunte de comportamiento: el antiguo comportamiento implícito de “los comandos peligrosos se autoaprueban en estas sesiones” ha desaparecido — si dependías de él, define approvals.unattended_mode: approve de forma explícita. La estrategia de aprobaciones en el lado cron está cubierta en nuestra guía de automatización con cron, y la configuración de webhooks en la guía de notificaciones de negocio.
Cuándo puedes usarlo
El PR #98558 se integró el 30 de agosto y no está en v0.20.6 (etiquetada el 27 de agosto). Haz pull de la última main para probarlo ahora, o espera a la próxima release. Si alguna vez has tenido un trabajo de webhook atascado en silencio esperando una aprobación, esta actualización merece la pena.