Last updated on

Hermes v0.19 Smart Approvals: configure 3 portões de segurança passo a passo, com comandos


O Hermes Agent v0.19.0 torna o Smart Approvals o comportamento padrão. Antes, quando o Agent queria executar um comando marcado, ele interrompia você para pedir confirmação linha por linha. Agora, um revisor LLM independente classifica cada comando como seguro, perigoso ou incerto — e apenas os incertos chegam até você.

Parece ótimo, mas em produção uma “aprovação automática” errada pode custar um banco de dados, uma configuração de produção ou uma chave de API vazada. Por isso, este artigo divide o Smart Approvals em três portões que você pode realmente implantar, mantendo a automação sem perder o controle. Todas as chaves de configuração abaixo foram verificadas contra o código-fonte do v0.19.0 e a documentação oficial — chaves que circulam pela internet como smart_approvals: true ou deny_rules: com campos pattern:/reason: não existem. O schema real está aqui.

Para o panorama completo do v0.19, consulte nossas notas de lançamento do v0.19.0 e a visão geral dos recursos do v0.19.

Portão 1: revisão prévia por LLM — aprovar automaticamente o seguro, rejeitar automaticamente o perigoso, escalar o incerto

Este é o padrão do v0.19. O Hermes não joga mais todo comando para você: um modelo de revisão interno o julga primeiro.

Lógica de decisão:

  • Seguro → aprovado automaticamente, sem interrupção
  • Perigoso → rejeitado automaticamente, com o motivo registrado
  • Incerto → escalado para você confirmar

Cada comando é revisado individualmente — uma aprovação anterior não dá passe livre para o próximo comando semelhante. Isso alivia a fadiga de aprovação, mas traz um novo problema: os critérios do revisor são uma caixa-preta para você. Por isso você precisa do Portão 2 como rede de segurança.

Aliás, o modelo de revisão é configurável — a chave real fica em auxiliary.approval (não em approvals.review_model, que não existe). Você vai vê-la no exemplo completo abaixo.

Portão 2: approvals.deny — linhas vermelhas que nem o modo yolo cruza

A configuração de linhas vermelhas que o v0.19 oferece no config.yaml é approvals.deny: uma lista de padrões glob fnmatch que bloqueiam comandos de terminal correspondentes incondicionalmente. Ela tem precedência sobre --yolo, /yolo e mode: off — ou seja, é a contraparte editável pelo usuário da lista de bloqueio rígida embutida do Hermes: “por mais confiante que o Agent esteja, este comando nunca deve ser executado”.

Exemplo de configuração:

# ~/.hermes/config.yaml
approvals:
  mode: smart        # smart | manual | off (smart é o padrão)
  deny:              # linhas vermelhas: padrões glob que bloqueiam incondicionalmente
    - "git push --force*"
    - "rm -rf /"
    - "*curl*|*sh*"
    - "kubectl delete namespace*"

Dicas:

  1. Liste as categorias de operações que você nunca quer executadas automaticamente — push forçado em branches compartilhados, exclusões recursivas, apagar namespaces de produção, escrever segredos via CLI etc.
  2. Os padrões são globs fnmatch sem distinção de maiúsculas/minúsculas, não regex. Coloque aspas no YAML — um * inicial sem aspas é erro de parsing.
  3. Em uma correspondência, o Agent recebe uma mensagem BLOCKED explícita e a instrução de não tentar novamente nem reformular o comando. Não existe campo reason na lista deny; para documentar a intenção, use um comentário YAML ao lado do padrão.
  4. Nota: approvals.deny corresponde a comandos de terminal (após normalização e desofuscação, então truques como r\m ou git st""atus não escapam), não a strings de chamadas de ferramentas — browser_*, file_* e afins estão fora do seu escopo.

Portão 3: intervenção humana com feedback aprendível — /deny é mais que um não

Quando a revisão prévia por LLM não decide e o comando chega até você, normalmente há duas opções: aprovar ou rejeitar. O v0.19 adiciona a rejeição com motivo: /deny <motivo> (/deny all <motivo> rejeita de uma vez todas as aprovações pendentes). O motivo é transmitido ao Agent e escrito no contexto, então na próxima vez ele ajusta o rumo em vez de tentar o mesmo comando de novo.

Exemplo CLI / TUI:

# O Hermes quer executar: docker system prune -a -f
# Você decide que não é o momento e rejeita com motivo
/deny isso vai limpar todas as imagens e pode quebrar outros contêineres

# O motivo fica no contexto; tentativas futuras evitarão comandos semelhantes

Se você só quer bloquear uma vez, uma rejeição sem motivo funciona. Mas para aprendizado de longo prazo, crie o hábito de rejeitar com motivo — uma rejeição com justificativa é feedback; uma rejeição seca é um muro.

E se o Agent sair completamente dos trilhos no meio de uma sequência, o /stop ainda encerra a execução atual na hora. Ele existe desde o v0.3, mas combina especialmente bem com o novo fluxo de aprovações do v0.19.

Exemplo completo de configuração com três portões

