> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Solução de Problemas

> Documentação de Solução de Problemas do AgentEye.

Este guia mapeia os sintomas mais comuns em produção para um diagnóstico e correção concretos, para que você possa resolver incidentes com as ferramentas que já possui, sem precisar configurar infraestrutura adicional de observabilidade. Ele cobre o servidor, coletor, painel, assistente de IA, Python SDK, monitoramento de saúde e certificados, backups, análises com ClickHouse e multi-tenancy.

As páginas do painel têm escopo por organização em `/<org-slug>/…`, e o stream de eventos é a página inicial da organização (`/<org-slug>/`). Os nomes de páginas neste guia (por exemplo, `/sessions`, `/queries`) referem-se a essas rotas com escopo de organização.

***

## Visualizando Logs

O AgentEye não inclui uma pilha de logging ou monitoramento. Tanto o servidor quanto o painel escrevem logs estruturados no **stdout**, para que você possa lê-los diretamente com `kubectl` ou `docker`; nenhum agregador é necessário.

### Kubernetes

Acompanhe os logs ao vivo do servidor e do painel:

```bash theme={null}
kubectl logs -n agenteye -l app=server    -f --timestamps
kubectl logs -n agenteye -l app=dashboard -f --timestamps
```

Variações úteis:

| Objetivo                                    | Comando                                                           |
| ------------------------------------------- | ----------------------------------------------------------------- |
| Últimas 200 linhas (sem acompanhamento)     | `kubectl logs -n agenteye -l app=server --tail=200 --timestamps`  |
| Logs da falha anterior                      | `kubectl logs -n agenteye <pod-name> --previous`                  |
| Acompanhar todas as réplicas ao mesmo tempo | `kubectl logs -n agenteye -l app=server --max-log-requests=10 -f` |
| Postgres (StatefulSet)                      | `kubectl logs -n agenteye postgres-0 -f`                          |

### Docker Compose

```bash theme={null}
docker logs -f agenteye-server
docker logs -f agenteye-dashboard
```

### Correlacionando uma única requisição entre painel e servidor

Cada requisição do painel é marcada com um `request_id` e propagada ao servidor via cabeçalho `x-request-id`. O servidor o ecoa nos cabeçalhos de resposta e em cada linha de log emitida para aquela requisição. Para rastrear uma requisição de ponta a ponta:

1. Capture o id do cabeçalho de resposta, por exemplo:
   ```bash theme={null}
   curl -i https://dashboard.example.com/api/events | grep -i x-request-id
   # x-request-id: 9a7b0d6e-5e9b-4c0a-9f8a-5f1e4b5c0f3a
   ```
2. Busque nos logs de ambos os pods esse id:
   ```bash theme={null}
   REQ=9a7b0d6e-5e9b-4c0a-9f8a-5f1e4b5c0f3a
   kubectl logs -n agenteye -l app=dashboard --tail=5000 | grep "$REQ"
   kubectl logs -n agenteye -l app=server    --tail=5000 | grep "$REQ"
   ```

Você verá as linhas `proxy passthrough`, `withAuth: authorized` e `upstream response` do painel junto com o par `http request received` / `http request completed` do servidor, todos compartilhando o mesmo `request_id`.

### Logs JSON e `jq`

Defina `AE_LOG_JSON=1` no painel (ativado por padrão quando `NODE_ENV=production`) para emitir um objeto JSON por linha. Então filtre estruturalmente:

```bash theme={null}
kubectl logs -n agenteye -l app=dashboard --tail=5000 \
  | jq 'select(.level == "warn" or .level == "error")'

kubectl logs -n agenteye -l app=dashboard --tail=5000 \
  | jq 'select(.route == "POST /api/keys")'
```

O servidor Rust emite pares `key=value` de tracing que funcionam bem com grep sem `jq`:

```bash theme={null}
kubectl logs -n agenteye -l app=server --tail=5000 | grep 'status=5'   # 5xx
kubectl logs -n agenteye -l app=server --tail=5000 | grep 'actor_key_id='
```

### Aumentando a verbosidade

| Componente | Variável de ambiente | Exemplo                                                   |
| ---------- | -------------------- | --------------------------------------------------------- |
| Servidor   | `RUST_LOG`           | `RUST_LOG=debug` ou `RUST_LOG=agenteye_server=debug,info` |
| Painel     | `AE_LOG_LEVEL`       | `AE_LOG_LEVEL=debug`                                      |

`debug` no servidor adiciona uma linha `api key authenticated` por autenticação. `debug` no painel adiciona linhas `upstream request`, `session validated` e `proxy passthrough`.

### Retenção de logs

O stdout do container é efêmero; o kubelet rotaciona os arquivos de log (padrão \~10 MiB por container) e mantém uma quantidade pequena em disco. Uma vez que o pod é excluído, os logs são perdidos. Se você precisar de retenção mais longa ou busca entre pods, aponte seu cluster para um coletor de logs (Loki, CloudWatch, Cloud Logging, Datadog, etc.) que monitore `/var/log/containers/`. O AgentEye não exige nem prescreve nenhuma escolha específica.

***

## Problemas de Autenticação

### `docker pull` falha com "unauthorized"

Certifique-se de ter autenticado o Docker no GHCR com seu `AGENTEYE_TOKEN`:

```bash theme={null}
echo $AGENTEYE_TOKEN | docker login ghcr.io -u x --password-stdin
```

O token deve ter permissão `read:packages` na organização `agenteye-enterprise`. Entre em contato com `support@exosphere.host` se seu token não funcionar.

### `gh release download` retorna 404 ou 401

* Confirme que `AGENTEYE_TOKEN` está exportado no seu shell: `echo $AGENTEYE_TOKEN`
* Confirme que você está usando `GITHUB_TOKEN=$AGENTEYE_TOKEN gh release download ...` (a CLI `gh` lê `GITHUB_TOKEN`)
* O token precisa de `contents:read` em `agenteye-enterprise/releases`

***

## Problemas no Servidor

### Servidor falha com "invalid port number"

O `POSTGRES_PASSWORD` (ou outra credencial) contém caracteres especiais para URL (`/`, `+`, `=`) que quebram a análise de `DATABASE_URL`. Regenere a senha usando codificação hexadecimal:

```bash theme={null}
NEW_PASS=$(openssl rand -hex 24)
```

Em seguida, atualize o secret do Kubernetes e a senha dentro do Postgres (ou recrie o `.env` para Docker Compose) e reinicie o servidor. Veja os passos completos em [enterprise-docs/kubernetes-deployment.md](/pt-br/agenteye/kubernetes-deployment) § "PostgreSQL credentials".

### Servidor encerra imediatamente na inicialização

Verifique os logs do container:

```bash theme={null}
docker logs agenteye-server
```

Causas comuns:

