8 min de leitura

Falhas parciais em comandos SSH: pare de fazer os agentes repetirem o trabalho

Falhas parciais em comandos SSH exigem reconciliação, não novas tentativas às cegas. Registre códigos de saída, checkpoints, recibos e o estado remoto observado para agentes de IA.

Falhas parciais em comandos SSH: pare de fazer os agentes repetirem o trabalho

Um agente de IA deve tratar um comando SSH com falha como uma transição de estado desconhecida, não como permissão para executar o mesmo texto novamente. Um comando pode criar um usuário, recarregar um serviço e depois falhar ao gravar um arquivo final. Uma nova tentativa às cegas pode criar uma conta duplicada, substituir uma configuração editada manualmente ou transformar uma implantação recuperável em uma indisponibilidade.

O conselho comum, «verifique o código de saída», é necessário, mas incompleto. O status de saída descreve como um processo terminou. A recuperação exige um registro do que o processo concluiu, do estado que o host informa agora e da operação que o agente pretendia realizar. Coloque esses dados em um recibo de comando durável e faça o agente reconciliar o estado antes de agir novamente.

Uma falha SSH deixa três incógnitas diferentes

Uma ação SSH com falha pode significar que o shell remoto falhou, que a conexão falhou ou que o controlador parou de esperar. Esses casos exigem tratamentos diferentes, mas os agentes costumam reduzir os três a «o comando falhou».

Considere um script de implantação remoto que executa estas operações em ordem:

  1. Grava um novo arquivo da aplicação em um diretório de releases.
  2. Altera um link simbólico current para apontar para esse release.
  3. Reinicia o serviço.
  4. Executa uma verificação de integridade e retorna um valor diferente de zero porque a verificação encontra um erro temporário de dependência.

O release está ativo mesmo que o comando tenha retornado falha. Repetir o script pode ser inofensivo se todas as operações tolerarem repetição. Com mais frequência, porém, o script cria um novo diretório de release, trunca um log, faz a rotação de uma credencial ou executa uma migração. O código de saída, sozinho, não resolve o que aconteceu.

O segundo caso é pior: uma interrupção do transporte SSH. O processo local pode receber 255 depois de uma falha de rede enquanto o shell remoto continua executando. Um timeout do controlador cria o mesmo problema. O controlador sabe apenas que não recebeu uma resposta final. Ele não sabe se o destino recebeu a solicitação, se o shell foi iniciado ou se o processo ainda está fazendo alterações.

Essa distinção muda a próxima ação do agente:

  • Uma saída remota confirmada com um recibo pede recuperação baseada no checkpoint que falhou.
  • Uma falha de transporte pede observação antes de qualquer alteração.
  • Um timeout do controlador pede observação e, se necessário, um procedimento explícito de cancelamento, não uma solicitação duplicada.

Não chame os três casos de tentativas novamente. Uma nova tentativa é uma operação com uma regra conhecida de repetição segura. Um estado remoto desconhecido precisa de reconciliação.

O status de saída informa sobre um processo, não sobre uma transação

Um código de saída SSH fornece evidências úteis, mas não é um registro de commit de banco de dados. O manual do OpenSSH diz que ssh termina com o status de saída do comando remoto ou com 255 se ocorrer um erro. Essa formulação estabelece um limite que muitos sistemas de automação ignoram: um status remoto descreve o comando quando o SSH o recebe, enquanto 255 cobre o caminho de erro do próprio SSH.

Um código de saída zero também precisa ser interpretado. No shell POSIX, o status de uma lista sequencial simples normalmente vem do último comando. Este script pode informar sucesso depois de uma falha importante:

install -m 0644 app.conf /etc/myapp/app.conf
systemctl restart myapp
logger -t deploy "deployment finished"

Se install falhar, mas systemctl restart e logger retornarem zero, o status final do script será zero. O agente vê sucesso e pode afirmar falsamente que a configuração foi alterada. Um echo done final cria a mesma mentira.

Os pipelines acrescentam outro caminho de falha. No Bash, o Bash Reference Manual documenta que o status de um pipeline é o status do último comando, a menos que pipefail esteja habilitado. Este comando pode produzir um resultado zero se a extração terminar corretamente depois de receber dados úteis:

curl --fail --silent https://example.invalid/build.tar.gz | tar -xz -C /srv/myapp

Use um interpretador explícito e declare o comportamento necessário:

#!/usr/bin/env bash
set -Eeuo pipefail

