8 min de leitura

Subprocessos órfãos de agentes podem manter credenciais ativas

Subprocessos órfãos de agentes podem manter credenciais e conexões ativas depois de um tempo limite. Conheça a limpeza de grupos de processos, a revogação do estado da execução e os métodos de auditoria.

Subprocessos órfãos de agentes podem manter credenciais ativas

Um agente de IA cujo tempo limite expirou não necessariamente parou. Se o wrapper do shell, o compilador, o auxiliar HTTP ou o comando SSH tiver criado um processo filho antes do tempo limite, esse filho pode continuar depois que o PID do pai desaparecer. Se ele herdou uma credencial utilizável ou uma conexão já autenticada, o tempo limite não encerrou a autoridade que você achava ter revogado.

Já vi notas de incidentes que começam com «o agente foi encerrado às 14:03» e terminam com uma chamada de API às 14:11. Em geral, ninguém descobriu uma exploração engenhosa. O executor encerrou um processo, enquanto o trabalho útil já havia passado para outro. A limpeza de processos parece uma tarefa operacional até que um agente autônomo possa usar credenciais de produção. A partir daí, essa tarefa passa a fazer parte do limite de segurança.

A morte do processo pai não encerra o trabalho

Um processo filho pode sobreviver ao pai porque o kernel acompanha os processos de forma independente, e não como extensões descartáveis de um comando de shell. Quando um processo pai termina, o sistema operacional reatribui seus filhos a um processo de reaproveitamento do sistema ou a um supervisor. O filho mantém seu próprio PID, memória, descritores de arquivo, sockets, diretório atual e, muitas vezes, seu ambiente.

Esse comportamento é legítimo. Sistemas de compilação o utilizam. Multiplexadores de terminal também. Gerenciadores de serviços dependem dele. O erro é tratar um PID pai como o limite de execução de uma execução de agente.

Considere uma cadeia conhecida:

agent-runner (PID 4102)
  shell tool wrapper (PID 4131)
    deployment script (PID 4140)
      ssh helper (PID 4144)

O executor chega ao prazo e envia um sinal ao PID 4102. Se o shell ou o script de implantação não terminarem junto com ele, o restante da cadeia pode continuar em execução. Um caso ainda mais complicado surge quando o script inicia um trabalho em segundo plano com &, usa nohup, chama um gerenciador de serviços ou pede a um host remoto para iniciar um trabalho. O processo pai pode terminar corretamente enquanto o filho já se tornou independente.

Por isso, um subprocesso órfão de agente é mais do que um consumidor de CPU esquecido. Ele é a continuação não observada de uma decisão que uma pessoa ou um agendador acreditava ter terminado. O dano depende do que o processo ainda consegue acessar, mas a falha começa antes: o executor escolheu a unidade errada para encerrar.

A especificação POSIX documenta os elementos por trás desse comportamento em suas interfaces de processos e controle de tarefas. Um grupo de processos é um conjunto de processos relacionados com um único ID de grupo. Os sinais podem ser enviados ao grupo em vez de a um único membro. Uma sessão agrupa um ou mais grupos de processos e normalmente mantém uma relação com um terminal controlador. Esses são conceitos distintos do kernel, e tratar os termos como equivalentes produz um código de limpeza frágil.

Um tempo limite precisa encerrar uma unidade de contenção

Um tempo limite só é seguro quando atinge uma unidade de contenção estabelecida antes do início do agente. Para uma árvore de comandos local, essa unidade costuma ser um grupo de processos dedicado. O executor registra imediatamente o ID do grupo e envia sinais para esse grupo quando o prazo termina.

A sequência importa. Não espere a limpeza para descobrir os filhos. Até lá, o processo pai original pode ter desaparecido, a relação de PPID pode já ser enganosa e outra execução pode ter começado.

Um caminho prático para o tempo limite tem cinco ações:

  1. Crie um grupo dedicado ou um trabalho pertencente a um supervisor antes de iniciar o agente.
  2. Registre o ID da execução, o PID, o PGID, o horário de início, o comando e o prazo em um único registro.
  3. Quando o tempo limite expirar, marque a execução como expirada antes de enviar um sinal, para que novas ações não sejam confundidas com trabalho aprovado.
  4. Envie TERM à unidade de contenção registrada, aguarde um breve período de tolerância definido e envie KILL somente aos sobreviventes.
  5. Capture o resultado e armazene os horários dos sinais, o estado de saída e os PIDs sobreviventes.