* `DATABASE_URL` não definido ou malformado: o servidor registrará o erro e encerrará.
* Postgres inacessível: confirme que o container do Postgres ou banco de dados gerenciado está em execução e que o host/porta estão corretos.
* Migrações falharam: verifique os logs por erros SQL.

### `GET /health` retorna não-200 ou expira

O servidor pode ainda estar executando migrações na primeira inicialização. Aguarde alguns segundos e tente novamente:

```bash theme={null}
curl http://localhost:8080/health
```

Se o problema persistir, verifique `docker logs agenteye-server` por erros.

### `GET /ready` retorna 503

`/ready` é a sonda de prontidão: retorna `503` quando o servidor não consegue alcançar **Postgres ou ClickHouse**. O corpo identifica a dependência com falha:

```bash theme={null}
curl -s http://localhost:8080/ready
# {"status":"not_ready","checks":{"postgres":"ok","clickhouse":"down","redis":"ok"}}
```

Corrija a dependência reportada como `down`: o pod do ClickHouse/Postgres está `Running`? O `CLICKHOUSE_URL` / `DATABASE_URL` está correto e acessível? No Kubernetes, o pod fica como `NotReady` até que `/ready` se recupere; isso é esperado e é exatamente o sinal que o monitoramento de saúde alerta. Redis nunca é causa: é reportado, mas não falha a prontidão.

### Coletor retorna 401 Unauthorized

A chave de API do coletor não tem permissão `events:add`, ou a chave foi desativada. Crie uma nova chave com a permissão correta:

```bash theme={null}
curl -s -X POST http://your-server:8080/keys \
  -H "Authorization: Bearer $ADMIN_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"new-collector","permissions":["events:add"]}'
```

### Requisições autenticadas ficaram lentas de repente (\~200ms em vez de \~5ms)

Este é o sintoma de o Redis estar fora do ar enquanto `REDIS_URL` está definido. Cada chamada ao cache expira após 100ms e recai no Postgres; nos caminhos de autenticação e OTP, a requisição faz duas dessas recaídas.

Confirme nos logs do servidor:

```
auth cache: L2 get failed error=redis call timed out
```

Resolução:

1. `redis-cli -h <your-redis> ping` para confirmar que o Redis está acessível na rede do cluster.
2. Se o Redis ficou brevemente fora do ar e voltou, **reinicie os pods do servidor**. O `redis::aio::ConnectionManager` não reestabelece de forma confiável após a queda da conexão subjacente; uma reinicialização do pod retoma a nova conexão de forma limpa. O mesmo se aplica ao painel.
3. Se você não quer executar o Redis agora, remova `REDIS_URL` do deployment e reinicie. Ambos os serviços funcionam sem o cache (a correção é preservada; a latência volta à linha de base pré-Redis).

### Servidor reporta `OTP request rate-limited` nos logs, mas o usuário diz que tentou apenas uma vez

Verifique se o Redis estava inacessível. O caminho de fallback usa `SELECT COUNT(*) FROM otp_codes WHERE created_at > now() - interval '15 minutes'`, que vê linhas de OTP geradas anteriormente. Se o usuário ficou clicando em "Reenviar" por uma hora, a janela de 15 minutos ainda pode conter ≥5 códigos. Resolva aguardando a janela expirar ou execute `DELETE FROM otp_codes WHERE user_id = $1 AND created_at > now() - interval '15 minutes'` (console do operador).

### Alterei `ALLOWED_EMAILS` / `SESSION_TTL_SECS` / `OTP_TTL_SECS` e reiniciei; nada mudou

Essas variáveis de ambiente são **sementes apenas da primeira inicialização**. Uma vez que a tabela `settings` tem uma linha para a chave correspondente, essa linha é a fonte de verdade; a variável de ambiente é lida uma vez na primeira inicialização e ignorada em todas as reinicializações subsequentes.

Para alterá-las após a primeira inicialização, faça login no painel e edite-as em `/settings`. A alteração se aplica em segundos em todas as réplicas; sem necessidade de reinicialização.

Se você precisar forçar uma re-semeação a partir do env (raro, tipicamente útil apenas em desenvolvimento), `DELETE FROM settings WHERE key = '<key>'` e reinicie o servidor. O bootstrap captará o valor atual da variável de ambiente na próxima inicialização. Editar via `/settings` é o caminho suportado em produção.

***

## Problemas no Coletor

### Coletor inicia, mas os eventos não aparecem no painel

1. Confirme que o coletor está em execução: `systemctl status agenteye-collector` (Linux) ou verifique o processo.
2. Confirme que `AGENTEYE_URL` aponta para `http(s)://your-server-host:8080/events` (observe: o caminho `/events`).
3. Execute um flush único para ver a saída imediata:
   ```bash theme={null}
   agenteye-collector flush
   ```
4. Verifique que o Python SDK está de fato escrevendo arquivos: `ls ${AGENTEYE_HOME:-~/.agenteye}/events/`
5. Se existirem arquivos em `${AGENTEYE_HOME:-~/.agenteye}/failed/`, os uploads estão falhando. Verifique os logs do coletor pelo erro, provavelmente um 4xx (chave incorreta ou URL) ou problema de rede.

### Arquivos estão acumulando em `$AGENTEYE_HOME/events/` e não estão sendo enviados

* O coletor pode não estar em execução. Inicie-o: `agenteye-collector start`; ele automaticamente faz o flush de eventos pré-existentes na inicialização.
* Verifique a saúde do coletor: `agenteye-collector health`
* O coletor pode estar em execução, mas incapaz de alcançar o servidor. Verifique as regras de firewall entre os hosts do coletor e do servidor.

### Arquivos em `$AGENTEYE_HOME/failed/`

Os arquivos são movidos para `failed/` após todas as tentativas de retry serem esgotadas (padrão: 5 tentativas com backoff exponencial). Isso significa:

* O servidor retornou um erro 4xx (chave incorreta, URL errada ou problema de payload)
* O servidor estava inacessível durante toda a janela de retry

Corrija o problema subjacente e, em seguida, recoloque manualmente na fila:

```bash theme={null}
mv ${AGENTEYE_HOME:-~/.agenteye}/failed/*.jsonl ${AGENTEYE_HOME:-~/.agenteye}/events/
agenteye-collector flush
```

### Coletor reporta `network error` em cada upload (falha no handshake TLS)

Se `curl -k` contra `AGENTEYE_URL` funciona, mas o binário do coletor falha em cada upload com `error sending request for url (...)`, o servidor AgentEye está apresentando um certificado TLS que não foi assinado por uma CA de confiança pública.