curl --fail --silent --show-error "$archive_url" | tar -xz -C "$release_dir"

O -e faz o Bash parar diante de muitas falhas não tratadas, -u rejeita variáveis não definidas e pipefail preserva a falha de membros anteriores do pipeline. A opção E permite que uma armadilha ERR se aplique dentro de funções e substituições de comando. Essas configurações melhoram o relato de falhas. Elas não tornam uma sequência atômica.

Esse último ponto importa. O set -e entra em ação depois que uma operação retorna um erro. Ele não consegue desfazer um diretório criado por um comando anterior nem restaurar um serviço reiniciado anteriormente. Também tem exceções que surpreendem as pessoas: comandos testados por if, comandos no lado esquerdo de && ou || e vários contextos compostos nem sempre causam a saída do shell. Escreva verificações explícitas ao redor das ações cuja falha altera a recuperação.

Defina o limite da operação antes de escrever o comando

Um agente não consegue recuperar uma instrução vaga como «implante o serviço». O comando remoto precisa de uma operação nomeada, com uma pós-condição que um observador possa testar.

Para uma alteração de release, a operação poderia ser: «Definir /srv/myapp/current como o release 2025-04-18.3 e confirmar que o serviço ativo informa esse release». Para uma alteração de banco de dados, poderia ser: «Aplicar a migração add_invoice_index exatamente uma vez e confirmar que existe um registro dessa migração». O texto do comando é um detalhe de implementação. A operação e sua pós-condição determinam se a recuperação pode prosseguir.

Divida uma operação em limites irreversíveis ou visíveis externamente. Um checkpoint útil não precisa corresponder a cada linha do shell. Registre um checkpoint depois de uma alteração de estado que mude a próxima decisão. Em uma implantação, isso pode incluir arquivo verificado, diretório de release preenchido, link simbólico alterado, serviço reiniciado e estado de integridade observado.

Evite a recomendação popular, mas errada, de tornar todo comando remoto «idempotente» e então tentar novamente para sempre. A idempotência se aplica a uma operação específica e a um estado desejado declarado. mkdir -p /srv/app pode ser repetido. useradd deploy só pode ser repetido se o agente verificar se a conta existente tem o UID, o grupo, o diretório pessoal e o shell esperados. ALTER TABLE pode falhar na segunda execução ou, pior, uma migração escrita de forma vaga pode aplicar uma alteração relacionada duas vezes.

Um comando pode ser seguro para repetir enquanto o fluxo de trabalho ao redor dele não é. Reiniciar um serviço pode ser repetível, mas reiniciá-lo no meio da cópia de uma configuração pode expor um arquivo incompleto. Coloque a validação de estado ao lado da ação. Não peça ao agente que a deduza de uma regra genérica.

Para cada operação, defina quatro campos antes de conceder acesso:

  • Um ID de operação que permaneça igual durante a recuperação.
  • Uma pós-condição desejada que um comando somente leitura possa inspecionar.
  • Checkpoints que descrevam as alterações de estado concluídas.
  • Uma ação de recuperação para cada checkpoint incompleto.

O ID da operação não é um detalhe cosmético. Se o controlador criar um novo identificador a cada tentativa, o destino não conseguirá distinguir uma continuação de uma nova solicitação. É assim que acontecem migrações repetidas e provisionamentos duplicados.

Grave um recibo antes e depois de cada alteração de estado

Um recibo durável transforma uma falha parcial em um evento que pode ser inspecionado. Grave-o no host de destino antes da primeira alteração, atualize-o depois de cada checkpoint importante e faça as atualizações de forma atômica.

O script Bash a seguir é propositalmente simples. Ele implanta um release já preparado, alterando um link simbólico e reiniciando um serviço do sistema. Não pretende resolver todos os métodos de implantação. Ele mostra a mecânica de recibos de que um agente precisa.

#!/usr/bin/env bash
set -Eeuo pipefail

operation_id=${1:?operation ID required}
release=${2:?release path required}
service=${3:?service name required}
state_dir=/var/lib/agent-ops
receipt="$state_dir/$operation_id.receipt"
tmp="$receipt.$$"

mkdir -p "$state_dir"
chmod 0700 "$state_dir"

write_receipt() {
  cat >"$tmp" <<EOF
operation_id=$operation_id
release=$release
service=$service
checkpoint=$1
updated_at=$(date -u +%Y-%m-%dT%H:%M:%SZ)
EOF
  chmod 0600 "$tmp"
  mv -f "$tmp" "$receipt"
}