O registro vem primeiro porque a limpeza pode disputar com o encerramento rápido de um processo. Se seu log disser apenas «agente encerrado», ele não poderá responder qual processo foi encerrado, quais filhos compartilhavam seu grupo ou se algum filho escapou antes do sinal.

No macOS, examine os identificadores em vez de confiar na exibição de uma árvore de processos. Este comando mostra os campos que explicam a maioria das falhas de tempo limite:

ps -axo pid,ppid,pgid,sid,lstart,etime,command

Uma execução expirada saudável poderia deixar uma saída com este formato antes da limpeza:

  PID  PPID  PGID   SID  STARTED                  ELAPSED COMMAND
 4102  3988  4102  4102  Thu Jul 24 14:00:02 2026   00:31 agent-runner ...
 4131  4102  4102  4102  Thu Jul 24 14:00:02 2026   00:31 /bin/sh -c ...
 4144  4131  4102  4102  Thu Jul 24 14:00:04 2026   00:29 ssh ...

Os valores são ilustrativos, não um padrão para codificar diretamente. O fato importante é que a execução tem um PGID conhecido, 4102. A limpeza envia o sinal a esse grupo, e não apenas ao PID 4102. Um destino negativo instrui kill a enviar o sinal a um grupo de processos:

kill -TERM -4102

Verifique a sintaxe para o runtime de linguagem e o sistema operacional que você usa. Alguns wrappers interpretam mal números negativos ou tratam um argumento extra como uma opção de comando. Não crie um limite de segurança em torno de uma linha de comando que você nunca testou sob um tempo limite real.

Um sinal enviado ao grupo também tem limites. Um filho pode chamar setsid, criar um novo grupo de processos, entregar o trabalho a outro serviço ou iniciar um processo em uma máquina remota. A disciplina de grupos fecha a fuga local comum, mas não todas as fugas possíveis. O executor precisa tratar essas transições como entregas explícitas, com seu próprio cancelamento e histórico de auditoria.

Grupos de processos, sessões e credenciais resolvem problemas diferentes

Um grupo de processos fornece um destino local para sinais. Uma sessão oferece um limite mais amplo e pode isolar o controle de tarefas do terminal. Nenhum dos dois revoga uma credencial que um processo copiou para a memória ou gravou no disco. Esses são controles separados e precisam de evidências separadas.

Essa distinção costuma desaparecer porque a falha parece um único evento: o tempo limite do agente expira e uma chamada posterior é bem-sucedida. A camada de limpeza pergunta: «Quais processos locais devem parar?». O tratamento de credenciais pergunta: «Qual processo ainda pode autorizar esta ação externa?». A auditoria pergunta: «Podemos provar qual ação ocorreu depois que a aprovação terminou?». Um grupo de processos responde apenas à primeira pergunta.

As variáveis de ambiente são o exemplo clássico de uma passagem inadequada. Se um executor exporta API_TOKEN, todos os descendentes o recebem, a menos que um processo posterior limpe o ambiente. Um filho pode copiar o token, passá-lo a outro programa ou manter uma conexão autenticada aberta. Substituir uma variável de ambiente depois que o processo pai começou não recolhe os bytes já herdados.

Arquivos e sockets são igualmente importantes. Um processo pode herdar um descritor de arquivo aberto que aponta para um arquivo de credencial, um socket HTTPS conectado com estado de sessão ou um socket de agente SSH. Um processo em segundo plano pode continuar usando o descritor depois que o processo pai termina. A opção close-on-exec ajuda a impedir a herança acidental durante um novo exec, mas não faz nada quando o filho já tem o descritor ou quando o programa o encaminha deliberadamente.

O SSH exige atenção especial. Uma chave privada carregada em um auxiliar local, um socket de agente SSH, uma conexão de controle multiplexada e um comando remoto têm quatro ciclos de vida diferentes. Encerrar o processo pai local pode deixar uma conexão existente ou um comando remoto em execução. Se o agente puder invocar SSH arbitrário, o executor precisa saber se autorizou uma chamada de auxiliar local, um canal autenticado ou um trabalho remoto. Chamar os três de «comando SSH» esconde o limite que você precisa controlar.