O **caminho de produção** é o hostname ACME de ingestão configurado em `deploy/base/certificates/domain.env` (veja [`kubernetes-deployment.md`](/pt-br/agenteye/kubernetes-deployment) Fases 3.1 / 4.2). Uma vez que `INGEST_DOMAIN` resolve para o LB público do Traefik e o cert-manager emitiu o certificado Let's Encrypt, os coletores verificam o certificado do servidor contra o store de confiança do sistema **sem necessidade de `AGENTEYE_TLS_CA`**; remova-o da sua configuração do coletor se foi definido para um deployment antigo com certificado autoassinado.

**Sintoma: o coletor funcionava ontem, falha hoje após uma lacuna de \~90 dias.** Isso significa que o deployment ainda usa o emissor legado `selfsigned` para `ingest-tls`. O certificado de 90 dias foi rotacionado e o arquivo de CA fixado está desatualizado. Corrija permanentemente mudando o cluster para o emissor ACME (Fase 3.1 do guia de deployment). Desbloqueio de curto prazo: re-extraia o certificado atual do servidor e atualize `AGENTEYE_TLS_CA`:

```bash theme={null}
kubectl get secret ingest-tls-cert -n agenteye \
  -o jsonpath='{.data.tls\.crt}' | base64 -d > /etc/agenteye/server-ca.crt
```

```bash theme={null}
export AGENTEYE_TLS_CA=/etc/agenteye/server-ca.crt
agenteye-collector flush
```

`AGENTEYE_TLS_CA` adiciona uma âncora de confiança adicional; as raízes públicas padrão ainda são confiáveis.

### Certificado `ingest-tls` está preso em `Ready: False` após o deploy

```bash theme={null}
kubectl describe certificate ingest-tls -n agenteye
```

Observe os `Events` e o `Order` / `Challenge` referenciado. Causas comuns:

* **DNS não resolvendo para o LB público.** O validador HTTP-01 não consegue alcançar `INGEST_DOMAIN`. Verifique com `dig +short INGEST_DOMAIN`; deve resolver para o mesmo endereço que o `EXTERNAL-IP` do LoadBalancer `traefik-public`. O cert-manager retenta automaticamente quando o DNS se propaga; não é necessário excluir o Certificate.
* **Porta 80 bloqueada no load balancer / security group.** HTTP-01 requer que a porta 80 seja acessível pelos validadores públicos do Let's Encrypt. Se você tem um WAF ou SG restringindo `:80`, abra-o (a configuração do Traefik redireciona para HTTPS, mas o Boulder segue o redirecionamento e aceita a resposta).
* **`dnsNames` não substituídos.** Se `kubectl get certificate ingest-tls -n agenteye -o jsonpath='{.spec.dnsNames}'` mostrar `INGEST_DOMAIN_PLACEHOLDER`, você pulou a etapa do `domain.env`; crie-o a partir de `domain.env.example` e reaplique.
* **Rate limiting pelo Let's Encrypt.** Ordens repetidas com falha para o mesmo hostname ativam os limites de certificado duplicado ou validação falhada. Aguarde pelo menos uma hora antes de tentar novamente; verifique o status do Order pela mensagem exata de rate limit.

### Certificado `dashboard-tls` está preso em `Ready: False` / o navegador ainda mostra um aviso

Mesmo fluxo de diagnóstico que `ingest-tls` acima (`kubectl describe certificate dashboard-tls -n agenteye`); as causas de DNS, porta 80, placeholder e rate limit se aplicam, mais duas específicas do painel:

* **`DASHBOARD_DOMAIN` resolve para o LoadBalancer errado.** Deve apontar para o LB do Traefik do *painel*, não o de ingestão pública. Execute `dig +short` no hostname e compare com o endereço do LB do painel.
* **A instância Traefik do painel não consegue servir o desafio.** Deve ser instalada com o arquivo de valores do painel incluído, que habilita um provedor Ingress com escopo para o solver HTTP-01 do cert-manager. Sem ele, o solver é inacessível e o Order fica em `pending` para sempre. Atualize a instância com os valores fornecidos; o desafio pendente então se completa por conta própria.
* **O LoadBalancer tinha restrição de IP.** Os intervalos de origem se aplicam à porta 80 também, o que bloqueia os validadores do Let's Encrypt — tanto na emissão inicial quanto em cada renovação de \~75 dias. Reabra o LB, ou coordene um solver DNS-01 com o suporte antes de restringi-lo.

Enquanto a emissão está falhando, o painel continua servindo o certificado anterior (ou o padrão do ingress em uma nova instalação) — o acesso é degradado por um aviso do navegador, nunca interrompido.

### A CLI ainda ignora a verificação TLS após o painel obter um certificado confiável

`--insecure` é persistido em `cli.json` no login. Uma vez que o painel serve um certificado de confiança pública, faça login novamente com `agenteye --base-url https://<your-dashboard-domain> --secure login`; a verificação é salva de volta como ativada e o aviso de inicialização desaparece.

***

## Problemas no Painel

### Não consigo desativar ou editar o usuário `ADMIN_EMAIL`

Por design. O usuário correspondente ao `ADMIN_EMAIL` é marcado como protegido em cada inicialização do servidor: o painel oculta o botão Desativar para aquela linha, e a API rejeita `DELETE /users/:id` e `PUT /users/:id` com `403 Forbidden`. Um trigger do banco de dados também rejeita instruções `UPDATE` diretas que desativariam a linha protegida.

Para rotacionar o admin de bootstrap, altere `ADMIN_EMAIL` no seu ambiente e reinicie o servidor. O novo e-mail é inserido/atualizado como protegido. O admin anterior retém o sinalizador de proteção até ser limpo no banco de dados (normalmente está bem, pois o e-mail anterior ainda é um admin válido até você removê-lo explicitamente).

### O painel não mostra eventos

1. Confirme que a URL do servidor e a chave de API estão corretas nas variáveis de ambiente do painel (`AGENTEYE_SERVER_URL`, `AGENTEYE_API_KEY`).
2. A chave de API do painel precisa da permissão `events:read`.
3. Confirme que eventos foram realmente ingeridos: `curl http://your-server:8080/events -H "Authorization: Bearer $ADMIN_KEY"`

### `/errors` está vazio, mas `/events` mostra linhas vermelhas

Versões mais recentes do SDK emitem falhas como eventos `agent_end` / `tool_result` / `hook_completed` com `outcome: "error"` no payload, em vez de uma linha dedicada com `event_type: "error"`. A página `/errors` agora corresponde a ambos: qualquer linha que o stream `/events` pinta de vermelho (tipo `event_type='error'` explícito, `outcome`/`status` no conjunto de falhas no payload, `is_error: true`, ou um campo `error` verdadeiro) aparece em `/errors`. Se você anteriormente via "no errors in this window" enquanto linhas vermelhas eram visíveis em `/events`, atualize o painel + servidor juntos (o filtro ampliado é `errored=true` em `GET /events`) e as duas visualizações concordarão.

