Chega de esperas de 5 minutos por aprovação no Hermes não supervisionado: a nova chave approvals.unattended_mode


Às 3 da manhã, seu job de webhook de monitoramento de memória encontra um “comando perigoso” — e então trava por 300 segundos completos, porque o prompt de aprovação é enviado para um lugar onde não há ninguém para respondê-lo. Pior: essa sessão travada segurou um drain de gateway do hermes update posterior por mais de cinco minutos. Esse é o incidente (issue #37284) por trás de uma correção mesclada em 30 de agosto (PR #98558): o Hermes ganha uma chave de config approvals.unattended_mode, com padrão deny, para que sessões em plataformas programáticas não supervisionadas (webhook, msgraph_webhook, api_server) falhem instantaneamente diante de um comando perigoso, em vez de esperar uma aprovação que ninguém pode dar. A mudança vive atualmente na main, ainda sem release.

O problema: aprovações enviadas a alguém que não existe

O sistema de aprovações do Hermes intercepta comandos perigosos (pense em rm -rf, DROP DATABASE) e levanta um prompt de /approve esperando um humano. Isso funciona bem em plataformas de chat — alguém está na tela. Mas webhook, msgraph_webhook e api_server vinculam HERMES_SESSION_PLATFORM da mesma forma que os gateways de chat, então a lógica de aprovação os confundiu com sessões interativas de gateway — exceto que esses adaptadores não têm canal algum para enviar uma aprovação ou receber uma resposta. Resultado: a sessão ficava bloqueada por 60-300 segundos e, no fim, falhava em modo fechado mesmo assim. Tempo desperdiçado, e ninguém jamais teve a chance de dizer sim.

A correção: unattended_mode, negar por padrão

A correção gira em torno de uma nova chave de config que espelha a semântica do 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 (padrão): uma sessão não supervisionada que encontra um comando perigoso é negada instantaneamente (0,04s medidos) com uma mensagem acionável — “esta sessão roda em uma plataforma não supervisionada (webhook) sem usuário presente para aprová-la; encontre uma abordagem alternativa que evite esta ação; para permitir ações sinalizadas, defina approvals.unattended_mode: approve no config.yaml”.
  • approve: opta explicitamente por aprovar automaticamente todos os comandos perigosos em plataformas não supervisionadas (o comportamento antigo do PR #37317, agora opt-in em vez de padrão).

A mudança cobre os três caminhos de guarda: _run_approval_gate (comandos regulares), check_all_command_guards (verificações de segurança do tirith) e check_execute_code_guard (a tool execute_code) — o que também fecha o buraco #87509, em que o execute_code do api_server disparava uma aprovação de gateway one-shot que ninguém podia responder.

Como configurar

Fique com o padrão (recomendado): nada a fazer, ele entra em vigor após o upgrade. Para permitir um cenário não supervisionado específico (digamos, um webhook privado totalmente confiável):

# 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

Bônus: a mesma correção também trouxe o single_query_mode — sessões de hermes chat -q "...", que rodam um turno e saem sem nenhum usuário esperando para responder prompts, costumavam travar do mesmo jeito e agora têm deny instantâneo por padrão. Para o panorama completo da política de aprovações, veja nosso guia de configuração do Smart Approvals e o guia contra a fadiga de aprovações.

O que isso significa para sua automação

Se você roda automação por webhook ou API, o efeito é: a falha muda de “timeout de 5 minutos” para “negação instantânea com um motivo claro”. O agente recebe a negação imediatamente e pode tentar outro caminho em vez de ficar pendurado. Uma nota comportamental: o antigo comportamento implícito de “comandos perigosos são auto-aprovados nessas sessões” acabou — se você dependia dele, defina approvals.unattended_mode: approve explicitamente. A estratégia de aprovação no lado dos cron jobs está coberta no nosso guia de automação com cron, e a configuração de webhooks no guia de notificações de negócio.

Quando você pode usar

O PR #98558 foi mesclado em 30 de agosto e não está no v0.20.6 (tag de 27 de agosto). Puxe a main mais recente para testar agora, ou espere o próximo release. Se você já teve um job de webhook preso silenciosamente numa aprovação, este é um motivo para atualizar.