fail() {
  status=$?
  write_receipt "failed:$status"
  exit "$status"
}
trap fail ERR

if [[ -f "$receipt" ]]; then
  . "$receipt"
  case "$checkpoint" in
    complete)
      printf 'operation already complete: %s\n' "$operation_id"
      exit 0
      ;;
    switched|restarted)
      printf 'operation requires reconciliation: %s\n' "$checkpoint" >&2
      exit 75
      ;;
  esac
fi

[[ -d "$release" ]]
write_receipt "release_verified"

ln -sfn "$release" /srv/myapp/current
write_receipt "switched"

systemctl restart "$service"
write_receipt "restarted"

active_target=$(readlink -f /srv/myapp/current)
[[ "$active_target" == "$release" ]]
systemctl is-active --quiet "$service"
write_receipt "complete"
printf 'operation complete: %s\n' "$operation_id"

O arquivo temporário e o mv são importantes. Em um único sistema de arquivos, a renomeação substitui o recibo em uma operação, então um leitor recebe o recibo completo anterior ou o novo recibo completo, não um arquivo pela metade. Mantenha o diretório de estado gravável apenas pela conta responsável pela operação. Se um usuário não confiável puder editar recibos, a lógica de recuperação do agente aceitará ficção como evidência.

A armadilha ERR registra o status de saída quando o Bash trata uma falha. Ela não pode ser executada quando a máquina perde energia, recebe um sinal que não pode ser capturado ou morre abruptamente. Por isso, o script registra o progresso depois de cada alteração de estado concluída, em vez de depender apenas de uma armadilha final.

Não use o source de formatos arbitrários de recibo como neste pequeno exemplo, a menos que o diretório tenha propriedade e permissões rigorosas. Em produção, prefira JSON analisado por um parser conhecido ou um formato de linhas fixo que rejeite campos inesperados. O exemplo usa source apenas em um arquivo que acabou de criar dentro de um diretório protegido, para manter o código do shell legível.

O recibo deve declarar fatos observados, não intenções otimistas. checkpoint=switched significa que o comando do link simbólico retornou com sucesso. Não significa que o serviço carregou o novo release. complete vem depois das verificações explícitas da pós-condição. Essa distinção impede que um agente trate um comando registrado como uma operação concluída.

Faça o agente pedir reconciliação, não um novo comando

Confirme a chamada de recuperação de risco
Exija aprovação para cada uso de uma chave SSH sensível antes que o agente faça outra alteração.

Depois de um resultado diferente de zero, o agente deve preservar o ID original da operação e executar primeiro verificações somente leitura. Ele não deve gerar novamente o comando de implantação com pequenas mudanças de redação. Uma nova redação não cria uma nova transição de estado.

Para o recibo de implantação acima, um comando de reconciliação pode inspecionar tanto o registro durável quanto a pós-condição ativa:

operation_id='release-7f3b'
cat "/var/lib/agent-ops/$operation_id.receipt"
printf 'current='
readlink -f /srv/myapp/current
systemctl is-active myapp
systemctl show myapp --property=ActiveState --property=SubState --no-pager

A saída tem um formato que o agente pode analisar sem fingir que prosa é evidência:

operation_id=release-7f3b
release=/srv/myapp/releases/2025-04-18.3
service=myapp
checkpoint=restarted
updated_at=2025-04-18T14:05:12Z
current=/srv/myapp/releases/2025-04-18.3
active
ActiveState=active
SubState=running

Aqui, o link simbólico aponta para o release solicitado e o serviço está ativo, mas o recibo parou em restarted. O processo remoto pode ter morrido depois de reiniciar o serviço e antes de gravar complete. O procedimento de recuperação pode executar novamente as verificações da pós-condição e, se elas passarem, gravar um recibo de conclusão por meio de um comando de recuperação com escopo restrito. Ele não deve reiniciar a implantação desde o começo.

Um protocolo útil do controlador mantém solicitação, resultado e recuperação separados. Por exemplo:

{
  "operation_id": "release-7f3b",
  "action": "deploy_release",
  "target": "app-01",
  "arguments": {
    "release": "/srv/myapp/releases/2025-04-18.3",
    "service": "myapp"
  },
  "mode": "reconcile"
}

O destino deve aceitar mode: reconcile apenas para inspeção somente leitura ou para um caminho de conclusão previamente escrito que verifique a pós-condição. Não permita que o agente envie uma string arbitrária de shell marcada como reconcile. Esse rótulo não tem significado de segurança quando o comando pode alterar qualquer coisa.

