Last updated on

Hermes v0.19 Smart Approvals: configura 3 compuertas de seguridad paso a paso, con comandos


Hermes Agent v0.19.0 convierte Smart Approvals en el comportamiento por defecto. Antes, cuando el Agent quería ejecutar un comando marcado, te interrumpía para pedirte confirmación línea por línea. Ahora un revisor LLM independiente clasifica cada comando como seguro, peligroso o incierto, y solo los inciertos llegan a ti.

Suena bien, pero en producción una «aprobación automática» equivocada puede costarte una base de datos, una configuración de producción o una clave API filtrada. Por eso este artículo descompone Smart Approvals en tres compuertas que puedes desplegar de verdad, para conservar la automatización sin perder el control. Todas las claves de configuración que aparecen abajo están verificadas contra el código fuente de v0.19.0 y la documentación oficial — claves que circulan por internet como smart_approvals: true o deny_rules: con campos pattern:/reason: no existen. El esquema real está aquí.

Para ver el panorama completo de v0.19, consulta nuestras notas de publicación de v0.19.0 y el resumen de funciones de v0.19.

Compuerta 1: revisión previa por LLM — autoaprobar lo seguro, autorrechazar lo peligroso, escalar lo incierto

Este es el comportamiento por defecto de v0.19. Hermes ya no te lanza cada comando: un modelo de revisión interno lo juzga primero.

Lógica de decisión:

  • Seguro → aprobado automáticamente, sin interrupciones
  • Peligroso → rechazado automáticamente con el motivo registrado
  • Incierto → escalado a ti para confirmación

Cada comando se revisa individualmente: una aprobación anterior no da paso libre al siguiente comando similar. Esto alivia la fatiga de aprobación, pero introduce un problema nuevo: los criterios del revisor son una caja negra para ti. Por eso necesitas la Compuerta 2 como red de seguridad.

Por cierto, el modelo de revisión es configurable — la clave real vive en auxiliary.approval (no en approvals.review_model, que no existe). Lo verás en el ejemplo completo más abajo.

Compuerta 2: approvals.deny — líneas rojas que ni el modo yolo puede cruzar

La configuración de líneas rojas que v0.19 te da en config.yaml es approvals.deny: una lista de patrones glob fnmatch que bloquean comandos de terminal coincidentes de forma incondicional. Tiene prioridad sobre --yolo, /yolo y mode: off — es decir, es la contraparte editable por el usuario de la lista negra integrada de Hermes: «por muy seguro que esté el Agent, este comando nunca debe ejecutarse».

Configuración de ejemplo:

# ~/.hermes/config.yaml
approvals:
  mode: smart        # smart | manual | off (smart es el valor por defecto)
  deny:              # líneas rojas: patrones glob que bloquean incondicionalmente
    - "git push --force*"
    - "rm -rf /"
    - "*curl*|*sh*"
    - "kubectl delete namespace*"

Consejos:

  1. Enumera las categorías de operaciones que nunca quieres que se ejecuten automáticamente — push forzado a ramas compartidas, borrados recursivos, eliminar namespaces de producción, escribir secretos vía CLI, etc.
  2. Los patrones son globs fnmatch insensibles a mayúsculas, no regex. Ponles comillas en YAML — un * inicial sin comillas es un error de parseo.
  3. Ante una coincidencia, el Agent recibe un mensaje BLOCKED explícito y se le indica que no reintente ni reformule el comando. No hay campo reason en la lista deny; si quieres documentar la intención, usa un comentario YAML junto al patrón.
  4. Nota: approvals.deny coincide con comandos de terminal (tras normalización y desofuscación, así que trucos como r\m o git st""atus no lo esquivan), no con cadenas de llamadas de herramientas — browser_*, file_* y similares quedan fuera de su alcance.

Compuerta 3: intervención humana con feedback aprendible — /deny es más que un no

Cuando la revisión previa por LLM no decide y el comando llega a ti, normalmente tienes dos opciones: aprobar o rechazar. v0.19 añade el rechazo con motivo: /deny <motivo> (/deny all <motivo> rechaza de una vez todas las aprobaciones pendientes). El motivo se transmite al Agent y se escribe en el contexto, así que la próxima vez ajusta el rumbo en lugar de reintentar el mismo comando.

Ejemplo CLI / TUI:

# Hermes quiere ejecutar: docker system prune -a -f
# Decides que no es el momento y rechazas con motivo
/deny esto eliminará todas las imágenes y podría romper otros contenedores

# El motivo queda en el contexto; los intentos posteriores evitarán comandos similares

Si solo quieres bloquearlo una vez, un rechazo sin motivo funciona. Pero para aprendizaje a largo plazo, acostúmbrate a rechazar con motivo — un rechazo razonado es feedback; un rechazo a secas es un muro.

Y si el Agent se descarrila por completo en mitad de una secuencia, /stop sigue cortando la ejecución al instante. Existe desde v0.3, pero combina especialmente bien con el nuevo flujo de aprobaciones en v0.19.

Ejemplo completo de configuración de tres compuertas