O padrão mais seguro passa uma solicitação de ação, não o segredo bruto. O processo pede a um componente de autoridade que execute uma solicitação HTTP ou uma operação SSH específica. Esse componente mantém o segredo, decide se a execução atual pode usá-lo, realiza a ação e devolve o resultado. Um filho que escapou ainda pode repetir solicitações enquanto sua execução continuar autorizada, portanto o componente de autoridade também precisa entender expiração ou revogação.

O Sallyport segue essa separação nos canais HTTP e SSH compatíveis: o agente solicita a ação pelo shim MCP, enquanto o aplicativo mantém o material de API ou SSH e executa a ação, em vez de passar o segredo ao processo do agente. Isso não substitui a limpeza de processos, mas elimina a forma mais fácil de herança de credenciais.

Executar em segundo plano é uma saída, não um detalhe inofensivo do shell

A falha de limpeza mais comum começa com uma conveniência do shell. Alguém escreve command &, inicia um pipe, usa nohup ou executa um runtime de linguagem que cria workers. O comando pai parece concluído ou atinge o tempo limite, e o worker continua.

Um pipeline de shell merece atenção especial. Um executor pode executar /bin/sh -c 'generator | uploader' e registrar o PID do shell. O shell tem processos filhos para os dois lados do pipeline. Dependendo de como o executor cria o grupo, encerrar apenas o shell pode deixar o gerador ou o uploader ativos. Se o uploader possuir uma credencial e uma conexão de rede, esse é exatamente o processo que você precisava encerrar.

nohup é pior do que muita gente admite. Ele impede que um processo receba um sinal de hangup, mas não torna o processo confiável nem o anuncia ao executor. Em automações, geralmente significa que alguém quer que o trabalho sobreviva ao terminal ou ao processo pai. Isso pode ser válido para um serviço gerenciado, mas o trabalho precisa passar para um supervisor que seja responsável por ele e registre seu ciclo de vida. Ele não deve ficar dentro de uma chamada de ferramenta do agente por acidente.

Processos filhos destacados criam outro tipo de problema. No Node.js, spawn com detached: true dá deliberadamente ao filho um novo grupo de processos e uma nova sessão em sistemas semelhantes ao Unix. Esse comportamento pode ser útil para um aplicativo de desktop que precisa sobreviver ao seu lançador. É uma escolha ruim dentro de um executor de agentes porque impede o encerramento normal do grupo pelo executor.

import { spawn } from "node:child_process";

const child = spawn("/bin/sh", ["-c", "sleep 600"], {
  detached: true,
  stdio: "ignore"
});
child.unref();

Esse trecho é um caso de teste de limpeza, não um padrão de execução para copiar em um executor de agentes. Ele cria um filho que deixa de compartilhar o grupo de processos normal do pai. Se uma estrutura de ferramentas puder executar código assim, a limpeza por grupo de processos, sozinha, não dará uma garantia completa. Restrinja a execução destacada, intercepte-a no limite da ferramenta ou execute a ferramenta em uma contenção mais forte do sistema operacional.

A recomendação popular de «simplesmente encerrar a árvore de processos» também falha quando isso significa percorrer recursivamente os PPIDs. Os PPIDs descrevem um momento, não um limite durável de pertencimento. A relação pode mudar. Um filho pode criar outro processo entre a sua busca e o envio do sinal. Um descendente pode sair da árvore. Registre uma identidade de grupo ou de trabalho no lançamento e transforme qualquer saída dessa identidade em uma operação deliberada e auditável.

Não faça a limpeza pelo nome do comando

Revogue uma sessão desaparecida
Revogue uma execução do agente no diário de sessões, sem depender do PID do processo pai.

pkill e a correspondência ampla por nome parecem atraentes porque são curtos. Também são inadequados para execuções concorrentes de agentes. pkill ssh pode encerrar uma conexão interativa sem relação com o caso. pkill python pode remover a ferramenta local de um desenvolvedor. A correspondência por texto dos argumentos pode não encontrar um processo que mudou seus argumentos ou pode encontrar por engano um processo de outra execução.