O código de saída 75 do exemplo é um sinal deliberado de falha temporária. O número exato importa menos que um contrato documentado: o agente entende que deve observar o estado, não enviar uma nova tentativa automática. Reserve resultados distintos do controlador para completed, reconcile_required, rejected_before_start e transport_unknown. Um único campo booleano success destrói as informações necessárias à recuperação.

Timeouts e desconexões exigem prova do estado remoto

Um timeout é uma observação local. O cliente local desistiu de esperar, mas não necessariamente interrompeu o comando remoto. Tratar um timeout como cancelamento é uma das formas mais rápidas de duplicar uma ação remota.

O controlador pode reduzir a ambiguidade tornando as operações de execução única. Antes de uma alteração, o script remoto cria um bloqueio exclusivo associado ao ID da operação. Uma tentativa posterior encontra o bloqueio e escolhe entre esperar, inspecionar o processo ou informar que a recuperação precisa de uma decisão humana.

Para um bloqueio simples no nível do host, flock costuma ser suficiente:

exec 9>/var/lib/agent-ops/deploy.lock
if ! flock -n 9; then
  printf 'another deployment operation is active\n' >&2
  exit 75
fi

Isso protege apenas os processos que respeitam o mesmo bloqueio. Não protege contra um administrador que execute um procedimento de implantação separado e não elimina todos os erros de projeto dos seus scripts. Para uma migração de banco de dados, use o bloqueio consultivo ou de migração próprio do banco quando disponível. Para uma ação de API, use um token de idempotência aceito por essa API. O bloqueio deve ficar junto do estado que protege.

Quando o controlador se reconectar depois de um timeout, inspecione nesta ordem:

  1. Leia o recibo do ID original da operação.
  2. Verifique se o processo original ainda está em execução, caso a operação tenha um marcador de processo confiável.
  3. Teste a pós-condição da operação com comandos somente leitura.
  4. Escolha uma ação explícita de recuperação ou escale o caso quando as observações divergirem.

Não use a presença do processo como único sinal. Um processo pode existir enquanto está bloqueado por uma dependência externa, e a ausência do processo diz pouco sobre o que ele alterou antes de terminar. O recibo e a pós-condição fornecem evidências mais fortes.

O multiplexamento SSH exige o mesmo cuidado. Uma conexão mestre pode ocultar a falha de um comando individual atrás de um transporte compartilhado, e um controlador pode confundir um canal fechado com uma operação com falha. Capture stdout, stderr, o status de saída SSH bruto, o horário de início e o horário de término do comando remoto como um único registro de ação. Preserve o stderr mesmo que o agente o resuma. Os dados brutos costumam mostrar se o Bash rejeitou uma variável não definida, se um comando remoto terminou com 75 ou se o próprio SSH retornou 255.

Algumas alterações exigem compensação, não novas tentativas

Veja qual processo retoma o trabalho
Autorize um novo processo de agente uma vez e revogue a sessão imediatamente se a recuperação parecer errada.

Muitas operações não podem ser tornadas seguras para repetição depois do fato. Rotação de credenciais, limpeza destrutiva, chamadas de API semelhantes a pagamentos e migrações de esquema exigem um procedimento de compensação ou uma decisão do operador.

Considere um fluxo de rotação de credencial. O comando pode criar uma nova credencial, atualizar um serviço, verificar o acesso e depois revogar a credencial antiga. Se falhar depois da criação, mas antes da atualização do serviço, tentar novamente pode criar outra credencial e deixar vários segredos ativos. O recibo deve registrar imediatamente o identificador da credencial recém-criada. A recuperação pode então verificar qual credencial o serviço usa e decidir se deve atualizar, revogar ou manter a nova.

Não coloque material secreto no recibo, na saída padrão ou no contexto do agente. Armazene apenas um identificador não secreto ou uma impressão digital, desde que o próprio identificador não conceda acesso. O processo de recuperação precisa saber qual objeto existe, não seu valor privado.

As migrações de banco de dados trazem outra armadilha. A tabela de histórico de um framework de migrações pode informar que uma migração nomeada foi concluída, mas talvez não descreva um preenchimento de dados interrompido que tenha sido executado fora da transação do framework. Escreva as migrações de modo que a alteração do esquema, o progresso do preenchimento e o marcador de conclusão tenham verificações separadas. Se o banco aceitar DDL transacional para sua operação, use esse recurso, mas não presuma que toda instrução DDL ou efeito externo será revertido com a transação.