# ~/.hermes/config.yaml
approvals:
  mode: smart                   # smart | manual | off (smart es el valor por defecto)
  timeout: 300                  # segundos de espera por tu aprobación; agotado = rechazo
  cron_mode: deny               # deny | approve — política para ejecuciones cron no supervisadas
  deny:                         # líneas rojas: bloqueo incondicional, incluso bajo yolo
    - "rm -rf /"
    - "git push --force*"
    - "kubectl delete namespace*"
    - "*curl*|*sh*"
  denial_breaker_threshold: 3   # parada dura tras N rechazos consecutivos (0 desactiva)
  smart_policy: |               # opcional: añade reglas personalizadas al LLM revisor
    Always ESCALATE commands that modify anything under /etc.

# Modelo de revisión (opcional): por defecto auto; se recomienda un modelo rápido y barato
auxiliary:
  approval:
    provider: auto              # auto | openrouter | nous | codex | custom
    model: ""                   # vacío = predeterminado del provider; p. ej. gemini-flash, clase haiku

Puntos fáciles de pasar por alto:

  • denial_breaker_threshold (por defecto 3): cada vez que el revisor rechaza una variante reformulada del mismo comando, se quema otra llamada de revisión. Al llegar a N rechazos consecutivos, el mensaje de rechazo se convierte en una instrucción de parada dura — el Agent debe detenerse, informar de la operación bloqueada y dejar que la ejecutes manualmente o con /approve. Cualquier aprobación reinicia el contador; pon 0 para desactivarlo.
  • smart_policy: añade tus propias reglas al system prompt del LLM revisor (el canal de confianza, nunca mezclado con el texto no fiable del comando), para ajustar su criterio a tu entorno sin tocar código.
  • La ruta de configuración es ~/.hermes/config.yaml (o el config.yaml de tu Profile actual), no un .hermes/config.yaml a nivel de proyecto.

Reinicia Hermes tras guardar y verifica:

hermes config get approvals.mode
hermes config get approvals.deny

¿Cuándo trabajan juntas las tres compuertas?

Escenario Compuerta 1: revisión LLM Compuerta 2: approvals.deny Compuerta 3: Humano
ls -la para inspeccionar un directorio aprobado automáticamente sin coincidencia sin interrupción
rm -rf / coincide con deny bloqueado al instante, incluso bajo yolo no se necesita humano
docker system prune -a juzgado incierto sin coincidencia escalado a ti
Variantes repetidas de un comando rechazado se alcanza el umbral del breaker parada dura; lo ejecutas tú

La clave: las compuertas se complementan — la revisión LLM absorbe la carga rutinaria, approvals.deny impone restricciones duras y el juicio humano cubre las zonas grises. No se sustituyen entre sí.

Avanzado: distinta rigidez de aprobación por Profile

Cada Profile de Hermes tiene su propio directorio de configuración (Profile por defecto: ~/.hermes/config.yaml; Profiles con nombre: ~/.hermes/profiles/<name>/config.yaml), así que no necesitas una clave profiles: anidada en tu configuración — basta con editar el archivo del Profile correspondiente. Por ejemplo: mantén las tres compuertas en el Profile de trabajo; usa mode: off más deny en un Profile personal; deja solo las líneas rojas deny en un Profile de CI/CD. Al cambiar de Profile, Hermes carga automáticamente el conjunto de reglas correspondiente.

Problemas comunes y solución

  1. Las reglas deny no surten efecto: comprueba la ruta — la configuración de usuario es ~/.hermes/config.yaml (o el config.yaml de tu Profile actual), no un .hermes/config.yaml a nivel de proyecto. Además, los cambios solo se cargan tras reiniciar Hermes/gateway — no existe el comando hermes config reload.
  2. La revisión previa por LLM es demasiado lenta: apunta auxiliary.approval.model a un modelo ligero (p. ej. gemini-flash, clase haiku) en lugar del revisor por defecto.
  3. Siguen apareciendo confirmaciones en modo yolo: el comando fue juzgado incierto y no coincidió con ningún patrón de approvals.deny. Añade un patrón para él, o ajusta el revisor con smart_policy.
  4. Errores de parseo YAML: los globs que empiezan por * deben ir entre comillas (p. ej. "*curl*|*sh*"); si no, todo el bloque approvals falla al parsear y la configuración se ignora.

Resumen

Smart Approvals en Hermes v0.19 no entrega la autoridad al LLM — deja que el LLM pre-filtre mientras la decisión final sigue en tus manos. Tres compuertas:

  • Compuerta 1: revisión previa por LLM (approvals.mode: smart) para la rutina
  • Compuerta 2: approvals.deny como líneas rojas duras, efectivas incluso en modo yolo
  • Compuerta 3: /deny <motivo> y confirmación humana para las zonas grises

Así configurado, tu Agent no es ni un pesado que lo pregunta todo ni un descontrolado que puede hacerlo todo.

# Los cambios se aplican al reiniciar Hermes (no hay comando reload)
hermes config get approvals.mode    # verifica el modo
hermes config get approvals.deny    # verifica las líneas rojas

¿Quieres más guías de seguridad y eficiencia de Hermes? Consulta nuestra guía de manejo de errores y recuperación y la de tareas largas sin quedarse atascado. Para entender por qué Smart Approvals es el comportamiento por defecto, lee fatiga de aprobación: no más asentir en cada paso.