# ~/.hermes/config.yaml
approvals:
  mode: smart                   # smart | manual | off (smart é o padrão)
  timeout: 300                  # segundos de espera pela sua decisão; estourou = rejeição
  cron_mode: deny               # deny | approve — política para execuções cron não supervisionadas
  deny:                         # linhas vermelhas: bloqueio incondicional, mesmo sob yolo
    - "rm -rf /"
    - "git push --force*"
    - "kubectl delete namespace*"
    - "*curl*|*sh*"
  denial_breaker_threshold: 3   # parada forçada após N rejeições consecutivas (0 desativa)
  smart_policy: |               # opcional: anexe regras próprias ao LLM revisor
    Always ESCALATE commands that modify anything under /etc.

# Modelo de revisão (opcional): auto por padrão; recomenda-se um modelo rápido e barato
auxiliary:
  approval:
    provider: auto              # auto | openrouter | nous | codex | custom
    model: ""                   # vazio = padrão do provider; ex.: gemini-flash, classe haiku

Pontos fáceis de passar despercebidos:

  • denial_breaker_threshold (padrão 3): cada variante reformulada do mesmo comando rejeitada pelo revisor queima outra chamada de revisão. Quando as rejeições consecutivas atingem o limite, a mensagem de rejeição vira uma instrução de parada forçada — o Agent deve parar, reportar a operação bloqueada e deixar você executá-la manualmente ou via /approve. Qualquer aprovação zera o contador; coloque 0 para desativar.
  • smart_policy: anexa suas próprias regras ao system prompt do LLM revisor (o canal confiável, nunca misturado com o texto não confiável do comando), para ajustar o julgamento ao seu ambiente sem editar código.
  • O caminho de configuração é ~/.hermes/config.yaml (ou o config.yaml do seu Profile atual), não um .hermes/config.yaml no nível do projeto.

Reinicie o Hermes após salvar e verifique:

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

Quando os três portões trabalham juntos?

Cenário Portão 1: revisão LLM Portão 2: approvals.deny Portão 3: Humano
ls -la para inspecionar um diretório aprovado automaticamente sem correspondência sem interrupção
rm -rf / corresponde a deny bloqueado na hora, mesmo sob yolo nenhum humano necessário
docker system prune -a julgado incerto sem correspondência escalado para você
Variantes repetidas de um comando rejeitado limite do breaker atingido parada forçada; você executa

O ponto-chave: os portões se complementam — a revisão LLM absorve a carga rotineira, approvals.deny impõe restrições rígidas e o julgamento humano cobre as zonas cinzentas. Eles não se substituem.

Avançado: rigor de aprovação diferente por Profile

Cada Profile do Hermes tem seu próprio diretório de configuração (Profile padrão: ~/.hermes/config.yaml; Profiles nomeados: ~/.hermes/profiles/<name>/config.yaml), então você não precisa de uma chave profiles: aninhada na configuração — basta editar o arquivo do Profile correspondente. Por exemplo: mantenha os três portões no Profile de trabalho; use mode: off mais deny em um Profile pessoal; deixe apenas as linhas vermelhas deny em um Profile de CI/CD. Ao trocar de Profile, o Hermes carrega automaticamente o conjunto de regras correspondente.

Armadilhas comuns e solução de problemas

  1. As regras deny não têm efeito: verifique o caminho — a configuração do usuário é ~/.hermes/config.yaml (ou o config.yaml do seu Profile atual), não um .hermes/config.yaml no nível do projeto. Além disso, as mudanças só são carregadas após reiniciar o Hermes/gateway — não existe comando hermes config reload.
  2. A revisão prévia por LLM é muito lenta: aponte auxiliary.approval.model para um modelo leve (ex.: gemini-flash, classe haiku) em vez do revisor padrão.
  3. Confirmações ainda aparecem no modo yolo: o comando foi julgado incerto e não correspondeu a nenhum padrão de approvals.deny. Adicione um padrão para ele, ou aperte o revisor com smart_policy.
  4. Erros de parsing YAML: globs que começam com * devem ficar entre aspas (ex.: "*curl*|*sh*"); caso contrário, todo o bloco approvals falha no parsing e a configuração é ignorada.

Resumo

O Smart Approvals do Hermes v0.19 não entrega a autoridade ao LLM — ele deixa o LLM pré-filtrar enquanto a decisão final permanece com você. Três portões:

  • Portão 1: revisão prévia por LLM (approvals.mode: smart) para a rotina
  • Portão 2: approvals.deny como linhas vermelhas rígidas, eficazes até no modo yolo
  • Portão 3: /deny <motivo> e confirmação humana para as zonas cinzentas

Assim configurado, seu Agent não é nem um chato que pergunta tudo, nem um descontrolado que pode fazer tudo.

# As mudanças valem após reiniciar o Hermes (não há comando reload)
hermes config get approvals.mode    # verifique o modo
hermes config get approvals.deny    # verifique as linhas vermelhas

Quer mais guias de segurança e eficiência do Hermes? Consulte nosso guia de tratamento de erros e recuperação e o de tarefas longas sem travar. Para entender por que o Smart Approvals é o padrão, leia fadiga de aprovação: sem mais assentir a cada passo.