Para ações visíveis externamente, prefira um token de idempotência da API a tentativas de dedução baseadas em SSH. Se o host remoto chamar uma API que aceite uma chave de idempotência, persista esse token no recibo antes da solicitação. Durante a recuperação, consulte a API pelo mesmo token ou envie novamente a solicitação com o mesmo token, de acordo com a semântica documentada da API. Gerar um novo token a cada tentativa do agente anula o recurso.

A regra é direta: se você não consegue explicar como determinar se uma ação aconteceu, não dê a um agente autônomo permissão para repeti-la. Peça a uma pessoa que inspecione o destino ou redesenhe a operação em torno de um registro de estado durável.

Os scripts de shell precisam de um contrato que o agente possa impor

Um script destinado ao uso por agentes deve expor um contrato restrito e legível por máquina. Agentes são ruins em reconstruir estados a partir de logs muito verbosos, saída colorida de terminal e uma mistura de avisos e mensagens de sucesso.

Use categorias de saída estáveis, um único objeto de resultado e IDs de operação explícitos. Por exemplo, escreva uma linha JSON final somente depois que o comando souber o resultado:

{"operation_id":"release-7f3b","outcome":"reconcile_required","checkpoint":"switched","exit_code":75}

Mantenha a saída diagnóstica comum no stderr e reserve o stdout para o registro de resultado, se o controlador puder impor essa convenção. Um comando shell que imprime banners, barras de progresso e JSON no stdout convida a falhas de análise. Se o comando transmitir progresso útil, grave primeiro o recibo durável e faça o controlador tratar o registro estruturado final como uma conveniência, não como o único registro.

Não permita que o agente escolha nomes arbitrários de checkpoints, caminhos de recibos, nomes de serviços ou interpretadores. Exponha um comando revisado com argumentos restritos. Um wrapper que aceite shell livre depois de -- apenas esconde o problema atrás de um rótulo mais limpo.

O contrato do comando também deve informar quais falhas podem ser repetidas com segurança. Por exemplo, um download de pacote pode retornar um erro de rede repetível antes de alterar o host. Uma troca de link simbólico seguida de uma conexão perdida não pode ser repetida até que a reconciliação verifique o destino do link. Essa classificação pertence à pessoa responsável pela operação, que entende seus efeitos, não a um modelo tentando adivinhar a partir do stderr.

Use um host de teste e interrompa o script em cada checkpoint. Envie um sinal de término durante a extração do arquivo, depois da troca do link simbólico, durante a reinicialização e depois da verificação final de integridade. Em seguida, execute o caminho de reconciliação e verifique se ele chega à decisão correta. Se você nunca interrompeu uma operação de propósito, não sabe se o comportamento de novas tentativas é seguro.

A autorização e os registros de auditoria devem preservar a história da recuperação

Verifique o histórico da recuperação
Verifique a cadeia de auditoria do Sallyport offline com sp audit verify, sem precisar da chave do cofre.

Um agente precisa de autoridade para executar uma leitura de recuperação, mas uma leitura que leve a uma nova alteração ainda deve seguir o limite normal de autorização. Não esconda uma segunda implantação dentro de um comando chamado status.

O Sallyport pode manter a credencial SSH fora do agente e registrar tanto a execução do agente quanto cada ação, ajudando a preservar quem autorizou uma tentativa de recuperação e qual comando foi enviado. Seu histórico de auditoria não substitui o recibo no destino: o registro de auditoria pode provar que uma solicitação de ação ocorreu, enquanto o recibo e a pós-condição explicam o estado resultante no destino.

Mantenha esses registros separados nas anotações do incidente. A identidade da sessão informa qual processo do agente tinha permissão. O registro da ação individual informa qual comando foi executado contra qual host e o que retornou. O recibo no destino informa onde a operação parou. Quando uma implantação dá errado, juntar esses fatos em uma única conversa desperdiça as evidências necessárias.

Exija confirmação por chamada para operações com efeitos irreversíveis, especialmente quando a reconciliação puder levar à exclusão de credenciais, ao reparo de esquema ou à limpeza. Essa aprovação extra é útil quando as evidências do agente entram em conflito: por exemplo, o recibo informa que uma troca foi concluída, mas o serviço ativo ainda informa um release antigo. Esse é um ponto de decisão, não uma nova tentativa de rotina.