Use o nome do comando apenas como pista de investigação. Para aplicar a regra, use um limite de propriedade.

Um executor que conhece um grupo de processos pode primeiro inspecionar seus membros. No macOS, filtre a tabela de processos usando o número registrado, e não um nome de executável presumido:

ps -axo pid,ppid,pgid,sid,etime,command | awk '$3 == 4102 || NR == 1'

A primeira coluna é o PID, a segunda é o PPID e a terceira é o PGID neste formato de comando. Em código de produção, evite analisar texto voltado para pessoas quando sua linguagem puder chamar APIs nativas de processos. Para um terminal de operador, essa saída oferece uma verificação rápida e legível antes da escolha do sinal.

Depois, envie o sinal ao grupo e inspecione novamente:

kill -TERM -4102
sleep 2
ps -axo pid,ppid,pgid,sid,etime,command | awk '$3 == 4102 || NR == 1'

Se ainda houver membros, descubra o motivo antes de enviar KILL por reflexo. Um processo bloqueado em trabalho de kernel não interrompível exige uma investigação diferente daquela de um processo que ignorou TERM. Um processo com outro PGID não sobreviveu ao sinal por acaso: ele atravessou o limite. Isso é evidência de uma decisão de projeto, de um comportamento da estrutura ou de uma ferramenta mal-intencionada.

Depois do período de tolerância definido, KILL é apropriado para processos locais que continuam no grupo registrado e não devem terminar o trabalho. Não prometa uma limpeza cuidadosa quando o agente já ultrapassou sua janela de autoridade. A tolerância serve para fechar arquivos e registrar o status, não para continuar indefinidamente um trabalho externo.

Contêineres e gerenciadores de serviços podem oferecer uma propriedade melhor do que um grupo de processos bruto quando você controla o ambiente de execução. Os fluxos de trabalho de agentes em desktops macOS não recebem automaticamente cgroups do Linux, portanto não importe recomendações sobre cgroups como se elas se aplicassem sem mudanças. Em um Mac, um grupo dedicado de processos filhos, permissões restritas para ferramentas e um contrato explícito para trabalhos remotos costumam ser a base. Se você precisa de limites de recursos ou de contenção completa dos descendentes, use um ambiente de execução que realmente ofereça esses controles.

A auditoria precisa sobreviver ao processo pai

Não é possível reconstruir uma ação que escapou a partir do texto final do agente. O processo pai pode ter terminado antes de liberar os logs, e um filho que continuou em execução não tem motivo para enviar um relatório. Construa a auditoria em torno de eventos imutáveis observados fora do processo do agente.

Para cada execução, registre pelo menos os seguintes campos antes de permitir trabalho externo:

{
  "run_id": "run-7f3c",
  "started_at": "2026-07-24T14:00:02Z",
  "deadline_at": "2026-07-24T14:00:32Z",
  "parent_pid": 4102,
  "process_group": 4102,
  "approval_identity": "signed agent process identity",
  "state": "active"
}

O registro da ação precisa incluir o ID da execução, uma sequência da ação, o horário em que o gateway a aceitou, o canal, a identidade do destino e o resultado. Nunca registre por padrão valores bearer brutos, chaves privadas, cabeçalhos de autorização ou corpos completos de solicitações. Um registro que expõe a credencial enquanto documenta seu uso cria um segundo incidente.

Quando o tempo limite expirar, acrescente uma transição de estado antes de enviar qualquer sinal:

{
  "run_id": "run-7f3c",
  "event": "deadline_expired",
  "observed_at": "2026-07-24T14:00:32Z",
  "process_group": 4102,
  "signal": "TERM"
}

Agora sua investigação tem uma pergunta objetiva com uma resposta objetiva: uma ação externa começou depois de deadline_expired? Se o gateway aceitar uma ação depois desse evento, ele não aplicou o estado da execução ou o chamador não carregava a identidade esperada pelo gateway. Se uma ação começou antes da expiração, mas terminou depois, diga isso claramente. Início e conclusão são horários diferentes, e misturá-los faz um trabalho comum em andamento parecer uma fuga.

