A aprovação de scripts para agentes de IA pode confiar em um interpretador assinado?
A aprovação de scripts para agentes de IA precisa de mais do que um interpretador assinado. Revise os bytes exatos do código-fonte, o contexto de execução, as dependências e o destino da ação.

Um interpretador assinado não prova qual script você aprovou. Ele prova algo mais específico: o sistema operacional iniciou um binário de interpretador cuja assinatura pôde validar. Depois disso, o interpretador pode ler qualquer quantidade de arquivos mutáveis, aceitar código-fonte em uma string de comando, carregar código por meio de um resolvedor de pacotes e agir com credenciais que o script nunca teve.
Essa distinção se perde quando um cartão de aprovação diz «Python» ou «Node» e exibe um tranquilizador selo de assinatura. Já vi revisores aprovarem esse pedido porque o nome do binário era conhecido e passarem o resto da tarde descobrindo qual checkout do repositório, link simbólico, configuração do ambiente ou pré-carregamento de pacote realmente forneceu o código. Executáveis conhecidos merecem uma confiança adequada a executáveis. Eles não tornam qualquer código-fonte confiável.
Um interpretador assinado identifica apenas o interpretador
A assinatura de código responde a uma pergunta de procedência sobre um arquivo executável. No macOS, as ferramentas codesign podem inspecionar a assinatura e o requisito designado de um executável. O Gatekeeper e as proteções de execução da plataforma usam informações relacionadas ao avaliar um software. Nenhum desses mecanismos afirma que um arquivo Python passado na linha de comando veio do mesmo desenvolvedor, que não mudou desde a revisão ou que seus imports são inofensivos.
Considere estas duas chamadas:
/usr/bin/python3 /Users/dev/work/release/publish.py
/usr/bin/python3 -c "import os; os.system('curl ...')"
A identidade do interpretador pode ser idêntica nos dois casos. A identidade do código-fonte é completamente diferente. A primeira chamada tem um caminho que pode ajudar o revisor a encontrar o código. A segunda não tem nenhum arquivo de script. Um pedido que reduz qualquer uma das chamadas a «Python assinado solicita acesso à rede» elimina justamente a parte que uma pessoa precisa avaliar.
A documentação do Python descreve formas distintas de linha de comando para executar um arquivo, executar um comando com -c, executar um módulo com -m e ler o código-fonte da entrada padrão. Esse é o comportamento normal de um interpretador, não um defeito. O erro está em tratar essas formas como se todas tivessem por trás um único programa estável e assinado.
O mesmo erro aparece com a identidade do processo. Um sistema de aprovação pode informar corretamente que um processo de agente veio de uma autoridade de assinatura de código que você reconhece. Ainda assim, não pode concluir que todo arquivo local que o processo pede ao interpretador para executar merece a mesma aprovação. A identidade do chamador e a identidade do código-fonte respondem a perguntas diferentes:
- A identidade do chamador pergunta quem iniciou o pedido.
- A identidade do interpretador pergunta qual binário analisa o código-fonte.
- A identidade do código-fonte pergunta quais bytes o interpretador analisará.
- A identidade da ação pergunta qual host, rota de API, conta ou comando recebe o pedido resultante.
Se a tela de revisão só tiver espaço para os dois primeiros itens, ela dará uma falsa sensação de precisão. Na prática, o código-fonte e a ação decidem se o pedido é aceitável.
O alvo da revisão é uma tupla de execução
O revisor precisa de uma descrição estável da execução exata, não de um rótulo amigável. Chamo essa descrição de tupla de execução: o interpretador resolvido, seus argumentos, o artefato de código-fonte, o contexto de execução e a ação externa solicitada. Altere um membro relevante da tupla e você terá uma execução diferente, que precisa de uma nova decisão.
Para uma chamada Python baseada em arquivo, a tupla mínima útil se parece com isto:
{
"caller": {
"pid": 48172,
"signing_authority": "Example Development Team"
},
"interpreter": {
"resolved_path": "/usr/local/bin/python3.12",
"signing_identity": "Python Software Foundation",
"sha256": "c44e...9a10"
},
"argv": ["/usr/local/bin/python3.12", "/private/var/run/gateway-src/publish.py"],
"source": {
"display_path": "/Users/dev/work/release/publish.py",
"sha256": "6ab1...ee42"
},
"context": {
"working_directory": "/Users/dev/work/release",
"environment": {"DEPLOY_ENV": "staging"}
},
"requested_action": "POST https://api.example.invalid/releases"
}
As abreviações dos digests pertencem ao cartão de aprovação, mas o digest completo pertence ao diário. Em geral, o revisor precisa do caminho legível e de um diff ou uma prévia do código-fonte. Um investigador precisa de um valor inequívoco que possa comparar mais tarde.
Não coloque todas as variáveis de ambiente no cartão. Isso transforma uma decisão em um teste de visão. Capture os valores que afetam a seleção do código, a resolução de comandos, as credenciais, o roteamento por proxy, a seleção do destino e os switches de recursos. Para Python, isso pode incluir PYTHONPATH, PYTHONHOME e um caminho de configuração fornecido explicitamente. Para execução de shell, costuma incluir PATH, o diretório atual e as variáveis interpoladas no comando. Registre o ambiente completo em dados de auditoria protegidos se o seu modelo de ameaça exigir isso, mas apresente à pessoa apenas o subconjunto relevante.
É também aqui que as equipes confundem uma segunda distinção: reprodutibilidade não é autorização. Um lockfile, um commit do Git ou uma imagem de contêiner podem ajudar a reproduzir o que foi executado. Eles não dizem se esse código deve chamar a produção, excluir uma branch remota ou abrir uma sessão SSH. Associe a identidade do código-fonte a um pedido de ação claro.
O Python pode esconder código atrás de launchers comuns
O Python faz uma chamada simples de arquivo parecer mais fácil do que é. python deploy.py informa onde a execução começa, mas o interpretador pode importar módulos do diretório do script, de pacotes instalados, de caminhos de busca configurados e de código selecionado pela lógica da aplicação. Um ambiente virtual também pode mudar qual interpretador um python sem qualificação resolve.
Comece resolvendo o executável antes de avaliar sua assinatura. O rótulo python, python3 ou venv/bin/python não é uma identidade. Um launcher pode ser um link simbólico, um shim ou um binário diferente depois de uma atualização da toolchain. O gateway deve resolver o objeto que o kernel iniciará, inspecionar esse objeto e registrar seu caminho e digest.
Depois, trate o caminho do código-fonte como uma ajuda visual, não como o limite de segurança. Resolva os links simbólicos para obter uma localização canônica no registro da revisão, mas não execute o original mutável depois da revisão. Um checkout do repositório pode substituir deploy.py sem mudar o caminho. Um link simbólico pode apontar para outro destino. Uma verificação de caminho, sozinha, não detecta nenhum desses eventos.
Uma sequência prática é:
- Leia os bytes solicitados do script e calcule o SHA-256.
- Copie esses bytes para um diretório privado, pertencente ao gateway e com permissões restritas.
- Exiba o caminho do chamador, o caminho canônico, o digest e uma prévia do código-fonte para aprovação.
- Invoque o interpretador verificado com a cópia privada e registre o resultado associado a esse digest.
Essa cópia não é trabalho burocrático. Ela fecha a diferença entre o momento da verificação e o momento do uso. Se o revisor aprovou o digest 6ab1...ee42, o interpretador precisa ler os bytes cujo digest é 6ab1...ee42. Calcular o hash do arquivo no repositório e depois pedir ao Python que leia novamente o arquivo do repositório deixa uma janela pequena, mas real, para que ele seja substituído.
Os imports ainda precisam de uma decisão. Se publish.py importar um release_helpers.py local, um helper alterado pode mudar o comportamento mesmo que o arquivo de entrada continue igual. A opção mais rigorosa é um manifesto de código-fonte que inclua todos os módulos locais permitidos nessa execução. Para o trabalho rotineiro, uma opção mais prática é preparar o script de entrada e sua árvore de pacotes locais declarada em conjunto, rejeitar imports fora dessa árvore preparada e exigir uma nova aprovação quando o digest do manifesto mudar.
Não finja que isso detecta imports dinâmicos, extensões nativas, sitecustomize ou código arbitrário obtido em tempo de execução. Não detecta. A tela de aprovação deve indicar essas permissões quando existirem. Um script que diz importlib.import_module(os.environ["PLUGIN"]) não merece a mesma aprovação ampla que um script autocontido apenas porque ambos começam com o mesmo interpretador assinado.
O arquivo de entrada do Node é apenas uma parte do programa
O Node acrescenta outra camada de ambiguidade. node task.js tem um arquivo de entrada, mas a resolução de módulos pode selecionar código por meio de package.json, exports de pacotes, lockfiles, links simbólicos e do diretório atual. A documentação da CLI do Node também descreve pré-carregamentos como --require e --import, que podem executar código antes do início do arquivo de entrada.
Isso significa que um sistema de revisão precisa exibir o vetor completo de argumentos, não apenas o caminho final .js. Estas chamadas merecem análises diferentes:
node tools/publish.mjs
node --import ./tools/setup.mjs tools/publish.mjs
node --require ./tools/patch.cjs tools/publish.mjs
node -e "require('child_process').execSync(process.argv[1])" "git push --force"
Um revisor que veja apenas tools/publish.mjs não perceberá o código executado antes dele na segunda e na terceira chamadas. Na última chamada, não há arquivo de entrada revisado. A string de comando é o artefato de código-fonte e deve ser exibida, armazenada e ter seu hash calculado como tal.
A variável de ambiente NODE_OPTIONS merece o mesmo tratamento. O Node a documenta como uma forma de passar opções de linha de comando permitidas pelo ambiente. Se um processo puder fornecer pré-carregamentos ou alterar o comportamento de depuração por esse meio, um gateway que ignore essa variável terá inspecionado um comando incompleto. Não é preciso assustar os revisores com todas as configurações de tempo de execução, mas é necessário mostrar as que fazem código ser carregado ou alteram a seleção do destino.
Os gerenciadores de pacotes criam outra armadilha. npm run publish muitas vezes parece uma tarefa nomeada, mas o comportamento vem de um package.json mutável, seus scripts, o lockfile, hooks do gerenciador de pacotes e binários encontrados na árvore de dependências do projeto. O nome da tarefa deve ser expandido antes da aprovação. Mostre o comando resolvido, a revisão do projeto ou o manifesto preparado e cada hook de ciclo de vida que será executado. Se essa expansão não estiver disponível, peça uma aprovação mais restrita ou recuse o pedido. «Executar script do pacote» não descreve uma ação de forma significativa quando o arquivo do pacote pode mudar sem aviso.
Para automações Node repetíveis, prepare um snapshot revisado do workspace ou use um artefato de build imutável. Um hash apenas de publish.mjs é suficiente quando o script não tem dependências locais nem caminho de pré-carregamento. A maioria dos projetos não atende a essa condição.
Strings de shell precisam ser tratadas como código-fonte
Pedidos de shell falham na revisão quando alguém os chama de comandos, e não de programas. sh -c analisa uma string de código-fonte com expansões, substituições, redirecionamentos, pipelines, funções e busca de comandos. A string pode ser curta, mas pode invocar uma sequência ilimitada de outros programas.
Compare estes pedidos:
/bin/sh -c 'curl -fsS "$RELEASE_URL" | sh'
/bin/sh /private/var/run/gateway-src/release.sh
O primeiro pedido precisa da string de comando exata, de todos os valores relevantes do ambiente e de uma explicação do que o programa seguinte receberá. O segundo precisa do mesmo tratamento de caminho e conteúdo de script aplicado ao Python ou ao Node. A assinatura de /bin/sh informa quem forneceu o analisador. Ela não aprova nenhuma das entradas de código-fonte.
Não aprove um comando shell com base no primeiro verbo. git status pode ser inofensivo em um vetor exato de argumentos, enquanto git -c credential.helper=... altera as entradas que o Git carregará. curl pode buscar dados, gravar um arquivo ou direcionar bytes para outro interpretador. O revisor precisa de sintaxe suficiente para ver redirecionamentos e substituições, além de contexto de execução suficiente para saber onde os programas serão resolvidos.
PATH costuma ser esquecido. Um script que chama deploy sem um caminho absoluto delega a seleção do executável ao ambiente. Se o pedido vier de um workspace de agente, um invasor que consiga alterar esse workspace poderá colocar um programa no início do PATH. Quando possível, capture o caminho do executável resolvido para cada subcomando sensível à segurança. Quando avaliar o shell completo for inseguro ou incerto demais, use uma interface de comandos restrita em vez de tentar construir um analisador de shell perfeito.
Esse último ponto vai contra uma recomendação popular: «Basta permitir um shell assinado e pedir aprovação a cada chamada». Ela é popular porque o shell existe em toda parte e a aprovação parece simples. Está errada porque uma única aprovação não tem um objeto de código-fonte estável, a menos que o sistema registre a string exata ou o script imutável e o contexto relevante. A aprovação por chamada ainda pode aprovar a coisa errada com admirável consistência.
Um hash de conteúdo precisa de um arquivo ao qual possa realmente se vincular
Um hash é uma evidência sobre bytes, não uma prova de que o programa pretendido os usará. A implementação precisa vincular os bytes revisados à execução. É aqui que muitos projetos cuidadosos falham.
O padrão inseguro é fácil de reconhecer:
1. Read /workspace/scripts/publish.py
2. Calculate and display SHA-256
3. Wait for approval
4. Run python /workspace/scripts/publish.py
Entre as etapas 2 e 4, outro processo pode editar o arquivo, substituir um link simbólico ou alterar um diretório montado. O registro de aprovação continua correto sobre o que o revisor viu, mas não serve para explicar o que foi executado.
Use um destes modelos:
- Copie os bytes revisados para um diretório de execução privado, defina permissões para impedir que o processo solicitante os altere e execute a cópia.
- Execute um artefato imutável previamente construído, cujo digest tenha sido revisado e registrado.
- Mantenha um objeto de arquivo já aberto durante o caminho de verificação e execução somente se o interpretador e o sistema operacional permitirem executar exatamente esse objeto sem resolver novamente um caminho mutável.
O modelo da cópia privada costuma ser mais fácil de explicar e auditar. Ele também fornece um artefato estável para a análise de incidentes. Preserve o caminho original exibido como contexto, pois as pessoas precisam saber qual arquivo do projeto motivou a execução, mas não o confunda com os bytes executados.
O hash de conteúdo tem limites que devem permanecer visíveis. Ele não pode decidir se o código-fonte é seguro. Não pode estabilizar respostas remotas, comportamentos dependentes do tempo, valores aleatórios ou código carregado depois do hash. Ele evita uma classe específica de erro de aprovação: revisar uma versão local do script e executar outra. Esse é um limite útil, desde que seja descrito com honestidade.
Use SHA-256 ou outro digest criptográfico atual, com uma codificação fixa, e inclua sempre o nome do algoritmo nos registros. Uma sequência hexadecimal sem contexto gera confusão no futuro. Um registro de digest deve dizer sha256:6ab1...ee42, e não apenas 6ab1...ee42.
Os cartões de aprovação devem exibir evidências úteis para uma pessoa
Um bom cartão de aprovação permite que o revisor decida rapidamente sem esconder os fatos que mudam a decisão. Não comece com um hash de arquivo. Pessoas não conseguem avaliar um hash visualmente. Comece com a ação solicitada e o chamador, depois mostre o interpretador, a localização do código-fonte, o estado do código e o contexto de execução relevante.
Para um pedido de implantação, um cartão compacto poderia ser assim:
Caller: signed process from Example Development Team, PID 48172
Action: POST release data to api.example.invalid
Interpreter: /usr/local/bin/python3.12, signed by Python Software Foundation
Source: /Users/dev/work/release/publish.py
Reviewed bytes: sha256:6ab1...ee42
Execution copy: /private/var/run/gateway-src/6ab1...ee42/publish.py
Context: DEPLOY_ENV=staging, working directory /Users/dev/work/release
O cartão deve oferecer a prévia do código-fonte ou um diff em relação ao último digest aprovado. Para trabalhos repetidos, um diff costuma ser melhor porque direciona a atenção para as linhas alteradas. Ainda assim, disponibilize o código completo quando solicitado. Uma prévia cortada de forma enganosa é pior do que nenhuma prévia.
Evite rótulos vagos como «Permitir ferramentas de implantação» ou «Permitir acesso do Python». Eles ensinam as pessoas a clicar com base no reconhecimento da marca. Uma decisão também deve declarar sua duração. Uma execução, uma sessão de processo e uma versão de artefato revisado são escopos diferentes. Uma aprovação de sessão para um processo de agente pode reduzir o cansaço causado pelos pedidos, mas qualquer script cujo digest mude deve iniciar uma nova decisão sobre o código-fonte antes de reutilizar a autoridade externa.
Isso é diferente de um mecanismo de regras. Você não precisa de uma linguagem para que as pessoas escrevam condições como «permitir scripts seguros». Precisa de um objeto de revisão fixo que não possa se ampliar silenciosamente depois da aprovação. O sistema deve construir esse objeto a partir das entradas resolvidas, exibi-lo e vincular a execução a ele.
Os limites das dependências precisam ser explícitos
O digest de um script de entrada só pode ser suficiente quando o limite de código do programa é realmente aquele único arquivo. Trate isso como exceção, não como padrão. Imports do Python, módulos do Node, comandos source do shell, templates, arquivos de configuração e plugins executáveis podem mudar o comportamento depois que o ponto de entrada passa pela revisão.
Defina o limite de acordo com a consequência da ação. Para uma leitura de baixo risco em um serviço de desenvolvimento, talvez você aceite um script de entrada preparado junto de uma declaração explícita de que ele pode importar pacotes instalados. Para uma gravação em produção ou um comando SSH, inclua as dependências locais em um manifesto, fixe as dependências externas e rejeite downloads de código executável durante a execução. Assim, o registro informa ao investigador o que você quis dizer com «o script».
Um manifesto simples pode conter caminhos relativos e digests:
sha256 publish.py 6ab1...ee42
sha256 release_helpers.py 9d07...1a3c
sha256 config/targets.json 743e...64b1
O gateway deve calcular esse manifesto a partir de cópias preparadas ou de uma entrada de build controlada, em vez de aceitar um manifesto fornecido pelo mesmo workspace mutável. Se o projeto declarar um lockfile como parte do seu limite, calcule o hash desse lockfile também. Um lockfile só ajuda quando o ambiente de execução o respeita e o processo revisado não pode substituir a árvore de dependências.
Chega um ponto em que a execução local baseada em interpretador se torna ampla demais para uma decisão com um clique. Se o código puder descobrir plugins em diretórios arbitrários, buscar e executar conteúdo remoto ou gravar e executar scripts gerados, divida o trabalho. Aprove um build que produza um artefato imutável, inspecione a ação declarada do artefato e depois aprove essa ação. Esse limite adicional custa menos do que reconstruir uma alteração acidental em produção.
Os registros precisam responder o que foi executado, não ao nome usado pela interface
Quando uma ação dá errado, a primeira pergunta útil costuma ser «o que exatamente foi executado com essa autoridade?». Um registro que diga «Python aprovado» não consegue responder. Mantenha a tupla de execução, o escopo da decisão, a interação do revisor, os horários e o resultado observado. Remova segredos do registro, mas não remova a identidade do artefato de código-fonte nem a ação de destino.
Um registro sólido conecta eventos relacionados. A entrada da sessão identifica o processo do agente e sua autoridade. A entrada da ação identifica o interpretador, o digest do código-fonte preparado, os argumentos, o destino e o resultado. Se um revisor revogar uma sessão, esse evento deve se conectar à mesma identidade de sessão. Caso contrário, os operadores não poderão saber se a revogação interrompeu o solicitante que fez a chamada.
A evidência contra adulteração melhora a qualidade do registro. Um diário encadeado por hashes pode tornar alterações posteriores detectáveis, mas não corrige campos ausentes. Verifique a cadeia e ainda pergunte se ela registra o caminho resolvido, o digest do código-fonte, o contexto e a ação real. A integridade preserva evidências, mas não cria evidências que o sistema nunca capturou.
Os diários separados do Sallyport são úteis aqui porque distinguem a execução do agente de chamadas HTTP ou SSH individuais, projetando ambos a partir de um único registro de auditoria criptografado e encadeado por hashes. O comando sp audit verify pode verificar a cadeia offline sobre o texto cifrado, que é a propriedade certa para conferir se as evidências mantidas foram alteradas posteriormente.
Trate alterações no código-fonte como uma nova autoridade
O padrão mais seguro é simples: quando o digest do código-fonte mudar, exija uma nova decisão para uma ação externa. Não mantenha silenciosamente a aprovação anterior porque o caminho, o interpretador, o nome do projeto ou a assinatura do processo parecem conhecidos.
Essa regra criará alguns pedidos a mais durante o desenvolvimento ativo. É assim que deve ser. A revisão do código altera a autoridade quando o código pode usar uma credencial, modificar um serviço remoto ou executar um comando SSH. A resposta não é eliminar todos os pedidos. Melhore o artefato de revisão, prepare um código-fonte determinístico e conceda a sessão de processo mais ampla somente quando o código-fonte continuar identificado de forma independente.
Para equipes que usam um gateway de ações, mantenha o controle concentrado no ponto em que as credenciais saem da máquina local. O agente deve solicitar uma chamada HTTP ou um comando SSH com um registro de revisão vinculado ao código-fonte, enquanto o gateway mantém a credencial e devolve o resultado. Essa organização evita entregar segredos a um script mutável, mas ainda exige honestidade sobre qual código solicitou a ação.
Comece pela chamada de interpretador mais sensível. Resolva o binário, exiba todos os argumentos, calcule o hash e prepare os bytes reais do código-fonte, registre o contexto relevante e faça com que um digest alterado signifique uma aprovação alterada. Com esse registro, um interpretador assinado se torna uma evidência útil em uma decisão completa, em vez de um rótulo tranquilizador sobre um script desconhecido.
FAQ
Um binário Python ou Node assinado torna seguro aprovar um script?
Não. Uma assinatura informa quem assinou o binário do interpretador, como Python, Node ou um shell. Ela não diz qual arquivo de código esse binário lerá, se o arquivo foi alterado nem quais arquivos o código carregará em seguida.
O que um pedido de aprovação deve exibir para um script?
Aprove um registro exato da execução: o interpretador resolvido, sua identidade de assinatura, o vetor de argumentos, a localização canônica do script e o digest do script. Inclua o diretório de trabalho, os valores relevantes do ambiente e as dependências declaradas quando puderem alterar o comportamento.
Verificar o caminho de um script é suficiente para aprovar um agente?
Um caminho ajuda a pessoa a localizar o arquivo, mas não é uma identidade. Um script pode ser editado no lugar, substituído por meio de um link simbólico ou obtido de outra revisão no mesmo caminho. Por isso, associe o caminho a um digest do conteúdo.
Como evitar uma condição de corrida na verificação do hash?
Calcule o hash dos bytes exatos que serão executados e depois execute uma cópia imutável desses bytes, pertencente ao gateway. Se você calcular o hash de um arquivo e executar mais tarde o caminho mutável original, uma alteração entre esses eventos invalida a verificação.
Módulos importados podem mudar o comportamento de um script aprovado?
O Python pode carregar imports pelo sistema normal de importação, por hooks de inicialização e por carregadores explícitos em tempo de execução. O Node pode pré-carregar módulos e resolver pontos de entrada de pacotes. Portanto, trate o script de entrada como o começo do limite da revisão, não como o limite completo.
Como devo revisar um comando shell -c?
Trate a string como código-fonte, não como um argumento. Armazene os bytes exatos da string de comando, calcule o hash, exiba-os no cartão de aprovação e registre o executável do shell e o ambiente que os interpretarão.
Ambientes virtuais do Python mudam a identidade do interpretador?
Um ambiente virtual pode apontar para o mesmo interpretador por meio de um launcher ou link simbólico, ou pode usar um binário diferente. Resolva o executável que o sistema operacional iniciará e verifique esse objeto, em vez de confiar no rótulo do comando ou no nome do diretório do ambiente virtual.
A assinatura do processo pode substituir o hash do script?
A assinatura de um processo pode ajudar a estabelecer quem produziu o chamador, enquanto o digest do script identifica o que esse chamador pediu ao interpretador para executar. Ambos devem fazer parte de uma aprovação de alto impacto, e nenhum substitui o outro.
Uma equipe deve aprovar permanentemente o caminho de um script de implantação?
Para automações repetidas, aprove um artefato restrito e imutável ou uma revisão liberada e analisada, com validade e escopo de ação explícitos. Uma aprovação permanente para qualquer arquivo em um caminho conhecido transforma edições normais do repositório em autoridade sobre credenciais.
O que um registro de auditoria deve manter para scripts aprovados?
Mantenha um registro de auditoria com a decisão, a identidade do chamador, a identidade do interpretador, o comando exato, o digest do código-fonte, o destino da ação e o resultado. Um registro que diga apenas «Python aprovado» não consegue explicar o que aconteceu depois de um incidente.