Um bom projeto de recuperação torna barata a ação conservadora. Dê ao agente um comando de reconciliação somente leitura, um ID de operação durável e um resultado de escalonamento definido. Assim, uma desconexão produz um registro que pode ser inspecionado, não uma segunda tentativa que altera o sistema novamente.

Comece corrigindo o comando que as pessoas já repetem

Encontre o comando SSH que sua equipe executa novamente depois de um timeout ou de uma mensagem vermelha de implantação. Adicione um ID de operação, um recibo protegido e uma verificação de pós-condição somente leitura antes de mudar qualquer outra coisa.

Depois, interrompa-o de propósito. Se o caminho de recuperação não consegue dizer se a primeira tentativa alterou o estado, ele não está pronto para um agente autônomo. Reescreva a operação até que a resposta venha do host de destino, não da confiança em um código de saída.

FAQ

O que um código de saída SSH realmente informa a um agente de IA?

O SSH normalmente retorna o status de saída do comando remoto. Isso informa se o shell do comando relatou sucesso, mas não prova que todas as operações anteriores deixaram o host inalterado. Trate um status diferente de zero como um sinal para inspecionar o estado registrado antes de tentar novamente.

Quando é seguro tentar novamente um comando SSH com falha de forma automática?

Só tente novamente de forma automática quando todas as operações anteriores à falha forem idempotentes e você puder verificar sua pós-condição. Atualizar metadados de pacotes e reiniciar um serviço identificado podem se enquadrar nessa regra; criar contas, alterar regras de firewall ou migrar dados geralmente exige reconciliação primeiro.

O set -e impede falhas parciais em comandos SSH?

Não. O set -e interrompe o shell em muitas condições de erro, mas tem exceções deliberadas em condicionais, pipelines e substituições de comando. Além disso, não consegue desfazer uma operação concluída antes de um comando posterior falhar.

Por que os scripts remotos devem usar pipefail?

Use set -o pipefail no Bash quando a falha de qualquer membro de um pipeline deve fazer o script falhar. Sem ele, curl | tar pode informar o status de tar mesmo quando curl falhou, dando ao agente uma visão perigosamente incompleta da execução.

O que um recibo de comando SSH deve conter?

Armazene um identificador da execução, a operação pretendida, cada checkpoint concluído, o status de saída e dados observados suficientes para apoiar a recuperação. Mantenha o recibo no host remoto e também no registro de ações do agente, porque uma conexão SSH interrompida pode impedir o retorno da saída.

Como impedir que uma tentativa do agente execute a mesma alteração duas vezes?

Use um ID de execução estável fornecido pelo controlador, grave os checkpoints de forma atômica em um diretório pertencente ao root e faça o comando carregar qualquer recibo anterior antes de agir. Um ID aleatório criado novamente a cada tentativa não diferencia uma repetição de uma nova solicitação.

O que um agente deve fazer depois de um timeout SSH?

Um timeout significa que o controlador parou de esperar, não que o processo remoto parou. Antes de tentar novamente, inspecione um recibo durável, o status do processo, o arquivo de bloqueio, o estado do serviço ou o registro da transação no host de destino.

O que significa o código de saída SSH 255?

O OpenSSH usa o status de saída do comando remoto quando recebe esse status e normalmente retorna 255 para erros próprios. Os agentes devem preservar o código de saída bruto e o stderr, distinguindo a falha do script remoto de uma falha de transporte antes de escolher a recuperação.

Como um agente pode saber se uma alteração remota já aconteceu?

Não decida apenas pelo código de saída. Verifique a pós-condição relevante: consulte o gerenciador de pacotes, inspecione o serviço do sistema, leia a tabela de migrações ou compare a configuração desejada com a ativa. A operação correta de recuperação depende desse estado observado.

As ações SSH de um agente de IA devem ter registros separados para sessão e comando?

Registre tanto a identidade da sessão quanto cada ação SSH individual. A aprovação da sessão informa qual processo do agente recebeu autorização, enquanto o registro da chamada informa qual comando foi executado, contra qual destino e com qual resultado. Misturar esses registros dificulta a reconstrução de um incidente.

Sallyport

O Sallyport executa chamadas de API e comandos SSH pelo seu agente de IA. As chaves ficam em um cofre local no seu Mac; você aprova cada execução e toda ação vai para um registro selado.

© 2026 Sallyport · Código aberto sob Apache-2.0 · Oleg Sotnikov