Mantenha o horário de parede para as pessoas e um valor monotônico de tempo decorrido para ordenar eventos dentro de uma máquina. Os relógios de parede podem mudar por sincronização ou ajuste manual. Durante um incidente, você não precisa de uma aula sobre medição do tempo; precisa de dados suficientes para não afirmar que uma ação ocorreu depois que o processo pai morreu quando os relógios discordam.

Os diários de sessões e atividades do Sallyport separam a visão da execução das chamadas individuais, e seu log criptografado, encadeado por hash, pode ser verificado offline com sp audit verify. Isso é útil quando um processo pai desaparece, porque o histórico de auditoria não depende de o agente fornecer voluntariamente sua própria versão dos fatos.

Um histórico de auditoria é evidência, não contenção. Ele informa que uma chamada foi feita e apoia a revisão posterior. Não encerra um processo órfão local, não recolhe dados que já foram devolvidos a ele nem cancela um comando remoto que não tenha um caminho de cancelamento. Trate essas funções como responsabilidades diferentes e torne cada uma visível no registro da execução.

Reconstitua a falha na ordem certa

Leve a autoridade para além do executor
Os agentes solicitam ações HTTP e SSH pelo shim MCP, enquanto o Sallyport as executa diretamente.

Quando encontrar um possível órfão, preserve os fatos antes de limpar o cenário. Um kill -9 apressado pode ser justificável para interromper um trabalho prejudicial, mas pode apagar as relações entre processos que você precisa entender para corrigir o executor. Capture primeiro um instantâneo dos processos quando a situação permitir.

Comece pelo registro da execução expirada. Anote o PID do processo pai, o PGID ou a identidade do trabalho, o horário de início, o prazo e todos os sinais enviados. Depois, capture o instantâneo atual dos processos. No macOS, compare PID, PPID, PGID, SID, tempo decorrido e comando. Um órfão costuma ter PPID 1 ou um supervisor, mas não use isso como único teste. Um processo pode continuar sendo um risco enquanto seu PPID ainda aponta para outro lugar.

Em seguida, classifique o que escapou:

  • Um processo no PGID original sobreviveu ao sinal esperado.
  • Um processo tem um novo PGID ou SID e, portanto, se desconectou localmente.
  • Um processo local fez uma solicitação para iniciar um trabalho remoto, e o trabalho remoto continuou.
  • Uma credencial ou um canal autenticado continuou utilizável depois que a execução expirou.

Cada classe exige uma correção diferente. A primeira aponta para o tratamento de sinais ou para o momento da limpeza. A segunda aponta para um mecanismo de desconexão não aprovado. A terceira exige um ID de trabalho remoto e um protocolo de cancelamento. A quarta exige que a autoridade de ação vincule as solicitações a uma execução atual, em vez de confiar que o processo pai se comportará corretamente.

Depois, relacione os registros de ações à linha do tempo. Não comece lendo as transcrições do agente. Procure solicitações aceitas depois da expiração, destinos diferentes da instrução original, chamadas repetidas que continuam um lote e chamadas que o processo pai não poderia ter relatado porque já havia terminado. A transcrição pode explicar a intenção depois. Ela não prova que uma solicitação de rede ocorreu ou não.

Por fim, decida se a credencial precisa ser trocada ou revogada. Se nenhum segredo bruto entrou no agente e o gateway de ações rejeitou chamadas após a expiração, o risco restante pode estar limitado aos dados ou às alterações já concluídas. Se o filho herdou um token bearer, uma chave privada, acesso ao agente SSH ou um canal administrativo conectado, presuma que ele ainda pode agir até que você desative essa autoridade. É nesse ponto que as equipes perdem tempo discutindo se o processo «provavelmente» fez alguma coisa. Se não puder comprovar que ele perdeu o acesso, remova o acesso.

Um teste de falha deve tornar o órfão evidente

Pare de exportar tokens de API
O Sallyport injeta credenciais bearer, basic ou de cabeçalho personalizado somente quando executa a solicitação HTTP.

Um mecanismo de teste de tempo limite precisa conter um teste que falhe claramente quando um filho sobrevive. Testar apenas se o processo pai retorna um tempo limite quase não prova nada.