### `/models`, `/tools` ou `/hooks` está lento ou falha ao carregar em intervalos de tempo amplos

**Sintoma:** em uma tabela de eventos grande (milhões de linhas), abrir `/models`, `/tools` ou `/hooks` — ou ampliar o intervalo de tempo para `7d`, `30d` ou `all` — os gráficos giram e então mostram um erro de carregamento. O servidor registra um `MEMORY_LIMIT_EXCEEDED` do ClickHouse (Código 241) ou um timeout de consulta para a requisição `latency_aggregate`.

**Causa:** builds mais antigas calculavam os rollups de latência e distribuição dessas páginas com uma consulta que lia o `payload` completo de eventos brutos e emparelhava eventos de requisição/resposta com uma classificação e junção na memória. O pico de memória da consulta crescia portanto com o tamanho da janela, então em um tenant ocupado um intervalo amplo poderia exceder o teto de memória por consulta do ClickHouse.

**Correção:** atualize para um build que inclua essa correção. O rollup agora lê apenas as colunas compactas promovidas e emparelha eventos com uma agregação em streaming, então o pico de memória não escala mais com o payload bruto — intervalos amplos ficam bem dentro do teto de memória e retornam em uma fração do tempo. A melhoria é inteiramente do lado da consulta: aplica-se a todos os dados existentes no próximo carregamento de página, sem re-ingestão ou backfill.

### Painel falha ao carregar / página em branco

Verifique os logs do container do painel:

```bash theme={null}
docker logs agenteye-dashboard
```

A causa mais comum é `AGENTEYE_SERVER_URL` ou `AGENTEYE_API_KEY` ausentes ou apontando para um servidor inacessível.

### Analytics / telemetria do painel

O painel envia analytics de uso de produto anônimos para o PostHog por padrão, roteados pelo próprio caminho `/ingest` do painel (um proxy reverso para `https://us.i.posthog.com`). Enviá-los como first-party significa que bloqueadores de anúncios do navegador não os descartam. Isso é independente da funcionalidade principal do painel:

* O **container do painel** (não o navegador) é quem alcança o PostHog. Se seu acesso de saída para `https://us.i.posthog.com` estiver bloqueado, a telemetria silenciosamente não opera; o painel funciona normalmente e nenhum erro é exibido aos usuários.
* Nenhum dado de agente, sessão ou evento é incluído, apenas o uso da UI do painel.
* Para desativar a telemetria completamente, defina `AE_ANALYTICS_DISABLED=1` no container do painel e reinicie. Veja [Telemetry & privacy](/pt-br/agenteye/deployment#telemetry--privacy) no guia de deployment.

### Analytics / telemetria da CLI

A CLI `agenteye` envia analytics de uso anônimos para o PostHog por padrão: quais comandos são executados, status de sucesso/saída e duração. Isso é independente da funcionalidade da CLI:

* A **máquina que executa a CLI** alcança `https://us.i.posthog.com` diretamente. Se seu acesso de saída estiver bloqueado, a telemetria silenciosamente não opera (o envio tem limite de tempo, então nunca atrasa um comando) e a CLI funciona normalmente.
* Nenhum dado de agente, sessão ou evento é incluído: **argumentos de comandos e valores de flags** (URL do painel, token, e-mail, ids de sessão, filtros de consulta) nunca são enviados.
* Para desativá-la, defina `AGENTEYE_ANALYTICS_DISABLED=1` (ou o cross-tool `DO_NOT_TRACK=1`) no ambiente da CLI. Veja [Telemetry & privacy](/pt-br/agenteye/cli#telemetry--privacy) no guia da CLI.

***

## Problemas no Assistente de IA

Veja [enterprise-docs/assistant.md](/pt-br/agenteye/assistant) para configuração completa.

### O botão do assistente não aparece

O botão fica oculto a menos que **todos** esses critérios sejam atendidos:

* O usuário conectado tem a permissão `agent:use`.
* `AGENTEYE_AGENT_URL` está definido no painel e o serviço `agent` está acessível.
* Um endpoint LLM está configurado no serviço `agent` (`ANTHROPIC_API_KEY`, um gateway via `ANTHROPIC_BASE_URL`, ou Bedrock/Vertex). Com nenhum definido, o agente reporta "not configured" e o botão permanece oculto.

Verifique a saúde do agente a partir do host do painel: `curl http://agent:9100/health` deve retornar `{"status":"ok","llm_configured":true,...}`.

### O assistente diz que não consegue ler algo

As ferramentas são controladas por usuário. Se um usuário não tem `evaluations:read` (ou `events:read`, `dashboards:read`), as ferramentas correspondentes não são oferecidas e o assistente dirá que não consegue ler aquele dado. Conceda a permissão de leitura relevante.

### "assistant not configured" (HTTP 503) ao enviar

O container `agent` não tem endpoint LLM configurado, ou o `AGENTEYE_AGENT_TOKEN` do painel não corresponde ao do agente. Defina ambos e reinicie.

### O container `agent` reinicia / fica sem memória sob carga

Cada conversa gera um processo filho de curta duração. Certifique-se de que o container executa com um processo init (a imagem usa `tini`; no Compose defina `init: true`) e forneça limites de memória adequados. Reduza `AGENTEYE_AGENT_MAX_STEPS` se necessário.

***

## Problemas na CLI

### `agenteye` falha ao iniciar com `ModuleNotFoundError: No module named 'click'`

Uma instalação nova da CLI `agenteye` na versão **0.1.6** pode travar na inicialização com:

```
ModuleNotFoundError: No module named 'click'
```

A versão 0.1.6 dependia de `click` ser instalado indiretamente pelo `typer`; versões atuais do `typer` não o incluem mais, então um ambiente limpo acaba sem o pacote. **Atualize para a versão 0.1.7 ou mais recente**, que depende de `click` diretamente:

```bash theme={null}
pipx upgrade agenteye      # se instalado com pipx (ou: pipx install --force agenteye)
uv tool upgrade agenteye   # se instalado com uv
pip install --upgrade agenteye
```

Veja [enterprise-docs/cli.md](/pt-br/agenteye/cli) para orientações de instalação.

***

## Problemas no Python SDK

### Nenhum arquivo aparecendo em `$AGENTEYE_HOME/events/`

O SDK armazena eventos em buffer e faz flush a cada 500 ms por padrão. Se o processo encerrar antes do flush, os eventos podem ser perdidos. Chame `agenteye.configure(flush_interval=0.1)` para flush mais rápido em scripts de curta duração, ou garanta que seu processo execute por tempo suficiente para um ciclo de flush.

Se `AGENTEYE_HOME` estiver definido, verifique se o SDK está escrevendo em `$AGENTEYE_HOME/events/` e não em `~/.agenteye/events/` (requer SDK ≥ 0.0.1b5).

### `ValueError: Reserved field names cannot be used as custom fields`

Os nomes `timestamp`, `type` e `environment` são reservados e não podem ser usados como campos personalizados. Passá-los gera:

```
ValueError: Reserved field names cannot be used as custom fields: [...]
```

Renomeie o campo personalizado com problema. Observe que `session_id` e `agent_id` são parâmetros explícitos da chamada de evento, não campos personalizados; passar qualquer um deles novamente como campo personalizado gera `TypeError`.

***

## Problemas no Monitoramento de Saúde

### Nenhum alerta chegando no Slack (Robusta)

O alerta de saúde do Robusta é **opt-in**; não envia nada até ser instalado e apontado para um canal do Slack. Verifique o release e seu sink:

```bash theme={null}
kubectl get pods -n robusta          # robusta-runner + robusta-forwarder devem estar Running
kubectl logs -n robusta -l app=robusta-runner --tail=50
```

Causas comuns: `api_key` / `slack_channel` do Slack não foram definidos (ou o token foi revogado); o `api_key` é um token de relay em nuvem do Robusta (`robusta integrations slack`), mas o `disableCloudRouting: true` incluído precisa de um **bot token** do Slack auto-hospedado (`xoxb-…`), ou defina `disableCloudRouting: false`; o `scope` do sink exclui o namespace onde seus pods estão (os valores incluídos limitam a `agenteye`); ou nenhuma falha ocorreu ainda. Force um alerta de teste derrubando um pod:

```bash theme={null}
kubectl -n agenteye delete pod -l app=clickhouse   # será recriado
```

Veja [enterprise-docs/health-monitoring.md](/pt-br/agenteye/health-monitoring#2-pod-failure-alerting-with-robusta-opt-in) para instalação e configuração.

### Servidor continua alternando entre `NotReady`

A sonda de prontidão atinge `/ready`, que falha quando Postgres ou ClickHouse está inacessível. Se o servidor alterna entre `NotReady`, uma dependência está intermitentemente indisponível; verifique os pods do ClickHouse e Postgres e os valores `CLICKHOUSE_URL` / `DATABASE_URL` do servidor. Confirme o que `/ready` reporta:

```bash theme={null}
kubectl -n agenteye exec deploy/server -- sh -c 'curl -s localhost:8080/ready'
```

Essa sonda é deliberadamente tolerante (limite de falha generoso), então alternâncias sustentadas indicam um problema real de dependência em vez de uma sonda muito agressiva. A liveness permanece em `/health`, então a alternância de prontidão **não** reiniciará o pod.

## Problemas no Monitoramento de Certificados

### CronJob não está enviando notificações para o Slack

O CronJob `cert-renewal-check` requer uma URL de webhook do Slack armazenada em um Secret. Verifique se existe:

```bash theme={null}
kubectl get secret cert-renewal-notify-config -n agenteye
```

Se estiver faltando, crie-o:

```bash theme={null}
kubectl create secret generic cert-renewal-notify-config \
  --namespace agenteye \
  --from-literal=SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
```

Sem o secret, o CronJob ainda executa e registra os resultados no stdout. Verifique os logs com:

```bash theme={null}
kubectl logs -n agenteye -l job-name --tail=50
```

### Certificado do cliente expirou antes de uma notificação ser recebida

O CronJob executa a cada 12 horas. Se não esteve em execução, verifique seu status:

```bash theme={null}
kubectl get cronjob cert-renewal-check -n agenteye
```

Dispare uma verificação manual:

```bash theme={null}
kubectl create job --from=cronjob/cert-renewal-check manual-cert-check -n agenteye
kubectl logs -n agenteye -l job-name=manual-cert-check
```

Para reemitir o certificado expirado imediatamente:

```bash theme={null}
cd base/certificates/client-certs
./issue-client-cert.sh <cluster-name>
```

Em seguida, aplique o `collector-mtls-secret.yaml` regenerado nos clusters que executam seus coletores e reinicie-os:

```bash theme={null}
kubectl apply -f collector-mtls-secret.yaml -n <collector-namespace>
```

***

## Problemas de Backup

### `agenteye-backup` falha com "No space left on device"

O CronJob `agenteye-backup` despeja Postgres + ClickHouse em um volume de rascunho `emptyDir` chamado `backup-tmp` (padrão `30Gi`), depois **transmite em streaming** o arquivo `tar` diretamente para o S3 — o arquivo comprimido nunca é gravado de volta no rascunho, então o rascunho só precisa conter os *dumps brutos*, não dumps + uma segunda cópia de arquivo em disco. Um pod despejado / `No space left on device` portanto significa que os **dumps brutos** excedem o tamanho do rascunho (o dump de `events` do ClickHouse domina e cresce ao longo do tempo). Verifique os logs do job com falha:

```bash theme={null}
kubectl logs -n agenteye -l job-name=<failed agenteye-backup job>
```

Correção: no seu overlay, aumente o `sizeLimit` do `emptyDir` `backup-tmp` do CronJob acima do total de dumps brutos, e certifique-se de que o armazenamento efêmero do nó pode realmente armazená-lo (`sizeLimit` é um limite, não uma reserva). Se os dumps ultrapassarem o disco de um único nó, substitua o `emptyDir` por um PVC (EBS/PD) para `backup-tmp`, ou comprima os dumps na fonte.

> Versões mais antigas gravavam o `.tar.gz` no mesmo rascunho de `20Gi` dos dumps, então `dumps + arquivo` o estouravam e o pod era despejado **antes** do upload ser executado — o que parece uma falha do S3, mas na verdade é disco. A transmissão em streaming do upload remove esse problema de duplicação.

### `agenteye-backup` falha ao instalar `curl`

O job executa na imagem `postgres:16` e instala `curl` na inicialização para o dump HTTP do ClickHouse. Em um cluster sem acesso de saída aos mirrors de pacotes Debian, a etapa `apt-get` falha. Permita esse acesso de saída do pod de backup, ou inclua `curl` em uma imagem de backup espelhada/personalizada e referencie-a no seu overlay.

### `agenteye-backup` executa, mas nada chega ao armazenamento de objetos

A base vem com um `BACKUP_BUCKET` real (`ts-prod-agenteye/backups`) e a ServiceAccount `agenteye-backup`. O job **transmite em streaming** o arquivo para o S3 (`tar cz … | aws s3 cp - s3://…`). Se o pod de backup não tem acesso de escrita ao bucket, o upload falha — e porque o script executa sob `set -euo pipefail`, uma falha em qualquer ponto desse pipe **falha** todo o job na etapa `upload` em vez de silenciosamente não fazer nada (o trap EXIT do pod registra `backup FAILED during step: upload`). Esta também é a etapa que você alcança *após* corrigir um despejo por espaço em disco, então se os backups eram anteriormente despejados na etapa de arquivo, verifique se o upload agora chega. Busque nos logs do job com falha o erro de acesso ao S3:

```bash theme={null}
kubectl logs -n agenteye -l job-name=<failed agenteye-backup job> | grep -iE 's3|upload|denied'
```

Correção: no seu overlay defina `BACKUP_BUCKET` para um bucket que você possui e anote a ServiceAccount `agenteye-backup` existente com acesso de escrita (IRSA / Workload Identity / Pod Identity). Veja a seção **Backups** de [enterprise-docs/kubernetes-deployment.md](/pt-br/agenteye/kubernetes-deployment).

***

## Avaliações / sessões / queries com ClickHouse

### A barra lateral da página `/queries` está vazia após a atualização

Três tabelas (`events`, `evaluations`, `agent_sessions`) são esperadas. Se a barra lateral do SchemaBrowser estiver vazia após a atualização, o servidor falhou ao aplicar o DDL do ClickHouse na inicialização. Verifique os logs do servidor por `failed to apply CH DDL statement`:

```bash theme={null}
kubectl logs -n agenteye deploy/server | grep -E 'clickhouse|CH DDL'
```

A causa mais comum é o ClickHouse estar inacessível enquanto as migrações executam. O servidor recusa iniciar se não conseguir alcançar o CH, então um pod travado geralmente tem um `CrashLoopBackOff` em vez de uma página de queries silenciosamente quebrada, mas um DDL parcialmente aplicado (um statement OK, os próximos com 5xx) deixa o schema incompleto. Reinicie o pod do servidor após verificar que o CH está acessível:

```bash theme={null}
kubectl rollout restart deploy/server -n agenteye
```

### Novas avaliações não aparecem em `/sessions` ou `/queries`

Após a atualização, novas avaliações são escritas no ClickHouse, não no Postgres, e aparecem em `/sessions` (controlado por `evaluations:read`) e em `/queries`. Se não aparecerem:

1. Confirme que o pipeline do avaliador está habilitado (`EVALUATOR_ENDPOINT` definido no servidor) e produzindo resultados terminais; verifique linhas de log `evaluation_finalized`.
2. Confirme que o CH está acessível a partir do servidor: `kubectl exec -n agenteye deploy/server -- curl -fsS http://clickhouse:8123/ping`.
3. Faça uma verificação pontual na tabela CH: `kubectl exec -n agenteye clickhouse-0 -- clickhouse-client -q 'SELECT count() FROM agenteye.evaluations'`.

### Queries falham sob carga com "Memory limit exceeded", ou ClickHouse tem `OOMKilled`

**Sintoma:** sob carga pesada de painel/queries, páginas analíticas (stream de eventos, `/sessions`, visualização de modelos/latência, editor SQL) começam a falhar ou expirar; o servidor alterna brevemente para `NotReady`; e o pod do ClickHouse mostra contagem de reinicializações crescente. Isso é quase sempre **memória**, não CPU ou disco.

**Confirme que é memória** (não um problema de throughput que replicação resolveria):

1. Verifique se o pod teve kills por falta de memória:
   ```bash theme={null}
   kubectl -n agenteye describe pod clickhouse-0 | grep -iE 'Restart Count|Last State|Reason|OOMKilled'
   ```
   `Reason: OOMKilled` / `Exit Code: 137` com contagem de reinicializações crescente é o indicador.

2. Pergunte ao ClickHouse o que ele está rejeitando:
   ```bash theme={null}
   kubectl -n agenteye exec clickhouse-0 -- clickhouse-client -q \
     "SELECT name, value FROM system.errors WHERE value>0 ORDER BY value DESC"
   ```
   Uma contagem grande de `MEMORY_LIMIT_EXCEEDED` é a assinatura. A mensagem diz *"maximum: N GiB"* — esse **N é `0,9 × o limite de memória do pod`** (o `max_server_memory_usage_to_ram_ratio` em `deploy/base/clickhouse/configmap.yaml`). Se suas leituras pesadas precisam de mais que N, são rejeitadas.

3. Descarte as coisas que *não* são o problema — se CPU, contagem de partes e disco estão todos baixos, adicionar réplicas/sharding seria custo desperdiçado:
   ```bash theme={null}
   kubectl -n agenteye top pod clickhouse-0
   kubectl -n agenteye exec clickhouse-0 -- clickhouse-client -q \
     "SELECT table, count() parts FROM system.parts WHERE active AND database='agenteye' GROUP BY table"
   ```

**Causa:** o limite de memória do pod do ClickHouse é muito pequeno para o conjunto de trabalho analítico. As leituras mais pesadas puxam a coluna `payload` JSON bruta, executam `JSONExtract*` sobre ela e usam `FINAL` — cada uma pode precisar de vários GiB. Se os caches configurados (`mark_cache_size` + `uncompressed_cache_size`) são maiores que o pod, eles agravam: caches são cobrados contra o mesmo orçamento e competem com a memória de queries.

**Correção — escale a memória do ClickHouse:**

1. Aumente o limite de memória do ClickHouse no seu overlay fazendo patch nos `resources` do container do StatefulSet `clickhouse` (o mesmo mecanismo de overlay usado para `resources` de outros componentes). O orçamento utilizável do servidor é `0,9 × limite`, então um limite de `6Gi` dá \~5,4 GiB, `16Gi` dá \~14 GiB. Defina `requests.memory` como um piso real também, para que o scheduler o reserve. Aplicar isso **recria o pod do CH** (réplica única → \~30–60s de tempo de inatividade de analytics); faça-o em uma janela de baixo tráfego.
2. Mantenha os caches em `deploy/base/clickhouse/configmap.yaml` proporcionais ao limite — caches pequenos (algumas centenas de MiB) são seguros em um pod pequeno; aumente-os apenas junto com um aumento correspondente no limite de memória. O `max_memory_usage` por query é definido explicitamente no perfil `users.xml` (veja a seção de nó fixo abaixo) e é mantido abaixo do limite em nível de servidor (`0,9 × limite`) para que nenhuma query única possa usar *mais* RAM que o container tem.
3. Se o próprio nó é o teto, verifique a memória do host que o ClickHouse consegue ver:
   ```bash theme={null}
   kubectl -n agenteye exec clickhouse-0 -- clickhouse-client -q \
     "SELECT formatReadableSize(value) FROM system.asynchronous_metrics WHERE metric='OSMemoryTotal'"
   ```
   Se isso for apenas um pouco acima do limite do pod, mova o ClickHouse para um nó maior (otimizado para memória) — via seletor de nó/affinity no seu overlay — antes de aumentar o limite ainda mais.

**Quando você não pode adicionar memória: execute queries na RAM e falhe rapidamente — não derrame em um disco lento.** Se o nó é fixo e o pod não pode crescer, limite o que qualquer query pode usar (para que uma query não tome o nó inteiro) e, em um **disco de dados lento (não-SSD)**, **não** permita que grandes agregações/ordenações derramem em disco. Derramar em um disco lento é mais lento que o timeout de leitura do cliente do servidor, então uma query derramando retorna um `500` do painel no meio do caminho enquanto o ClickHouse continua processando — manter queries na RAM e rejeitar rapidamente a rara que excede o orçamento (`MEMORY_LIMIT_EXCEEDED`, sub-segundo) é o que restaura o carregamento. Observe uma peculiaridade do ClickHouse ao aplicar estas configurações:

* **Estas são configurações de *perfil*, e o ClickHouse lê `<profiles>` apenas de `users_config` (`users.xml` / `users.d/*.xml`) — nunca de `config.d`.** Um bloco `<profiles>` colocado em `config.d/agenteye.xml` é **silenciosamente ignorado** (`max_execution_time`, `max_memory_usage`, etc. simplesmente não se aplicam). A configuração incluída portanto as fornece como uma chave `users.xml` no ConfigMap `clickhouse-config`, montada em `/etc/clickhouse-server/users.d/agenteye.xml`.
* Os padrões incluídos: `max_memory_usage` (teto por query — uma query não pode consumir todo o orçamento do servidor), `max_bytes_before_external_group_by` / `max_bytes_before_external_sort` = **`0` (derrame desativado)** para que queries fiquem na RAM em vez de arrastar no disco lento, e `max_execution_time` (proteção contra runaway, alinhado com o timeout de leitura do cliente do servidor).
* **Verifique se estão ativos** (assim você também detecta o problema do config.d):
  ```bash theme={null}
  kubectl -n agenteye exec clickhouse-0 -- clickhouse-client -q \
    "SELECT name, value FROM system.settings
     WHERE name IN ('max_memory_usage','max_bytes_before_external_group_by','max_execution_time')"
  ```
  Espere um `max_memory_usage` diferente de zero e `max_bytes_before_external_group_by = 0`. Se `max_memory_usage` mostrar `0`/padrão, o perfil não está sendo aplicado — verifique se as configurações estão em um mount `users.d`, não em `config.d`.

Trade-off: com derrame desativado, uma query cujo conjunto de trabalho excede `max_memory_usage` é **rejeitada** (`MEMORY_LIMIT_EXCEEDED`) em vez de completar lentamente — em um disco lento essa rejeição rápida é preferível, porque uma query derramando excederia o timeout do cliente e falharia de qualquer forma. Se seu disco de dados é **rápido (SSD)**, você pode em vez disso aumentar os limites `max_bytes_before_external_*` para permitir que queries grandes derramem para disco e completem.

***

## Multi-tenancy (organizações)

### Erros durante a atualização que habilita organizações (pods mistos antigos/novos)

**Sintoma:** durante um deploy em rolagem da versão que habilita organizações, algumas requisições falham: os logs do servidor mostram `there is no unique or exclusion constraint matching the ON CONFLICT specification` no caminho de `api_keys`, e/ou canais de alerta/Slack/webhook param de disparar enquanto o rollout está em andamento.

**Causa:** a atualização substitui o antigo índice único de escopo de instância em `api_keys(name)` por índices parciais por organização, e move as configurações de canal de alerta (e `default_user_permissions`) da tabela global `settings` para `org_settings` por organização. Um pod **antigo** do servidor ainda emite `ON CONFLICT (name)` (agora sem constraint correspondente) e ainda lê a configuração de canal das antigas linhas de `settings` (agora vazias). Pods antigos e novos não podem coexistir com segurança nesses dois caminhos.

**Correção:** não faça um rollout lento desta atualização específica entre versões mistas. Faça a transição de forma limpa: escale o servidor antigo para zero (ou use uma breve janela de manutenção) e suba a nova versão junto com suas migrações, em vez de executar réplicas antigas e novas lado a lado. O tráfego normal e a ingestão retomam imediatamente após a transição; isso afeta apenas a janela de transição de versão.

### O provisionamento de uma organização falha em `CREATE USER` / `CREATE ROW POLICY`, ou uma organização consegue ler os dados de outra

**Sintoma:** criar uma organização retorna um erro mencionando `CREATE USER`, `CREATE ROW POLICY` ou "access management is disabled"; ou, pior, membros de uma organização veem eventos/avaliações de outra no editor SQL ou assistente.

**Causa:** o isolamento por organização é aplicado por um usuário ClickHouse dedicado + política de linha por organização. Isso requer que o **gerenciamento de acesso** SQL esteja habilitado e que `users_without_row_policies_can_read_rows=false` esteja configurado no ClickHouse. Com o gerenciamento de acesso desativado, o provisionamento não consegue criar o usuário/política; com o padrão da política de linha deixado no seu valor permissivo, um usuário que tem SELECT mas nenhuma política lê **todas** as linhas (falha aberta).

**Correção:** use a configuração incluída em `deploy/base/clickhouse/`, que define ambos. Se você usa sua própria configuração do ClickHouse, habilite o gerenciamento de acesso SQL no usuário interno do servidor e defina `users_without_row_policies_can_read_rows=false` (veja `deploy/base/clickhouse/configmap.yaml`), depois reinicie o ClickHouse e re-crie a organização com a CLI `agenteye-orgctl` (veja [enterprise-docs/tenant-management.md](/pt-br/agenteye/tenant-management)).

### Usuários da organização perdem acesso ao ClickHouse após alterar `ORG_CH_SECRET`

**Sintoma:** o editor SQL e o assistente de IA de repente retornam falhas de autenticação do ClickHouse para todas as organizações, imediatamente após `ORG_CH_SECRET` ser alterado ou definido de forma inconsistente entre réplicas.

**Causa:** a senha do ClickHouse de cada organização é derivada como um HMAC de `ORG_CH_SECRET`. Rotacioná-lo (ou executar réplicas com valores diferentes) invalida a credencial ClickHouse armazenada de cada organização; a senha derivada não corresponde mais ao usuário provisionado.

**Correção:** defina `ORG_CH_SECRET` como um único valor forte **antes** de provisionar uma segunda organização e mantenha-o estável e idêntico em cada réplica do servidor. A reconciliação de inicialização do servidor re-provisiona o usuário ClickHouse de cada organização a partir do secret atual na inicialização, então uma reinicialização do servidor em todas as réplicas (com o secret consistente) corrige os usuários órfãos. Trate o valor como um secret de longa duração; não o rotacione casualmente. Como rede de segurança, se `ORG_CH_SECRET` for deixado no valor padrão de desenvolvimento integrado (ou seja, não definido), a reconciliação de inicialização **ignora** organizações não-padrão e registra um erro em vez de reescrever suas credenciais ClickHouse para o valor de desenvolvimento conhecido publicamente, então uma única réplica que reinicia sem o secret não pode quebrar as outras réplicas. Defina o secret de forma consistente e reinicie para provisionar essas organizações.

### O assistente de IA retorna 400 / recusa conversar após habilitar organizações

**Sintoma:** o dock do assistente carrega, mas cada mensagem retorna um erro (HTTP `400`), e o agente registra uma requisição `/chat` sem organização rejeitada.

**Causa:** o agente é ciente de organização e falha de forma fechada; ele rejeita um `/chat` que não carrega contexto de organização. Isso acontece durante um rollout de transição onde o agente foi atualizado, mas o painel que envia a requisição ainda não está ciente de organização.

**Correção:** conclua o rollout para que o painel envie contexto de organização (o estado final normal, nenhum flag necessário). Para cobrir o período enquanto um painel não ciente de organização fala com um agente ciente de organização, defina `AGENTEYE_AGENT_ALLOW_NO_ORG=1` no serviço `agent` para que ele recue para a organização `default` em vez de recusar, e limpe-o assim que a atualização do painel chegar. Veja a referência de variáveis de ambiente em [enterprise-docs/assistant.md](/pt-br/agenteye/assistant#environment-variable-reference).

***

## Auditorias

### Uma auditoria nunca é executada (próxima execução continua adiando, sem histórico de execução)

**Sintoma:** a página de auditoria mostra *last run: never*, ou `next run` continua avançando para o futuro sem que apareça uma linha no histórico de execução.

**Causa:** a auditoria está desativada (auditorias desativadas não têm entrada na fila), ou os workers de auditoria do servidor estão falhando ao reivindicar trabalho.

**Correção:** confirme que a auditoria está **habilitada** (o botão executar agora requer isso). Então verifique os logs do servidor por `audits pipeline started` na inicialização e por erros `audits:` — uma linha `claim_due failed` aponta para conectividade do Postgres. `AUDIT_WORKERS` padrão é `1`; deve ser ≥ 1 para qualquer auditoria executar.

### Execuções de auditoria têm sucesso, mas não encontram nada

**Sintoma:** o histórico de execução mostra `succeeded` com `findings: 0` mesmo que `/errors` claramente mostre falhas.

**Causa:** a janela de varredura não cobre as falhas, ou os filtros de escopo as excluem.

**Correção:** verifique a janela da linha de execução (`window_from → window_to`) contra quando as falhas ocorreram — no modo `since_last`, cada execução só varre desde a última execução bem-sucedida, então falhas mais antigas são vistas apenas pela *primeira* execução ou por uma auditoria de janela `fixed`. Amplie `scope` (ambientes / ids de agente). As estatísticas de execução mostram `policy_hits` (quantas políticas determinísticas dispararam) e `improvements` (quantos a investigação de IA registrou) — se ambos são 0, a janela/escopo genuinamente não viu nada.

### A execução diz `analysis_unavailable` e produz apenas descobertas de política

**Sintoma:** as estatísticas de execução incluem `analysis_unavailable` e as únicas descobertas são `kind: policy`; nenhuma melhoria de IA aparece.

**Causa:** a investigação agêntica não pôde executar: o servidor não consegue alcançar o serviço agent (`AGENTEYE_AGENT_URL` / `AGENTEYE_AGENT_TOKEN` não definidos no **servidor** — a auditoria reutiliza a conexão do assistente), o serviço assistente não tem LLM configurado, ou a chamada errou/expirou (a string `analysis_unavailable` tem o detalhe). A passagem de política determinística é o piso — sempre executa — então a auditoria ainda tem sucesso com suas descobertas de segurança.

**Correção:** defina `AGENTEYE_AGENT_URL` (por exemplo, `http://agent:9100`) e `AGENTEYE_AGENT_TOKEN` no **servidor** — os mesmos valores que o assistente do painel já usa (os manifestos/compose incluídos agora os conectam) — e configure um LLM no serviço assistente (veja [assistant.md](/pt-br/agenteye/assistant)), depois execute novamente. Uma investigação grande pode precisar de um `AUDIT_LLM_TIMEOUT_MS` maior (servidor) — mantenha-o acima do `AGENTEYE_AUDIT_TIMEOUT_MS` do agente.

### O sandbox de código da auditoria está desativado (`sandbox_available: false`)

**Sintoma:** o `/health` do agente mostra `sandbox_available: false`, e as execuções de auditoria observam que o sandbox está indisponível; a IA investiga apenas com SQL.

**Causa:** o sandbox bubblewrap dentro do pod precisa de **namespaces de usuário não privilegiados**, que o perfil seccomp do pod ou o kernel do nó está bloqueando.

**Correção:** defina `seccompProfile: Unconfined` (k8s) ou `security_opt: [seccomp:unconfined]` (compose) no agente, e confirme que o kernel do nó permite namespaces de usuário não privilegiados (algumas imagens gerenciadas, como GKE COS, os desativam). Onde você não pode habilitá-lo, isso é esperado e seguro — o auditor degrada para SQL apenas automaticamente. Veja [deployment.md](/pt-br/agenteye/deployment).

### Relatório de e-mail de auditoria não entregue

**Sintoma:** uma auditoria revelou novas descobertas, mas nenhum e-mail chegou.

**Causa:** a auditoria não tem um canal de **e-mail** anexado, o e-mail está desativado em toda a organização em `alerts.enabled_channels`, não há destinatários, ou o SMTP não está configurado.

**Correção:** anexe um canal de e-mail à auditoria, certifique-se de que `email` está em `alerts.enabled_channels`, defina destinatários (no canal ou via `alerts.email_default_recipients`) e configure o SMTP (o mesmo transporte que os e-mails de alertas + OTP usam). O e-mail é enviado apenas quando uma execução produz **pelo menos uma nova** descoberta.

### Um padrão silenciado ou descartado mantém sua página de descoberta antiga, mas nunca é re-classificado

**Sintoma:** após silenciar uma descoberta, execuções posteriores nunca surfaceiam aquele padrão novamente — mesmo que ele ainda ocorra.

**Causa:** esse é o comportamento projetado: silenciar/descartar são supressões duráveis codificadas pela impressão digital do padrão.

**Correção:** abra a descoberta e use **reopen** para limpar a supressão; a próxima execução classificará o padrão novamente. Use **resolve** (não silenciar) para padrões "corrigidos" sobre os quais você gostaria de ser notificado se regredirem.

***

## Obtendo Ajuda

Entre em contato com `support@exosphere.host` com:

* Sua versão do AgentEye (da tag de release)
* Logs relevantes do container (`docker logs <container>`)
* Uma descrição do problema e o que você já tentou