Crie um dispositivo de teste que inicie um processo pai e um filho no mesmo grupo registrado. O filho deve aguardar tempo suficiente para que o mecanismo exceda o tempo limite do pai. Antes de bloquear, o pai deve informar o PID e o grupo do filho. Depois do tempo limite, confirme que nenhum dos dois processos existe e que o log de ações de teste não contém chamadas aceitas depois do registro de expiração.

Este dispositivo de shell mostra o formato do problema:

#!/bin/sh
(
  trap 'exit 0' TERM INT
  sleep 600 &
  child=$!
  printf 'parent=%s child=%s pgid=' "$$" "$child"
  ps -o pgid= -p "$$" | tr -d ' '
  wait "$child"
)

Execute-o usando o mesmo código de lançamento que o executor de agentes usa, e não em um terminal interativo que forneça silenciosamente um comportamento diferente de controle de tarefas. Capture os IDs impressos, force o prazo e verifique a tabela de processos. Se o filho continuar, você aprendeu algo específico: o lançamento não criou o grupo que você supunha ou o sinal do tempo limite não o atingiu.

Repita o teste para as ferramentas que seus agentes realmente invocam. Wrappers de shell, APIs de processos filhos do Node, chamadas de subprocessos do Python, gerenciadores de pacotes, compiladores e auxiliares SSH fazem escolhas diferentes sobre grupos, descritores e encaminhamento de sinais. Você não precisa de centenas de testes. Precisa de um teste destrutivo para cada padrão de lançador que possa criar descendentes.

Acrescente um segundo dispositivo de teste que tente se desconectar. O teste pode usar uma chamada que crie uma sessão ou uma opção de runtime que crie um filho destacado. O resultado esperado deve ser rejeição, propriedade do supervisor ou um evento de registro explícito. Um sucesso silencioso é um defeito, porque informa ao agente que ele pode mover o trabalho para fora do limite do tempo limite.

Não pare nos PIDs locais. Se o agente puder iniciar um trabalho remoto, faça o lado remoto devolver um identificador de trabalho e teste o cancelamento depois do tempo limite local. O estado desejado não é «o cliente SSH saiu». O estado desejado é «o trabalho remoto identificado por esta execução foi interrompido ou seu trabalho restante tem um responsável documentado».

A aprovação deve expirar antes do processo

A aprovação humana de uma execução de agente vale pouco se um filho puder usá-la depois que a execução for declarada encerrada. Vincule a autoridade para ações externas a uma identidade e a um estado de execução que o componente de autoridade verifique em cada solicitação. Quando o executor marcar a execução como expirada, novas ações dessa execução devem falhar mesmo que um processo órfão local ainda tenha tempo de CPU.

Esse projeto não significa pedir a uma pessoa aprovação para cada comando de shell. Significa que o componente capaz de gastar autoridade sabe quando uma execução terminou. Esse componente pode fornecer à execução um identificador de curta duração, rejeitá-lo depois da revogação e registrar a recusa. O encerramento do grupo de processos limita o dano local, enquanto o limite da ação limita as consequências de uma disputa durante a limpeza.

Mantenha a aprovação por ação para operações que exigem esse controle, mas não confunda aprovação com supervisão. Uma pessoa pode aprovar um processo de agente assinado no início de uma sessão. Se um descendente continuar depois que o agente terminar, ele excedeu a duração aprovada da execução, mesmo tendo herdado o mesmo contexto local. O sistema precisa tornar essa condição aplicável, em vez de depender da boa vontade do processo filho.

O executor também deve distinguir o cancelamento de uma execução do cancelamento de um efeito externo. Uma solicitação cancelada pode já ter chegado à API. Um cliente SSH encerrado pode já ter iniciado um comando remoto. Registre a solicitação de cancelamento, a saída local observada e qualquer confirmação devolvida pelo sistema externo como eventos separados. Essa linguagem é menos reconfortante do que «cancelado», mas informa aos operadores o que realmente se sabe.

A primeira correção que eu faria em um executor de agentes é pequena e pouco glamourosa: criar e registrar um grupo dedicado de processos no lançamento, encerrá-lo no caminho do tempo limite e confirmar o resultado em um teste de falha. Combine isso com um limite de ações que recuse a execução após a expiração. Quando esses dois fatos forem verdadeiros, um órfão será um incidente que você consegue conter e explicar, em vez do medo vago de que algo ainda possa estar em execução.

FAQ

O que é um subprocesso órfão em uma execução de agente de IA?

Um processo órfão é aquele cujo processo pai original terminou, fazendo o sistema operacional reatribuí-lo a outro processo. Ele ainda pode continuar em execução, manter conexões de rede abertas e usar qualquer material de credencial que tenha recebido. O tempo limite do processo pai só prova que um PID terminou.

Encerrar um agente de IA também encerra seus processos filhos?

Somente se o executor iniciar o agente em um grupo de processos isolado ou em um limite de contenção equivalente e depois encerrar todo esse limite. Encerrar apenas o PID do processo pai deixa intactos os processos filhos que foram criados de forma independente. Teste isso com um processo filho que continue dormindo depois que o pai terminar.

Devo usar um grupo de processos ou uma sessão para os tempos limite de agentes?

Use um grupo de processos para uma árvore de comandos local no macOS e envie um sinal ao ID negativo do grupo depois do prazo. Uma sessão pode oferecer um limite mais amplo, enquanto um gerenciador de serviços ou contêiner pode impor controles de recursos mais fortes. Escolha um limite e registre seu identificador antes do início do trabalho.

Um processo órfão ainda pode usar uma chave de API depois que o agente é encerrado?

Um socket de controle SSH, uma conexão autenticada aberta, um descritor de arquivo herdado ou um token bearer de longa duração podem continuar utilizáveis depois que o processo pai termina. A solução é evitar entregar credenciais brutas ao processo do agente e dar a cada ação externa uma duração limitada. A revogação precisa abranger o caminho da ação, não apenas a sessão de conversa.

Como encontro no macOS os processos filhos deixados por um agente cujo tempo limite expirou?

No macOS, examine PID, PPID, PGID, SID, tempo decorrido e linha de comando com ps antes de enviar um sinal. Procure processos cujo PPID mudou para 1 ou para outro supervisor e cujo PGID ainda corresponde à execução expirada. Preserve esse instantâneo antes da limpeza se precisar criar um registro do incidente.

O `pkill` é seguro para limpar agentes de IA cujo tempo limite expirou?

Não. Uma correspondência por nome pode encerrar um editor, executor de testes ou outra execução de agente que não têm relação com o caso, além de deixar passar um processo filho que mudou o nome do executável. Envie o sinal a um grupo de processos registrado ou a um trabalho pertencente a um supervisor.

O que um registro de auditoria da execução de um agente de IA deve conter?

Comece pelo prazo, pelo identificador do grupo de processos ou do trabalho, pelo PID do processo pai, pela identidade da ação aprovada e pelos horários registrados em um relógio monotônico. Acrescente cada chamada externa, o status de saída e cada sinal de limpeza. Sem o identificador do limite, atribuir os eventos depois se torna um exercício de suposição.

Um gateway de ações pode impedir vazamentos de credenciais causados por processos órfãos?

Ele ajuda somente quando mantém a credencial fora do agente e registra a ação de forma independente da saída do próprio agente. Ainda é preciso ter contenção no sistema operacional, porque um processo órfão pode consumir arquivos, CPU, sockets e dados que já obteve. Um gateway registra o que atravessou seu limite, mas não faz uma árvore de processos inadequada desaparecer.

O que devo fazer depois de descobrir um processo de agente órfão?

Primeiro, encerre o grupo registrado, aguarde brevemente e só então intensifique a ação para os processos sobreviventes. Depois, capture os processos restantes e relacione seu horário de início, grupo, atividade de rede aberta e registros de ações. Faça a rotação ou revogue uma credencial quando não puder comprovar que o processo que escapou perdeu o acesso.

Como testar a limpeza após o tempo limite de um agente autônomo de programação?

Execute um teste deliberado de falha no CI: permita que um processo pai crie um filho, faça o pai ultrapassar o tempo limite e confirme que nenhum dos dois PIDs continua existindo e que nenhuma ação ocorreu depois do registro de expiração. Repita o teste para wrappers de shell, runtimes de linguagem e auxiliares SSH, pois cada camada pode criar outros processos. Um caminho de limpeza que nunca foi testado é apenas uma esperança.

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