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

# Kubernetes Operator (AIOps)

> Gerencie instâncias ChatCLI e uma plataforma AIOps autônoma no Kubernetes com 17 CRDs, 54 tipos de remediação, análise de logs/métricas, integração GitOps e diagnóstico code-aware.

O **ChatCLI Operator** vai além do gerenciamento de instâncias. Ele implementa uma **plataforma AIOps completa** que detecta anomalias autônomamente, correlaciona sinais, solicita análise de IA e executa remediação — tudo sem dependências externas além do provedor LLM.

A plataforma suporta **Deployments, StatefulSets, DaemonSets, Jobs e CronJobs**, integra-se com **Helm, ArgoCD e Flux** para remediação GitOps-aware, analisa **logs de aplicação com extração de stack traces** (Java, Go, Python, Node.js), correlaciona **métricas Prometheus** com incidentes, e permite vincular **repositórios de código-fonte** para diagnóstico code-aware.

## API Group e CRDs

O operator usa o API group `platform.chatcli.io/v1alpha1` com 17 Custom Resource Definitions:

| CRD                       | Short Name | Descrição                                                                                     |
| ------------------------- | ---------- | --------------------------------------------------------------------------------------------- |
| **Instance**              | `inst`     | Instância do servidor ChatCLI (Deployment, Service, RBAC, PVC)                                |
| **Anomaly**               | `anom`     | Sinal bruto do K8s Watcher (restarts, OOM, falhas de deploy, etc.)                            |
| **Issue**                 | `iss`      | Incidente correlacionado agrupando múltiplas anomalias                                        |
| **AIInsight**             | `ai`       | Análise de causa raiz gerada por IA com contexto enriquecido (logs, métricas, código, GitOps) |
| **RemediationPlan**       | `rp`       | Ações concretas para resolver o problema (runbook ou IA agêntica)                             |
| **Runbook**               | `rb`       | Procedimentos operacionais manuais (opcional)                                                 |
| **PostMortem**            | `pm`       | Relatório de incidente auto-gerado após resolução (todos os modos)                            |
| **SourceRepository**      | `srcrepo`  | Vincula workloads a repositórios git para diagnóstico code-aware                              |
| **NotificationPolicy**    | `np`       | Política de notificações multi-canal com throttling e templates                               |
| **EscalationPolicy**      | `ep`       | Cadeia de escalação com níveis e timeouts (L1→L2→L3)                                          |
| **ServiceLevelObjective** | `slo`      | SLO com burn rate alerting multi-janela (modelo Google SRE)                                   |
| **IncidentSLA**           | `sla`      | SLA de resposta/resolução por severidade com business hours                                   |
| **ApprovalPolicy**        | `ap`       | Política de aprovação auto/manual/quorum com change windows                                   |
| **ApprovalRequest**       | `ar`       | Workflow de aprovação com blast radius e evidências                                           |
| **ClusterRegistration**   | `cr`       | Federação multi-cluster com kubeconfig e health check                                         |
| **AuditEvent**            | `ae`       | Trilha de auditoria imutável (append-only)                                                    |
| **ChaosExperiment**       | `chaos`    | Experimentos de chaos engineering com 7 tipos e safety checks                                 |

<Info>
  Para documentação detalhada de cada componente da plataforma AIOps, consulte as páginas dedicadas em [AIOps Platform](/pt/features/aiops/notifications).
</Info>

## Instalação do Operator

Um único comando instala tudo: **17 CRDs + RBAC + Deployment + Service + Dashboard**.

<Tabs>
  <Tab title="Via OCI Registry (recomendado)">
    Instala direto do GHCR — **não precisa clonar o repositório**:

    ```bash theme={"system"}
    helm install chatcli-operator \
      oci://ghcr.io/diillson/charts/chatcli-operator \
      --namespace chatcli-system \
      --create-namespace
    ```

    Para fixar uma versão específica:

    ```bash theme={"system"}
    helm install chatcli-operator \
      oci://ghcr.io/diillson/charts/chatcli-operator \
      --version 1.152.0 \
      --namespace chatcli-system \
      --create-namespace
    ```
  </Tab>

  <Tab title="Via path local (se clonou o repo)">
    ```bash theme={"system"}
    helm install chatcli-operator ./deploy/helm/chatcli-operator/ \
      --namespace chatcli-system \
      --create-namespace
    ```
  </Tab>
</Tabs>

<Tip>
  O chart do **operator** (`chatcli-operator`) é separado do chart do **server** (`chatcli`). O operator gerencia os controllers e o dashboard AIOps. O server é deployado via Instance CR ou pelo chart `chatcli` com watcher habilitado.
</Tip>

<Accordion title="Valores configuráveis">
  ```bash theme={"system"}
  # Com Prometheus para métricas de incidentes
  helm install chatcli-operator \
    oci://ghcr.io/diillson/charts/chatcli-operator \
    --namespace chatcli-system --create-namespace \
    --set prometheusUrl="http://prometheus-server.monitoring.svc:9090"

  # Com imagem customizada
  helm install chatcli-operator \
    oci://ghcr.io/diillson/charts/chatcli-operator \
    --namespace chatcli-system --create-namespace \
    --set image.repository=myregistry/chatcli-operator \
    --set image.tag=1.152.0

  # Com ServiceMonitor para Prometheus Operator
  helm install chatcli-operator \
    oci://ghcr.io/diillson/charts/chatcli-operator \
    --namespace chatcli-system --create-namespace \
    --set serviceMonitor.enabled=true
  ```

  | Valor                    | Padrão                              | Descrição                                     |
  | ------------------------ | ----------------------------------- | --------------------------------------------- |
  | `image.repository`       | `ghcr.io/diillson/chatcli-operator` | Imagem do operator                            |
  | `image.tag`              | `latest`                            | Tag da imagem                                 |
  | `replicaCount`           | `1`                                 | Réplicas (leader election ativo por padrão)   |
  | `api.port`               | `8090`                              | Porta do dashboard web e REST API             |
  | `prometheusUrl`          | `""`                                | URL do Prometheus para coleta de métricas     |
  | `leaderElect`            | `true`                              | Leader election para HA                       |
  | `serviceMonitor.enabled` | `false`                             | Criar ServiceMonitor para Prometheus Operator |
</Accordion>

<Accordion title="Instalação manual via kubectl (alternativa)">
  ```bash theme={"system"}
  kubectl apply -f operator/config/crd/bases/
  kubectl apply -f operator/config/rbac/role.yaml
  kubectl apply -f operator/config/manager/manager.yaml
  ```
</Accordion>

<Accordion title="Build via Docker (opcional)">
  ```bash theme={"system"}
  # Build a partir da raiz do repositório
  docker build -f operator/Dockerfile -t myregistry/chatcli-operator:dev .

  # Ou via Make
  cd operator
  make docker-build IMG=myregistry/chatcli-operator:dev
  make docker-push IMG=myregistry/chatcli-operator:dev
  ```
</Accordion>

## Arquitetura da Plataforma AIOps

```mermaid theme={"system"}
graph TD
    subgraph "ChatCLI Server"
        W[K8s Watcher<br/>collectors] --> GA[GetAlerts RPC]
        AI_RPC[AnalyzeIssue RPC<br/>LLM call]
        AG_RPC[AgenticStep RPC<br/>observe-decide-act]
    end

    subgraph "Operator"
        WB[WatcherBridge<br/>polls cada 30s] -->|gRPC| GA
        WB -->|cria| ANOM[Anomaly CR]
        ANOM -->|AnomalyReconciler<br/>correlação| ISS[Issue CR]
        ISS -->|IssueReconciler<br/>cria| INSIGHT[AIInsight CR]
        INSIGHT -->|AIInsightReconciler<br/>gRPC| AI_RPC
        AI_RPC -->|análise + ações| INSIGHT
        ISS -->|cria| PLAN[RemediationPlan CR]
        PLAN -->|RemediationReconciler<br/>executa| ACTIONS[54 action types:<br/>Scale / Restart / Rollback / Patch<br/>HelmRollback / ArgoSync / AdjustHPA<br/>CordonNode / DrainNode / ResizePVC...]
        PLAN -->|modo agêntico<br/>gRPC loop| AG_RPC
        AG_RPC -->|next action| PLAN
        ACTIONS -->|sucesso| RESOLVED[Issue Resolved]
        ACTIONS -->|falha| RETRY[Retry ou Escalate]
        RESOLVED -->|agêntico| PM[PostMortem CR]
    end

    style ANOM fill:#f9e2af,color:#000
    style ISS fill:#fab387,color:#000
    style INSIGHT fill:#89b4fa,color:#000
    style PLAN fill:#a6e3a1,color:#000
    style RESOLVED fill:#a6e3a1,color:#000
    style RETRY fill:#f38ba8,color:#000
    style PM fill:#cba6f7,color:#000
```

### O que o Operator Gerencia

Além dos CRDs e reconcilers, o operator provê:

* **REST API Gateway** (`:8090`) com 30+ endpoints para incidents, SLOs, approvals, analytics, clusters e audit
* **Web Dashboard embutido** acessível em `http://operator:8090/`
* **Grafana dashboards pré-configurados** disponíveis em `deploy/grafana/` para importação automática via sidecar
* **20+ métricas Prometheus** cobrindo issues, remediações, SLOs, notificações e aprovações

### Pipeline Autônomo

| Fase                   | Componente                            | O que Faz                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ---------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **1. Detecção**        | WatcherBridge                         | Consulta `GetAlerts` do servidor a cada 30s. Cria Anomaly CRs (dedup SHA256). Invalida dedup quando Issue atinge estado terminal.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **2. Correlação**      | AnomalyReconciler + CorrelationEngine | Agrupa anomalias por recurso + janela temporal. Calcula risk score e severidade. Cria/atualiza Issue CRs com `signalType`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| **3. Análise**         | AIInsightReconciler + 6 enrichers     | Coleta contexto K8s (Deployments, StatefulSets, DaemonSets, Jobs, CronJobs, HPAs), **análise avançada de logs** (stack traces Java/Go/Python/Node.js, 24+ error patterns), **métricas Prometheus** (CPU/mem/latency trends), **GitOps** (Helm/ArgoCD/Flux status), **código-fonte** (correlação commit↔incidente), **cascade analysis** (cross-service).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| **4. Remediação**      | IssueReconciler                       | Selecao de runbook validada por IA: **(a)** encontra TODOS os runbooks candidatos (multi-runbook por trigger), **(b)** IA válida cada um contra a causa raiz (`RUNBOOK_APPROVED: nome` ou `RUNBOOK_REJECTED`), **(c)** se rejeitado ou sem candidatos, gera novo runbook das sugestões da IA (com hash único por causa raiz), ou **(d)** remediação agentica (IA atua step-by-step).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| **5. Execução**        | RemediationReconciler                 | **54 tipos de ação**: workload (Scale, Restart, Rollback, AdjustResources, DeletePod, RestartStatefulSetPod), StatefulSet (ScaleStatefulSet, RestartStatefulSet, RollbackStatefulSet, AdjustStatefulSetResources, DeleteStatefulSetPod, ForceDeleteStatefulSetPod, UpdateStatefulSetStrategy, RecreateStatefulSetPVC, PartitionStatefulSetUpdate), DaemonSet (RestartDaemonSet, RollbackDaemonSet, AdjustDaemonSetResources, DeleteDaemonSetPod, UpdateDaemonSetStrategy, PauseDaemonSetRollout, CordonAndDeleteDaemonSetPod), Job (RetryJob, AdjustJobResources, DeleteFailedJob, SuspendJob, ResumeJob, AdjustJobParallelism, AdjustJobDeadline, AdjustJobBackoffLimit, ForceDeleteJobPods), CronJob (SuspendCronJob, ResumeCronJob, TriggerCronJob, AdjustCronJobResources, AdjustCronJobSchedule, AdjustCronJobDeadline, AdjustCronJobHistory, AdjustCronJobConcurrency, DeleteCronJobActiveJobs, ReplaceCronJobTemplate), GitOps (HelmRollback, ArgoSyncApp), autoscaling (AdjustHPA), infra (CordonNode, DrainNode), storage (ResizePVC), security (RotateSecret), networking (UpdateIngress, PatchNetworkPolicy), advanced (ApplyManifest, ExecDiagnostic). **Blast radius prediction** antes da execução. |
| **6. Resolução**       | IssueReconciler                       | Sucesso → Resolved (invalida dedup). Falha → re-análise com contexto de falha (estratégia diferente) → até maxAttempts → Escalated.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| **7. PostMortem**      | IssueReconciler                       | **Todas as remediações** (não apenas agênticas) geram PostMortem CR com timeline, causa raiz, lições, **métricas**, **correlação git**, **cascade chain**, **trending** (incidentes recorrentes), **feedback do dev**. Remediações bem-sucedidas também geram Runbooks reutilizáveis (um por causa raiz, nomes com hash).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| **8. Notificação**     | NotificationReconciler                | Envia notificações multi-canal (Slack, PagerDuty, OpsGenie, Email, Webhook, Teams) com throttling e templates. Escalação automática L1→L2→L3.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| **9. Aprovação**       | ApprovalReconciler                    | Workflow de aprovação auto/manual/quorum com blast radius, change windows e integração com Decision Engine.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| **10. SLO Monitoring** | SLOReconciler                         | Burn rate alerting multi-janela (modelo Google SRE), error budget tracking, business hours com timezone.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |

### Máquina de Estados do Issue

```mermaid theme={"system"}
stateDiagram-v2
    [*] --> Detected
    Detected --> Analyzing : AIInsight criado
    Analyzing --> Remediating : Via Runbook (manual ou auto-gerado)
    Analyzing --> Remediating : Via modo agêntico (sem Runbook/AI actions)
    Remediating --> Resolved : Remediação bem-sucedida (invalida dedup)
    Remediating --> Analyzing : Retry (re-análise com failure context)
    Remediating --> Escalated : Max tentativas (invalida dedup)
    Resolved --> [*]
    Escalated --> [*]

    note right of Resolved : Toda resolução gera PostMortem CR\nResolução agêntica também gera Runbook
```

## Criar Secret com API Keys

Antes de criar um Instance, você precisa de um Secret com as API keys do provedor LLM. O Instance referência este Secret via `apiKeys.name` — **sem ele, o servidor não consegue chamar a IA**.

<Tabs>
  <Tab title="OpenAI">
    ```bash theme={"system"}
    kubectl create secret generic chatcli-api-keys \
      --namespace chatcli-system \
      --from-literal=OPENAI_API_KEY="sk-sua-chave-aqui"
    ```
  </Tab>

  <Tab title="Anthropic (Claude)">
    ```bash theme={"system"}
    kubectl create secret generic chatcli-api-keys \
      --namespace chatcli-system \
      --from-literal=ANTHROPIC_API_KEY="sk-ant-sua-chave-aqui"
    ```
  </Tab>

  <Tab title="Google AI">
    ```bash theme={"system"}
    kubectl create secret generic chatcli-api-keys \
      --namespace chatcli-system \
      --from-literal=GOOGLEAI_API_KEY="sua-chave-aqui"
    ```
  </Tab>

  <Tab title="OpenRouter">
    ```bash theme={"system"}
    kubectl create secret generic chatcli-api-keys \
      --namespace chatcli-system \
      --from-literal=OPENROUTER_API_KEY="sk-or-sua-chave-aqui"
    ```
  </Tab>

  <Tab title="Múltiplos provedores">
    ```bash theme={"system"}
    kubectl create secret generic chatcli-api-keys \
      --namespace chatcli-system \
      --from-literal=OPENAI_API_KEY="sk-xxx" \
      --from-literal=ANTHROPIC_API_KEY="sk-ant-xxx" \
      --from-literal=GOOGLEAI_API_KEY="xxx" \
      --from-literal=OPENROUTER_API_KEY="sk-or-xxx"
    ```
  </Tab>

  <Tab title="Via YAML">
    ```yaml theme={"system"}
    apiVersion: v1
    kind: Secret
    metadata:
      name: chatcli-api-keys
      namespace: chatcli-system
    type: Opaque
    stringData:
      OPENAI_API_KEY: "sk-sua-chave-aqui"
      # ANTHROPIC_API_KEY: "sk-ant-xxx"
      # GOOGLEAI_API_KEY: "xxx"
      # OPENROUTER_API_KEY: "sk-or-xxx"
    ```
  </Tab>
</Tabs>

<Warning>
  O Secret **deve existir no mesmo namespace** do Instance CR. O nome do Secret deve corresponder ao campo `apiKeys.name` na spec do Instance. Sem esse Secret, o servidor inicia mas não consegue executar análises de IA nem remediações agênticas.
</Warning>

***

## CRD: Instance

O `Instance` gerencia instâncias do servidor ChatCLI no cluster.

### Especificação Completa

```yaml theme={"system"}
apiVersion: platform.chatcli.io/v1alpha1
kind: Instance
metadata:
  name: chatcli-prod
  namespace: chatcli          # O namespace deve existir antes de criar o Instance
spec:
  replicas: 1
  provider: CLAUDEAI       # OPENAI, OPENAI_ASSISTANT, CLAUDEAI, BEDROCK, GOOGLEAI, XAI, ZAI, MINIMAX, MOONSHOT, OPENROUTER, STACKSPOT, OLLAMA, COPILOT, GITHUB_MODELS
  model: claude-sonnet-4-6

  image:
    repository: ghcr.io/diillson/chatcli
    tag: latest
    pullPolicy: IfNotPresent

  server:
    port: 50051
    tls:
      enabled: true
      secretName: chatcli-tls   # Deve conter tls.crt, tls.key E ca.crt (em self-signed, ca.crt=tls.crt) — ver cookbook §2.1
    token:
      name: chatcli-auth
      key: token

  watcher:
    enabled: true
    interval: "30s"
    window: "2h"
    maxLogLines: 100
    maxContextChars: 32000
    targets:
      - name: api-gateway
        namespace: production
        metricsPort: 9090
        metricsFilter: ["http_requests_*", "http_request_duration_*"]
      - name: auth-service
        namespace: production
        metricsPort: 9090
      - name: worker
        namespace: batch
      - name: postgres                  # Monitorar StatefulSet
        kind: StatefulSet
        namespace: production
      - name: fluentd-agent             # Monitorar DaemonSet
        kind: DaemonSet
        namespace: logging
      - name: etl-pipeline              # Monitorar CronJob
        kind: CronJob
        namespace: data

  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 512Mi

  persistence:
    enabled: true
    size: 1Gi
    storageClassName: standard

  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    seccompProfile:
      type: RuntimeDefault

  apiKeys:
    name: chatcli-api-keys

  server:
    security:
      jwtSecretRef:
        name: chatcli-jwt
        key: secret
      rateLimitRps: 20
      # bindAddress: "0.0.0.0"  # Opcional — auto-detectado em Kubernetes

  extraEnv:
    - name: CHATCLI_AGENT_SECURITY_MODE
      value: "strict"
    - name: CHATCLI_AUDIT_LOG_PATH
      value: "/var/log/chatcli/audit.jsonl"
```

### Campos do Spec

#### Raiz

| Campo             | Tipo                 | Obrigatório | Padrão       | Descrição                                                        |
| ----------------- | -------------------- | :---------: | ------------ | ---------------------------------------------------------------- |
| `replicas`        | int32                |     Não     | `1`          | Número de réplicas do servidor                                   |
| `provider`        | string               |   **Sim**   |              | Provedor LLM                                                     |
| `model`           | string               |     Não     |              | Modelo LLM                                                       |
| `image`           | ImageSpec            |     Não     |              | Configuração da imagem                                           |
| `server`          | ServerSpec           |     Não     |              | Configuração do servidor gRPC                                    |
| `watcher`         | WatcherSpec          |     Não     |              | Configuração do K8s Watcher                                      |
| `resources`       | ResourceRequirements |     Não     |              | Requests/limits de CPU e memória                                 |
| `persistence`     | PersistenceSpec      |     Não     |              | Persistência de sessões                                          |
| `securityContext` | PodSecurityContext   |     Não     | nonroot/1000 | Security context do pod                                          |
| `fallback`        | FallbackSpec         |     Não     |              | Cadeia de fallback entre provedores LLM                          |
| `apiKeys`         | SecretRefSpec        |     Não     |              | Secret com API keys (todos os providers do fallback)             |
| `aiops`           | AIOpsSpec            |     Não     |              | Configuração do pipeline autônomo de gerenciamento de incidentes |

#### AIOpsSpec

Configura o pipeline de remediação automatica. Todos os campos são opcionais com defaults sensiveis. Runbooks auto-gerados pela IA herdam o valor de `maxRemediationAttempts` desta configuração.

| Campo                       | Tipo  | Obrigatório | Padrão | Range  | Descrição                                                                 |
| --------------------------- | ----- | :---------: | ------ | ------ | ------------------------------------------------------------------------- |
| `maxRemediationAttempts`    | int32 |     Não     | `5`    | 1-10   | Tentativas maximas de remediação antes de escalar para humano             |
| `resolutionCooldownMinutes` | int32 |     Não     | `10`   | 0-120  | Minutos após resolver antes de aceitar novas anomalias do mesmo recurso   |
| `dedupTTLMinutes`           | int32 |     Não     | `60`   | 5-1440 | Tempo (min) que o cache de dedup retém hashes de alertas                  |
| `enableAutoResolve`         | bool  |     Não     | `true` |        | Auto-resolver issues Escalados quando o recurso recupera                  |
| `agenticMaxSteps`           | int32 |     Não     | `10`   | 3-30   | Steps maximos por tentativa em modo agentico (cada step = 1 chamada a IA) |

```yaml theme={"system"}
spec:
  aiops:
    maxRemediationAttempts: 5
    resolutionCooldownMinutes: 10
    dedupTTLMinutes: 60
    enableAutoResolve: true
    agenticMaxSteps: 10
```

<Note>
  No modo agentico, o postmortem inclui o **raciocinio completo da IA** em cada step — qual ação foi escolhida, por que, e o resultado observado. Isso garante auditoria total das decisoes autonomas da IA.
</Note>

#### FallbackSpec

Configura failover automático entre provedores LLM. Quando o provedor primário falha (rate limit, timeout, erro de servidor), o sistema tenta automaticamente o próximo provedor na cadeia.

| Campo          | Tipo                     | Obrigatório | Padrão  | Descrição                                                           |
| -------------- | ------------------------ | :---------: | ------- | ------------------------------------------------------------------- |
| `enabled`      | bool                     |   **Sim**   |         | Ativa a cadeia de fallback                                          |
| `providers`    | \[]FallbackProviderEntry |   **Sim**   |         | Lista ordenada de provedores fallback (primeiro = maior prioridade) |
| `maxRetries`   | int32                    |     Não     | `2`     | Retentativas por provedor antes de ir para o próximo                |
| `cooldownBase` | string                   |     Não     | `"30s"` | Cooldown inicial após falha (backoff exponencial)                   |
| `cooldownMax`  | string                   |     Não     | `"5m"`  | Cooldown máximo                                                     |

#### FallbackProviderEntry

| Campo   | Tipo   | Obrigatório | Descrição                                                                                                                                                     |
| ------- | ------ | :---------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`  | string |   **Sim**   | Nome do provedor: OPENAI, OPENAI\_ASSISTANT, CLAUDEAI, BEDROCK, GOOGLEAI, XAI, ZAI, MINIMAX, MOONSHOT, OPENROUTER, STACKSPOT, OLLAMA, COPILOT, GITHUB\_MODELS |
| `model` | string |     Não     | Modelo LLM para este provedor                                                                                                                                 |

<Tip>
  O provedor primário (`spec.provider`) é sempre tentado primeiro. Os provedores em `fallback.providers` são tentados na ordem listada quando o primário falha. O Secret em `apiKeys` deve conter as API keys de **todos** os provedores na cadeia.
</Tip>

#### WatcherSpec

| Campo             | Tipo               | Obrigatório | Padrão  | Descrição                                    |
| ----------------- | ------------------ | :---------: | ------- | -------------------------------------------- |
| `enabled`         | bool               |     Não     | `false` | Ativa o watcher                              |
| `targets`         | \[]WatchTargetSpec |     Não     |         | Lista de recursos a monitorar (multi-target) |
| `deployment`      | string             |     Não     |         | Deployment único (legado)                    |
| `namespace`       | string             |     Não     |         | Namespace do deployment (legado)             |
| `interval`        | string             |     Não     | `"30s"` | Intervalo de coleta                          |
| `window`          | string             |     Não     | `"2h"`  | Janela de observação                         |
| `maxLogLines`     | int32              |     Não     | `100`   | Max linhas de log por pod                    |
| `maxContextChars` | int32              |     Não     | `32000` | Budget de contexto LLM                       |

#### WatchTargetSpec

| Campo           | Tipo      | Obrigatório | Padrão       | Descrição                                                                   |
| --------------- | --------- | :---------: | ------------ | --------------------------------------------------------------------------- |
| `name`          | string    |  **Sim**\*  |              | Nome do recurso a monitorar (ex: `postgres`, `fluentd`)                     |
| `deployment`    | string    |     Não     |              | Alias deprecated para `name` — mantido para compatibilidade                 |
| `kind`          | string    |     Não     | `Deployment` | Tipo do recurso: `Deployment`, `StatefulSet`, `DaemonSet`, `Job`, `CronJob` |
| `namespace`     | string    |   **Sim**   |              | Namespace do recurso                                                        |
| `metricsPort`   | int32     |     Não     | `0`          | Porta Prometheus (0 = desabilitado)                                         |
| `metricsPath`   | string    |     Não     | `/metrics`   | Path do endpoint Prometheus                                                 |
| `metricsFilter` | \[]string |     Não     |              | Filtros glob para métricas                                                  |

<Tip>
  Use `name` + `kind` para monitorar qualquer tipo de workload Kubernetes. Quando `kind` é omitido, assume `Deployment`. O campo legado `deployment` ainda funciona como alias para `name`. Exemplos:

  ```yaml theme={"system"}
  targets:
    - name: api-gateway             # Deployment (kind padrão)
      namespace: production
    - name: postgres                # StatefulSet (banco de dados)
      kind: StatefulSet
      namespace: production
    - name: fluentd                 # DaemonSet (agente de logging)
      kind: DaemonSet
      namespace: logging
    - name: etl-pipeline            # CronJob (batch agendado)
      kind: CronJob
      namespace: data
  ```

  O pipeline AIOps usará automaticamente ações de remediação específicas para cada tipo (ex: `ScaleStatefulSet`, `RestartDaemonSet`, `SuspendCronJob`) com base no kind detectado.
</Tip>

### Recursos Criados pelo Instance

| Recurso                | Nome                         | Descrição                                                                  |
| ---------------------- | ---------------------------- | -------------------------------------------------------------------------- |
| **Deployment**         | `<name>`                     | Pods do servidor ChatCLI                                                   |
| **Service**            | `<name>`                     | Service gRPC (headless automático quando réplicas > 1 para LB client-side) |
| **ConfigMap**          | `<name>`                     | Variáveis de ambiente (provider, model, etc.)                              |
| **ConfigMap**          | `<name>-watch-config`        | YAML multi-target (se `targets` definido)                                  |
| **ServiceAccount**     | `<name>`                     | Identity para RBAC                                                         |
| **Role**               | `<name>-watcher`             | Permissões K8s do watcher (single-namespace)                               |
| **RoleBinding**        | `<name>-watcher`             | Binding da SA ao Role (single-namespace)                                   |
| **ClusterRoleBinding** | `<namespace>-<name>-watcher` | Binding da SA à ClusterRole compartilhada (multi-namespace)                |
| **PVC**                | `<name>-sessions`            | Persistência (se habilitada)                                               |

### Balanceamento gRPC

O gRPC usa conexões HTTP/2 persistentes que fixam em um único pod via kube-proxy, deixando réplicas extras ociosas.

* **1 réplica** (padrão): Service ClusterIP padrão
* **Múltiplas réplicas**: Service headless (`ClusterIP: None`) é criado automaticamente, habilitando round-robin client-side via resolver `dns:///` do gRPC
* **Keepalive**: WatcherBridge faz ping a cada 30s (timeout de 5s) para detectar pods inativos rapidamente. O servidor aceita pings com intervalo mínimo de 20s (`EnforcementPolicy.MinTime`)
* **Transição**: Ao escalar de 1 para 2+ réplicas (ou voltar), o operator deleta e recria o Service automaticamente (ClusterIP é imutável no Kubernetes)

### RBAC Automático

* **Same namespace** (todos os targets no mesmo namespace do Instance): Cria `Role` + `RoleBinding` por Instance
* **Cross-namespace** (targets em namespace diferente do Instance, ou em múltiplos namespaces): Cria apenas `ClusterRoleBinding` por Instance, referenciando a `ClusterRole` compartilhada `chatcli-watcher` (pré-provisionada pelo Helm chart / kustomize)
* Na deleção do CR, o `ClusterRoleBinding` é removido pelo finalizer; a `ClusterRole` compartilhada permanece (é propriedade do release)

<Note>
  A partir da v1.152.0, o operator **não cria mais `ClusterRole` em runtime** (hardening H5). As ClusterRoles compartilhadas — `chatcli-watcher` para o watcher e `chatcli-role-{viewer,operator,admin,superadmin}` para as platform roles — são instaladas pelo Helm chart do operator. O ServiceAccount do operator tem o verb `bind` restrito a esses nomes específicos via `resourceNames`, impedindo escalonamento de privilégio mesmo em caso de comprometimento.
</Note>

<Note>
  **Upgrade a partir de v1.105.0**: clusters com Instances multi-namespace pré-existentes tinham um `ClusterRoleBinding` apontando para uma ClusterRole por-Instance (formato antigo). Como `roleRef` é imutável no Kubernetes, um `helm upgrade` direto travava o reconcile com `cannot change roleRef`. A partir de v1.152.0, o operator detecta o `roleRef` divergente no início de `reconcileClusterRBAC`, deleta o CRB obsoleto e recria apontando para `chatcli-watcher` — migração transparente, sem intervenção manual.
</Note>

### Imagem do Servidor e Auto-Resolução

A tag da imagem do servidor (`spec.image.tag`) segue três níveis de prioridade:

1. **Pin explícito** em `spec.image.tag` — honrado literalmente (GitOps-friendly).
2. **Omitido** — o operator resolve a partir do env var `CHATCLI_OPERATOR_APP_VERSION`, que o Helm chart injeta automaticamente a partir de `.Chart.AppVersion`. Efeito: `helm upgrade chatcli-operator` rola o servidor de todas as Instances que optaram por esse modo, sem patch manual.
3. **Fallback** — `latest` quando nenhum dos dois está presente (ex.: `make deploy` sem Helm).

```yaml theme={"system"}
apiVersion: platform.chatcli.io/v1alpha1
kind: Instance
metadata:
  name: chatcli-prod
spec:
  image:
    repository: ghcr.io/diillson/chatcli
    # tag omitido → herda appVersion do chart (recomendado p/ ambientes que atualizam via Helm)
  provider: CLAUDEAI
  model: claude-sonnet-4-6
  replicas: 2
```

<Tip>
  Para ambientes que querem versionamento imutável, continue pinando `spec.image.tag` e gerencie o upgrade manual. Para ambientes que querem "helm upgrade = upgrade completo", omita a tag.
</Tip>

### Auto-Rollout em Mudanças de Configuração

O operator monitora mudanças em ConfigMaps e Secrets referenciados pelo Instance e dispara rolling updates automaticamente via hash annotations no PodTemplate:

| Annotation                     | Fonte                                          | Quando Muda                       |
| ------------------------------ | ---------------------------------------------- | --------------------------------- |
| `chatcli.io/watch-config-hash` | ConfigMap `<name>-watch-config`                | Targets do watcher alterados      |
| `chatcli.io/configmap-hash`    | ConfigMap `<name>`                             | Variáveis de ambiente atualizadas |
| `chatcli.io/secret-hash`       | Secret referenciado em `apiKeys.name`          | API keys criadas ou atualizadas   |
| `chatcli.io/tls-hash`          | Secret referenciado em `server.tls.secretName` | Certificados TLS renovados        |

<Tip>
  Adicionar/remover targets no `watcher.targets` e aplicar o Instance causa rollout automático. Criar ou atualizar o Secret de API keys e renovar certificados TLS também disparam rollout automaticamente.
</Tip>

### Observação de Secrets e ConfigMaps

O operator observa (`Watches`) Secrets no namespace do Instance. Quando um Secret referenciado em `apiKeys.name` ou `server.tls.secretName` é criado ou atualizado, o reconciler é acionado automaticamente — mesmo que o Secret não existisse quando o Instance foi criado.

* **ConfigMap e Secret `envFrom`**: Marcados como `optional: true`, permitindo criar o Instance antes do Secret/ConfigMap
* **Ordem flexível de deploy**: Namespace → Instance → Secret/ConfigMap (qualquer ordem após o namespace)

## CRDs da Plataforma AIOps

### Anomaly

Representa um sinal bruto detectado pelo WatcherBridge.

```yaml theme={"system"}
apiVersion: platform.chatcli.io/v1alpha1
kind: Anomaly
metadata:
  name: watcher-highrestartcount-api-gateway-1234567890
  namespace: production
spec:
  signalType: pod_restart    # pod_restart | oom_kill | pod_not_ready | deploy_failing | error_rate | latency_spike
  source: watcher            # watcher | prometheus | manual
  severity: warning          # critical | high | medium | low | warning
  resource:
    kind: Deployment
    name: api-gateway
    namespace: production
  description: "HighRestartCount on api-gateway: container app restarted 8 times"
  detectedAt: "2026-02-16T10:30:00Z"
status:
  correlated: true
  issueRef:
    name: api-gateway-pod-restart-1771276354
```

#### Campos do Anomaly Spec

| Campo         | Tipo              | Descrição                                        |
| ------------- | ----------------- | ------------------------------------------------ |
| `signalType`  | AnomalySignalType | Tipo do sinal detectado                          |
| `source`      | AnomalySource     | Origem da detecção (watcher, prometheus, manual) |
| `severity`    | IssueSeverity     | Severidade do sinal                              |
| `resource`    | ResourceRef       | Recurso K8s afetado (kind, name, namespace)      |
| `description` | string            | Descrição legível do problema                    |
| `detectedAt`  | Time              | Timestamp da detecção                            |

#### Sinais Detectados (21 tipos)

**Sinais do Watcher:**

| AlertType (Server)  | SignalType (Anomaly) | Descrição                                  |
| ------------------- | -------------------- | ------------------------------------------ |
| `HighRestartCount`  | `pod_restart`        | Pod com muitos restarts (CrashLoopBackOff) |
| `OOMKilled`         | `oom_kill`           | Container terminado por falta de memória   |
| `PodNotReady`       | `pod_not_ready`      | Pod não está no estado Ready               |
| `DeploymentFailing` | `deploy_failing`     | Deployment com Available=False             |

**Sinais adicionais (via Prometheus, webhooks ou detecção interna):**

| SignalType             | Descrição                                                                    |
| ---------------------- | ---------------------------------------------------------------------------- |
| `error_rate`           | Taxa de erros HTTP elevada                                                   |
| `latency`              | Latência acima do threshold                                                  |
| `cpu_high`             | Uso de CPU elevado                                                           |
| `memory_high`          | Uso de memória elevado                                                       |
| `disk_pressure`        | Node com condição DiskPressure (disco cheio ou quase)                        |
| `node_not_ready`       | Node com condição NotReady (kubelet sem resposta, falha de rede ou hardware) |
| `memory_pressure`      | Node com condição MemoryPressure (memória insuficiente para novos pods)      |
| `pid_pressure`         | Node com condição PIDPressure (processos excessivos, risco de fork bomb)     |
| `network_unavailable`  | Node com rede indisponível (CNI falhou ou interface caiu)                    |
| `pvc_pending`          | PVC em estado Pending                                                        |
| `ingress_error`        | Erros no Ingress controller                                                  |
| `hpa_maxed`            | HPA no máximo de réplicas                                                    |
| `job_failed`           | Job falhou                                                                   |
| `cronjob_missed`       | CronJob não executou no schedule                                             |
| `certificate_expiring` | Certificado TLS expirando                                                    |
| `image_pull_error`     | Erro ao puxar imagem do container                                            |
| `crashloop_backoff`    | Pod em CrashLoopBackOff                                                      |
| `helm_release_failed`  | Helm release em estado failed                                                |
| `argocd_degraded`      | ArgoCD Application degradada                                                 |
| `config_drift`         | Drift de configuração detectado                                              |

#### Monitoramento de Nodes

O watcher monitora automaticamente a saude dos **nodes onde os pods dos targets estão rodando**. A cada ciclo de coleta, ele:

1. Identifica os nodes via label selector dos pods do target
2. Coleta as 5 condições oficiais do Kubernetes: `Ready`, `DiskPressure`, `MemoryPressure`, `PIDPressure`, `NetworkUnavailable`
3. Coleta métricas de CPU/memória do node (via metrics server)
4. Conta pods ativos vs capacidade do node
5. Verifica se o node está cordoned (unschedulable)

| Condição                 | Severidade | Signal           | Ação disponível           |
| ------------------------ | :--------: | ---------------- | ------------------------- |
| Node NotReady            |  CRITICAL  | `node_not_ready` | `CordonNode`, `DrainNode` |
| DiskPressure             |  CRITICAL  | `disk_pressure`  | `CordonNode`, `DrainNode` |
| MemoryPressure           |  CRITICAL  | `memory_high`    | `CordonNode`, `DrainNode` |
| PIDPressure              |   WARNING  | `node_not_ready` | `CordonNode`              |
| NetworkUnavailable       |  CRITICAL  | `node_not_ready` | `CordonNode`, `DrainNode` |
| Cordoned (Unschedulable) |   WARNING  | `node_not_ready` | Informativo               |
| Pod capacity >90%        |   WARNING  | `node_not_ready` | `CordonNode`              |

As informações de node são incluidas no contexto enviado a IA para análise, permitindo que a root cause seja correlacionada com problemas de infraestrutura (ex.: "OOMKill causado por MemoryPressure no node X").

### Issue

Incidente correlacionado que agrupa anomalias e gerencia o ciclo de vida da remediação.

```yaml theme={"system"}
apiVersion: platform.chatcli.io/v1alpha1
kind: Issue
metadata:
  name: api-gateway-pod-restart-1771276354
  namespace: production
spec:
  severity: high
  source: watcher
  signalType: pod_restart        # Propagated from Anomaly for tiered Runbook matching
  description: "Correlated incident: pod_restart on api-gateway"
  resource:
    kind: Deployment
    name: api-gateway
    namespace: production
  riskScore: 65
  correlatedAnomalies:
    - name: watcher-highrestartcount-api-gateway-1234567890
    - name: watcher-oomkilled-api-gateway-1234567891
status:
  state: Analyzing          # Detected | Analyzing | Remediating | Resolved | Escalated | Failed
  remediationAttempts: 0
  maxRemediationAttempts: 5  # default: 5, configurable via Instance aiops.maxRemediationAttempts
  detectedAt: "2026-02-16T10:30:00Z"
  conditions:
    - type: Analyzing
      status: "True"
      reason: AIInsightCreated
```

#### Estados do Issue

| Estado        | Descrição                                                                       |
| ------------- | ------------------------------------------------------------------------------- |
| `Detected`    | Issue recém-criado, aguardando análise                                          |
| `Analyzing`   | AIInsight criado, aguardando resposta da IA (ou re-análise com failure context) |
| `Remediating` | RemediationPlan em execução                                                     |
| `Resolved`    | Remediação bem-sucedida (dedup invalidado para detecção de recorrência)         |
| `Escalated`   | Max tentativas atingido ou sem ações disponíveis (dedup invalidado)             |
| `Failed`      | Falha terminal                                                                  |

### AIInsight

Análise de causa raiz gerada por IA com ações sugeridas para remediação automática.

```yaml theme={"system"}
apiVersion: platform.chatcli.io/v1alpha1
kind: AIInsight
metadata:
  name: api-gateway-pod-restart-1771276354-insight
  namespace: production
spec:
  issueRef:
    name: api-gateway-pod-restart-1771276354
  provider: CLAUDEAI
  model: claude-sonnet-4-6
status:
  analysis: "High restart count caused by OOMKilled. Container memory limit (512Mi) is insufficient for the current workload pattern."
  confidence: 0.87
  recommendations:
    - "Increase memory limit to 1Gi"
    - "Investigate possible memory leak in the application"
    - "Monitor GC pressure metrics"
  suggestedActions:
    - name: "Restart deployment"
      action: RestartDeployment
      description: "Restart pods to reclaim leaked memory immediately"
    - name: "Scale up replicas"
      action: ScaleDeployment
      description: "Add more replicas to distribute memory pressure"
      params:
        replicas: "4"
  generatedAt: "2026-02-16T10:31:00Z"
```

#### Campos do AIInsight Status

| Campo              | Tipo               | Descrição                                     |
| ------------------ | ------------------ | --------------------------------------------- |
| `analysis`         | string             | Análise de causa raiz gerada pela IA          |
| `confidence`       | float64            | Nível de confiança da análise (0.0-1.0)       |
| `recommendations`  | \[]string          | Recomendações legiveis para humanos           |
| `suggestedActions` | \[]SuggestedAction | Ações estruturadas para remediação automática |
| `generatedAt`      | Time               | Quando a análise foi gerada                   |

#### SuggestedAction

| Campo         | Tipo               | Descrição                                                                          |
| ------------- | ------------------ | ---------------------------------------------------------------------------------- |
| `name`        | string             | Nome legível da ação                                                               |
| `action`      | string             | Tipo da ação (54 tipos disponíveis — ver [Tipos de Ação](#tipos-de-ação-54-tipos)) |
| `description` | string             | Explicação do motivo desta ação                                                    |
| `params`      | map\[string]string | Parâmetros da ação (ex: `replicas: "4"`)                                           |

### RemediationPlan

Plano concreto de remediação gerado automaticamente a partir de Runbook ou ações da IA.

```yaml theme={"system"}
apiVersion: platform.chatcli.io/v1alpha1
kind: RemediationPlan
metadata:
  name: api-gateway-pod-restart-1771276354-plan-1
  namespace: production
spec:
  issueRef:
    name: api-gateway-pod-restart-1771276354
  attempt: 1
  strategy: "Attempt 1 (AI-generated): High restart count caused by OOMKilled"
  actions:
    - type: RestartDeployment
    - type: ScaleDeployment
      params:
        replicas: "4"
  safetyConstraints:
    - "No delete operations"
    - "No destructive changes"
    - "Rollback on failure"
status:
  state: Completed           # Pending | Executing | Completed | Failed | RolledBack
  result: "Deployment restarted and scaled to 4 replicas successfully"
  startedAt: "2026-02-16T10:31:30Z"
  completedAt: "2026-02-16T10:32:15Z"
```

#### Rollback Automático e Proteção de Estado

O operator implementa um **sistema de rollback automático** que garante que remediações malsucedidas não deixem o cluster em estado pior do que antes. Antes de executar qualquer ação, o estado completo do recurso é capturado em um **snapshot estruturado restaurável**.

<Steps>
  <Step title="Snapshot Pré-Remediação">
    Antes da primeira ação, o `RollbackEngine` captura um `ResourceSnapshot` estruturado com: replicas, imagens dos containers, CPU/memory requests e limits, estado do HPA (min/max replicas), e estado do node (schedulable/unschedulable). Funciona para **Deployments, StatefulSets, DaemonSets, Nodes e HPAs**.
  </Step>

  <Step title="Checkpoint por Ação">
    Em planos com múltiplas ações, um `ActionCheckpoint` é capturado **antes de cada ação individual**. Isso permite saber exatamente qual ação modificou o quê e em que ponto o plano falhou.
  </Step>

  <Step title="Rollback Automático em Falha de Ação">
    Se qualquer ação falha durante a execução, o operator **automaticamente restaura** o recurso para o estado do `PreflightSnapshot`. Replicas, imagens, resources requests/limits e estado do HPA são revertidos. O plano transiciona para estado `RolledBack` (não `Failed`).
  </Step>

  <Step title="Rollback em Timeout de Verificação">
    Se todas as ações executam com sucesso mas o recurso **não fica healthy dentro de 90 segundos** (verification timeout), o operator também executa rollback automático para o estado pré-remediação.
  </Step>

  <Step title="Verificação Pós-Falha">
    Após o rollback, o operator verifica se o recurso voltou ao estado healthy (`PostFailureHealthy`). Essa informação é registrada no status do plano para auditoria e decisão sobre retry.
  </Step>
</Steps>

**O que é capturado no snapshot:**

| Recurso         | Campos Capturados                                                          |
| --------------- | -------------------------------------------------------------------------- |
| **Deployment**  | replicas, container images, CPU/memory requests+limits, restart annotation |
| **StatefulSet** | replicas, container images, CPU/memory requests+limits                     |
| **DaemonSet**   | container images, CPU/memory requests+limits                               |
| **Node**        | schedulable state (para reverter cordon/drain)                             |
| **HPA**         | minReplicas, maxReplicas                                                   |

**Exemplo de RemediationPlan com rollback executado:**

```yaml theme={"system"}
apiVersion: platform.chatcli.io/v1alpha1
kind: RemediationPlan
metadata:
  name: api-gateway-plan-1
  namespace: production
status:
  state: RolledBack              # Ação falhou, rollback automático executado
  result: "Action AdjustResources (index 1) failed: invalid memory_limit | Rollback: Rolled back production/api-gateway: replicas: 5 → 3; container app: memory_limit=1Gi | Post-rollback: resource healthy"
  rollbackPerformed: true
  rollbackResult: "Rolled back production/api-gateway: replicas: 5 → 3; container app: memory_limit=1Gi"
  postFailureHealthy: true       # Recurso voltou ao normal após rollback
  preflightSnapshot:
    resourceKind: Deployment
    resourceName: api-gateway
    namespace: production
    replicas: 3
    containerImages:
      app: "ghcr.io/myorg/api-gateway:v2.1.0"
    containerResources:
      app:
        cpuRequest: "200m"
        cpuLimit: "1000m"
        memoryRequest: "256Mi"
        memoryLimit: "512Mi"
    hpaMinReplicas: 2
    hpaMaxReplicas: 8
    capturedAt: "2026-02-16T10:31:00Z"
  actionCheckpoints:
    - actionIndex: 0
      actionType: ScaleDeployment
      success: true
      timestamp: "2026-02-16T10:31:05Z"
    - actionIndex: 1
      actionType: AdjustResources
      success: false
      timestamp: "2026-02-16T10:31:10Z"
  evidence:
    - type: preflight_snapshot
      data: "Structured snapshot captured: kind=Deployment replicas=3 containers=1"
      timestamp: "2026-02-16T10:31:00Z"
    - type: action_completed
      data: "Action ScaleDeployment executed successfully"
      timestamp: "2026-02-16T10:31:05Z"
    - type: action_failed
      data: "Action AdjustResources failed: invalid memory_limit format"
      timestamp: "2026-02-16T10:31:10Z"
    - type: rollback
      data: "Rolled back production/api-gateway: replicas: 5 → 3; container app: memory_limit=1Gi"
      timestamp: "2026-02-16T10:31:11Z"
```

<Warning>
  O rollback automático restaura o estado **anterior à remediação**, não resolve o problema original. Após o rollback, o IssueReconciler avalia se há tentativas restantes e dispara **re-análise com contexto de falha** — a IA recebe o que falhou e sugere uma estratégia diferente.
</Warning>

**Fluxo completo em caso de falha:**

```mermaid theme={"system"}
flowchart TD
    A[Ação Executada] -->|Falha| B[Rollback Automático]
    A -->|Sucesso| C[Verificação de Saúde 90s]
    C -->|Healthy| D[Completed ✓]
    C -->|Timeout Unhealthy| B
    B --> E{Rollback OK?}
    E -->|Sim| F[Estado: RolledBack]
    E -->|Não| G[Estado: Failed]
    F --> H{Tentativas restantes?}
    G --> H
    H -->|Sim| I[Re-análise com failure context]
    H -->|Não| J[Escalação para humano]
    I --> K[IA sugere estratégia diferente]
    K --> A
```

**Campos de status adicionados ao RemediationPlan:**

| Campo                | Tipo                | Descrição                                                    |
| -------------------- | ------------------- | ------------------------------------------------------------ |
| `preflightSnapshot`  | ResourceSnapshot    | Estado completo do recurso antes de qualquer ação            |
| `actionCheckpoints`  | \[]ActionCheckpoint | Checkpoint antes de cada ação com resultado (success/fail)   |
| `rollbackPerformed`  | bool                | Se o rollback automático foi executado                       |
| `rollbackResult`     | string              | Descrição do que foi revertido (replicas, images, resources) |
| `postFailureHealthy` | \*bool              | Se o recurso está healthy após rollback                      |

***

#### Tipos de Ação (54 tipos)

**Workload:**

| Tipo                    | Descrição                                                 | Parâmetros                                                                |
| ----------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------- |
| `ScaleDeployment`       | Ajusta o número de réplicas                               | `replicas`                                                                |
| `RestartDeployment`     | Rollout restart do deployment                             | —                                                                         |
| `RollbackDeployment`    | Desfaz rollout (anterior, saudável ou revisão específica) | `toRevision` (optional: `previous`, `healthy`, ou número)                 |
| `PatchConfig`           | Atualiza chaves de um ConfigMap                           | `configmap`, `key=value`                                                  |
| `AdjustResources`       | Ajusta CPU/memória requests/limits de containers          | `memory_limit`, `memory_request`, `cpu_limit`, `cpu_request`, `container` |
| `DeletePod`             | Remove pod mais doente (CrashLoop > restarts)             | `pod` (optional — auto-seleciona o mais doente)                           |
| `RestartStatefulSetPod` | Restart de pod StatefulSet (preserva identidade/storage)  | `pod` (optional — omitir para rolling restart do StatefulSet inteiro)     |

**GitOps:**

| Tipo           | Descrição                                      | Parâmetros                               |
| -------------- | ---------------------------------------------- | ---------------------------------------- |
| `HelmRollback` | Rollback de Helm release para revisão anterior | `revision` (optional — padrão: anterior) |
| `ArgoSyncApp`  | Trigger de sync em ArgoCD Application          | `revision` (optional — padrão: HEAD)     |

**Autoscaling:**

| Tipo        | Descrição                                              | Parâmetros                                           |
| ----------- | ------------------------------------------------------ | ---------------------------------------------------- |
| `AdjustHPA` | Modifica min/max replicas ou target utilization do HPA | `minReplicas`, `maxReplicas`, `targetCPUUtilization` |

**Infraestrutura:**

| Tipo         | Descrição                     | Parâmetros |
| ------------ | ----------------------------- | ---------- |
| `CordonNode` | Marca node como unschedulable | `node`     |
| `DrainNode`  | Cordon + evict pods do node   | `node`     |

**Storage:**

| Tipo        | Descrição                                   | Parâmetros                 |
| ----------- | ------------------------------------------- | -------------------------- |
| `ResizePVC` | Expande PVC (somente expansão, não redução) | `pvc`, `size` (ex: `20Gi`) |

**Security:**

| Tipo           | Descrição                                     | Parâmetros                              |
| -------------- | --------------------------------------------- | --------------------------------------- |
| `RotateSecret` | Atualiza valores de Secret ou copia de source | `secret`, `sourceSecret` ou `key=value` |

**Networking:**

| Tipo                 | Descrição                                  | Parâmetros                                                 |
| -------------------- | ------------------------------------------ | ---------------------------------------------------------- |
| `UpdateIngress`      | Modifica backend ou annotations de Ingress | `ingress`, `backendService`, `backendPort`, `annotation.*` |
| `PatchNetworkPolicy` | Adiciona portas permitidas a NetworkPolicy | `networkPolicy`, `allowPort`, `protocol`                   |

**Advanced:**

| Tipo             | Descrição                                        | Parâmetros                                                            |
| ---------------- | ------------------------------------------------ | --------------------------------------------------------------------- |
| `ApplyManifest`  | Aplica manifesto JSON de um ConfigMap            | `configmap`, `key`                                                    |
| `ExecDiagnostic` | Executa comando diagnóstico whitelisted em pod   | `command` (string exata — ver [allowlist](#execdiagnostic-allowlist)) |
| `Custom`         | Ação personalizada (bloqueada por safety checks) | —                                                                     |

#### ExecDiagnostic Allowlist

A ação `ExecDiagnostic` faz match exato de string contra um allowlist de comandos read-only. Qualquer variação (flags diferentes, host alternativo, etc.) é rejeitada com `command "..." not in approved diagnostic commands whitelist`.

**Comandos aprovados por padrão (\~90):**

| Categoria                     | Comandos                                                                                                                                                                                                                            |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Processo / shell**          | `env`, `whoami`, `id`, `hostname`, `pwd`, `uname -a`, `uname -r`, `ps aux`, `ps -ef`, `top -b -n1`                                                                                                                                  |
| **Filesystem / recursos**     | `df -h`, `df -i`, `free -m`, `free -h`, `mount`, `uptime`, `ls -la /`, `ls -la /tmp`, `ls -la /var/log`, `du -sh /tmp`, `du -sh /var/log`                                                                                           |
| **Cgroups v2** (pod moderno)  | `cat /sys/fs/cgroup/memory.max`, `memory.current`, `memory.events`, `memory.stat`, `cpu.max`, `cpu.stat`                                                                                                                            |
| **Cgroups v1** (pod legado)   | `cat /sys/fs/cgroup/memory/memory.{limit_in_bytes,usage_in_bytes,oom_control,stat}`, `cat /sys/fs/cgroup/cpu/cpu.{cfs_quota_us,cfs_period_us,stat}`                                                                                 |
| **/proc introspection**       | `cat /proc/1/{cgroup,status,limits,cmdline,environ}`, `cat /proc/{meminfo,cpuinfo,loadavg,version}`, `cat /proc/net/{tcp,udp,sockstat}`                                                                                             |
| **Rede (read-only)**          | `netstat -tlnp`/`-an`/`-rn`, `ss -tlnp`/`-an`/`-s`, `ip addr`, `ip -s link`, `ip route`, `ip -6 route`, `ip neigh`, `ifconfig`, `arp -a`                                                                                            |
| **DNS / resolver**            | `cat /etc/{hosts,resolv.conf,nsswitch.conf}`, `nslookup/getent/dig/host kubernetes.default.svc.cluster.local`, `nslookup kube-dns.kube-system.svc.cluster.local`                                                                    |
| **Health / métricas / pprof** | `curl -s localhost{,:8080}/{health,healthz,ready,readyz,live,livez}`, `curl -s localhost:{8080,8081,9090,9091}/metrics`, `curl -s localhost:9090/-/{ready,healthy}`, `curl -s localhost:6060/debug/pprof/{,goroutine,heap}?debug=1` |
| **Envoy / Istio sidecar**     | `curl -s localhost:15000/ready`, `curl -s localhost:{15020,15021}/healthz/ready`                                                                                                                                                    |
| **wget fallback (Alpine)**    | `wget -qO- http://localhost{,:8080}/{health,healthz,metrics}`                                                                                                                                                                       |
| **Reachability TCP**          | `nc -zv kubernetes.default.svc.cluster.local 443`, `nc -zv kube-dns.kube-system.svc.cluster.local 53`                                                                                                                               |

Extender via env var `CHATCLI_ALLOWED_DIAGNOSTIC_COMMANDS` (comma-separated, lido uma vez na inicialização):

```yaml theme={"system"}
spec:
  extraEnv:
    - name: CHATCLI_ALLOWED_DIAGNOSTIC_COMMANDS
      value: "dig +short redis.default.svc.cluster.local, nc -zv redis.default.svc.cluster.local 6379"
```

<Warning>
  Cada entrada é matching exato. `nslookup <outro-host>` não funciona — é rejeitado. Se precisar de um host específico, adicione a string completa ao env var.
</Warning>

<Tip>
  A IA recebe esse allowlist no prompt de remediação (`server/handler_analysis.go`) e é instruída a escolher o comando certo por sintoma: `memory.events` para OOM, `cpu.stat` para throttling, `getent/dig` para DNS, pprof para apps Go travadas, `nc -zv` para dependência externa.
</Tip>

**StatefulSet:**

| Tipo                         | Descrição                            | Parâmetros                               |
| ---------------------------- | ------------------------------------ | ---------------------------------------- |
| `ScaleStatefulSet`           | Scaling ordenado de réplicas         | `replicas`                               |
| `RestartStatefulSet`         | Rolling restart via annotation       | —                                        |
| `RollbackStatefulSet`        | Rollback via ControllerRevision      | `toRevision`                             |
| `AdjustStatefulSetResources` | Ajusta CPU/memória                   | `container`, `memory_limit`, `cpu_limit` |
| `DeleteStatefulSetPod`       | Deleta pod específico ou mais doente | `pod` (opcional)                         |
| `ForceDeleteStatefulSetPod`  | Force-delete de pod preso (grace=0)  | `pod` (OBRIGATÓRIO)                      |
| `UpdateStatefulSetStrategy`  | Altera updateStrategy                | `type`, `maxUnavailable`                 |
| `RecreateStatefulSetPVC`     | Deleta PVC preso para recriação      | `pvc`, `confirm=true`                    |
| `PartitionStatefulSetUpdate` | Partition para canary rollout        | `partition`                              |

**DaemonSet:**

| Tipo                          | Descrição                                     | Parâmetros                               |
| ----------------------------- | --------------------------------------------- | ---------------------------------------- |
| `RestartDaemonSet`            | Rolling restart em todos os nodes             | —                                        |
| `RollbackDaemonSet`           | Rollback via ControllerRevision               | `toRevision`                             |
| `AdjustDaemonSetResources`    | Ajusta CPU/memória                            | `container`, `memory_limit`, `cpu_limit` |
| `DeleteDaemonSetPod`          | Deleta pod (opcionalmente em node específico) | `pod`, `node` (opcional)                 |
| `UpdateDaemonSetStrategy`     | Altera estratégia de update                   | `type`, `maxUnavailable`, `maxSurge`     |
| `PauseDaemonSetRollout`       | Pausa rollout (maxUnavailable=0)              | —                                        |
| `CordonAndDeleteDaemonSetPod` | Cordona node + deleta pod                     | `node` (OBRIGATÓRIO)                     |

**Job:**

| Tipo                    | Descrição                      | Parâmetros                               |
| ----------------------- | ------------------------------ | ---------------------------------------- |
| `RetryJob`              | Deleta Job falhado + recria    | —                                        |
| `AdjustJobResources`    | Ajusta CPU/memória no template | `container`, `memory_limit`, `cpu_limit` |
| `DeleteFailedJob`       | Limpa Job falhado              | —                                        |
| `SuspendJob`            | Pausa Job (suspend=true)       | —                                        |
| `ResumeJob`             | Retoma Job (suspend=false)     | —                                        |
| `AdjustJobParallelism`  | Altera paralelismo             | `parallelism`                            |
| `AdjustJobDeadline`     | Altera deadline                | `activeDeadlineSeconds`                  |
| `AdjustJobBackoffLimit` | Altera backoff limit           | `backoffLimit`                           |
| `ForceDeleteJobPods`    | Force-delete de todos os pods  | —                                        |

**CronJob:**

| Tipo                       | Descrição                         | Parâmetros                                             |
| -------------------------- | --------------------------------- | ------------------------------------------------------ |
| `SuspendCronJob`           | Pausa agendamento                 | —                                                      |
| `ResumeCronJob`            | Retoma agendamento                | —                                                      |
| `TriggerCronJob`           | Cria Job imediatamente            | —                                                      |
| `AdjustCronJobResources`   | Ajusta CPU/memória no jobTemplate | `container`, `memory_limit`, `cpu_limit`               |
| `AdjustCronJobSchedule`    | Altera schedule                   | `schedule`                                             |
| `AdjustCronJobDeadline`    | Altera deadline                   | `startingDeadlineSeconds`                              |
| `AdjustCronJobHistory`     | Altera limites de histórico       | `successfulJobsHistoryLimit`, `failedJobsHistoryLimit` |
| `AdjustCronJobConcurrency` | Altera política de concorrência   | `concurrencyPolicy`                                    |
| `DeleteCronJobActiveJobs`  | Mata Jobs ativos                  | —                                                      |
| `ReplaceCronJobTemplate`   | Substitui template de ConfigMap   | `configmap`, `key`                                     |

#### Exemplos de RemediationPlan com Novas Ações

<Tabs>
  <Tab title="GitOps: HelmRollback">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: RemediationPlan
    metadata:
      name: checkout-helm-rollback-plan-1
      namespace: production
    spec:
      issueRef:
        name: checkout-helm-release-failed-123
      attempt: 1
      strategy: "Rollback Helm release to previous stable revision"
      actions:
        - type: HelmRollback
          params:
            revision: "41"    # revision específica (omitir para anterior)
    ```
  </Tab>

  <Tab title="GitOps: ArgoSyncApp">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: RemediationPlan
    metadata:
      name: api-gateway-argo-sync-plan-1
      namespace: production
    spec:
      issueRef:
        name: api-gateway-argocd-degraded-456
      attempt: 1
      strategy: "Force ArgoCD sync to reconcile desired state"
      actions:
        - type: ArgoSyncApp
          params:
            revision: "abc123def"   # commit SHA (omitir para HEAD)
    ```
  </Tab>

  <Tab title="StatefulSet + HPA">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: RemediationPlan
    metadata:
      name: postgres-recovery-plan-1
      namespace: databases
    spec:
      issueRef:
        name: postgres-pod-restart-789
      attempt: 1
      strategy: "Restart unhealthy StatefulSet pod and adjust HPA"
      actions:
        - type: RestartStatefulSetPod
          params:
            pod: "postgres-2"   # pod específico (omitir para rolling restart)
        - type: AdjustHPA
          params:
            minReplicas: "3"
            maxReplicas: "10"
            targetCPUUtilization: "70"
    ```
  </Tab>

  <Tab title="Infra: Node Drain">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: RemediationPlan
    metadata:
      name: node-disk-pressure-plan-1
      namespace: kube-system
    spec:
      issueRef:
        name: node-disk-pressure-issue-321
      attempt: 1
      strategy: "Cordon and drain node with disk pressure"
      actions:
        - type: CordonNode
          params:
            node: "worker-node-03"
        - type: DrainNode
          params:
            node: "worker-node-03"
    ```
  </Tab>

  <Tab title="Storage + Security">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: RemediationPlan
    metadata:
      name: storage-and-certs-plan-1
      namespace: production
    spec:
      issueRef:
        name: pvc-full-cert-expired-555
      attempt: 1
      strategy: "Expand PVC and rotate expired certificate"
      actions:
        - type: ResizePVC
          params:
            pvc: "data-postgres-0"
            size: "50Gi"
        - type: RotateSecret
          params:
            secret: "tls-api-gateway"
            sourceSecret: "tls-api-gateway-renewed"
    ```
  </Tab>

  <Tab title="Networking">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: RemediationPlan
    metadata:
      name: networking-fix-plan-1
      namespace: production
    spec:
      issueRef:
        name: ingress-backend-error-777
      attempt: 1
      strategy: "Fix ingress backend and open blocked port"
      actions:
        - type: UpdateIngress
          params:
            ingress: "api-gateway-ingress"
            backendService: "api-gateway-v2"
            backendPort: "8080"
        - type: PatchNetworkPolicy
          params:
            networkPolicy: "api-gateway-netpol"
            allowPort: "8443"
            protocol: "TCP"
    ```
  </Tab>

  <Tab title="Advanced: Manifest + Diagnostic">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: RemediationPlan
    metadata:
      name: advanced-fix-plan-1
      namespace: production
    spec:
      issueRef:
        name: complex-issue-999
      attempt: 1
      strategy: "Run diagnostics then apply fix manifest"
      actions:
        - type: ExecDiagnostic
          params:
            command: "df -h"
        - type: ApplyManifest
          params:
            configmap: "hotfix-configmap"
            key: "manifest.yaml"
    ```
  </Tab>
</Tabs>

### Runbook (Manual ou Auto-gerado)

Procedimentos operacionais. Runbooks **manuais** têm prioridade sobre tudo. Quando não há Runbook manual, a IA **gera automaticamente** um Runbook CR reutilizável a partir das ações sugeridas.

<Tabs>
  <Tab title="Runbook manual">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: Runbook
    metadata:
      name: high-error-rate-deployment
      namespace: production
    spec:
      description: "Standard procedure for high error rate incidents on Deployments"
      trigger:
        signalType: error_rate
        severity: high
        resourceKind: Deployment
      steps:
        - name: Scale up
          action: ScaleDeployment
          description: "Increase replicas to absorb the error spike"
          params:
            replicas: "4"
        - name: Rollback
          action: RollbackDeployment
          description: "Revert to previous stable version if scaling doesn't help"
      maxAttempts: 3
    ```
  </Tab>

  <Tab title="Runbook auto-gerado pela IA">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: Runbook
    metadata:
      name: auto-pod-restart-high-deployment
      labels:
        platform.chatcli.io/auto-generated: "true"
        platform.chatcli.io/source-issue: "api-gateway-pod-restart-1771276354"
    spec:
      description: "Auto-generated: High restart count caused by OOMKilled..."
      trigger:
        signalType: pod_restart
        severity: high
        resourceKind: Deployment
      steps:
        - name: Restart deployment
          action: RestartDeployment
        - name: Scale up replicas
          action: ScaleDeployment
          params:
            replicas: "4"
      maxAttempts: 3
    ```

    Auto-generated Runbooks são **reutilizados** para futuras Issues com o mesmo trigger, evitando chamadas desnecessárias ao LLM.
  </Tab>

  <Tab title="Runbook: Helm + ArgoCD">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: Runbook
    metadata:
      name: helm-release-failed-runbook
      namespace: production
    spec:
      description: "Rollback de Helm release e sync ArgoCD após falha de deploy"
      trigger:
        signalType: helm_release_failed
        severity: critical
        resourceKind: Deployment
      steps:
        - name: Rollback Helm
          action: HelmRollback
          description: "Reverte para a revisão anterior estável"
        - name: Sync ArgoCD
          action: ArgoSyncApp
          description: "Força sync do ArgoCD para reconciliar estado"
      maxAttempts: 2
    ```
  </Tab>

  <Tab title="Runbook: StatefulSet + Storage">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: Runbook
    metadata:
      name: statefulset-disk-full-runbook
      namespace: databases
    spec:
      description: "Expande PVC e reinicia pod StatefulSet com disco cheio"
      trigger:
        signalType: disk_pressure
        severity: high
        resourceKind: StatefulSet
      steps:
        - name: Expand storage
          action: ResizePVC
          description: "Dobra o tamanho do PVC"
          params:
            pvc: "data-postgres-0"
            size: "100Gi"
        - name: Restart pod
          action: RestartStatefulSetPod
          description: "Reinicia o pod para reconhecer o novo tamanho"
          params:
            pod: "postgres-0"
      maxAttempts: 2
    ```
  </Tab>
</Tabs>

### RemediationPlan (Agentic Mode)

Quando não há Runbook manual nem ações sugeridas pela IA, o operator cria um **plano agêntico**. A IA atua como um agente com skills Kubernetes em um loop observe-decide-act:

```yaml theme={"system"}
apiVersion: platform.chatcli.io/v1alpha1
kind: RemediationPlan
metadata:
  name: api-gateway-pod-restart-plan-1
  namespace: production
spec:
  issueRef:
    name: api-gateway-pod-restart-1771276354
  attempt: 1
  strategy: "Agentic AI remediation"
  agenticMode: true
  agenticMaxSteps: 10
  agenticHistory:
    - stepNumber: 1
      aiMessage: "High restart count with OOMKilled. Scaling up to reduce memory pressure."
      action:
        type: ScaleDeployment
        params:
          replicas: "5"
      observation: "SUCCESS: ScaleDeployment executed successfully"
    - stepNumber: 2
      aiMessage: "Pods still restarting. Adjusting memory limits."
      action:
        type: AdjustResources
        params:
          memory_limit: "1Gi"
          memory_request: "512Mi"
      observation: "SUCCESS: AdjustResources executed successfully"
    - stepNumber: 3
      aiMessage: "All pods running stable. Issue resolved."
status:
  state: Completed
  agenticStepCount: 3
  agenticStartedAt: "2026-02-16T10:31:00Z"
```

<Note>
  Safety Guards: Maximum of 10 steps (configurable via `agenticMaxSteps`), timeout of 10 minutes. If an action fails, the observation reports "FAILED: error" and the loop continues -- the AI receives the feedback and adapts.
</Note>

**Na resolução agêntica:** O operator gera automaticamente:

1. **PostMortem CR** com timeline, causa raiz, impacto, lições aprendidas
2. **Runbook CR** reutilizável com os passos bem-sucedidos (label `source=agentic`)

### PostMortem (Auto-generated)

Relatório de incidente gerado automaticamente após **qualquer resolução de remediação** (standard ou agêntica). Contém o histórico completo do incidente: detecção, análise, ações executadas, resolução, além de **métricas**, **correlação git**, **cascade chain**, **trending de incidentes recorrentes** e campo de **feedback do desenvolvedor**.

```yaml theme={"system"}
apiVersion: platform.chatcli.io/v1alpha1
kind: PostMortem
metadata:
  name: pm-api-gateway-pod-restart-1771276354
  namespace: production
spec:
  issueRef:
    name: api-gateway-pod-restart-1771276354
  resource:
    kind: Deployment
    name: api-gateway
    namespace: production
  severity: high
status:
  state: Open              # Open | InReview | Closed
  summary: "OOMKilled containers caused cascading restarts on api-gateway"
  rootCause: "Memory limit (512Mi) insufficient for current workload pattern"
  impact: "Service degradation for 5 minutes, 30% error rate increase"
  timeline:
    - timestamp: "2026-02-16T10:30:00Z"
      type: detected
      detail: "Issue detected: pod_restart on api-gateway"
    - timestamp: "2026-02-16T10:31:00Z"
      type: action_executed
      detail: "ScaleDeployment to 5 replicas"
    - timestamp: "2026-02-16T10:31:35Z"
      type: action_executed
      detail: "AdjustResources memory_limit=1Gi"
    - timestamp: "2026-02-16T10:32:10Z"
      type: resolved
      detail: "All pods stable, issue resolved"
  lessonsLearned:
    - "Memory limits should account for peak workload patterns"
    - "Set up HPA to auto-scale on memory pressure"
  preventionActions:
    - "Configure HPA with min 3 replicas for api-gateway"
    - "Set memory limit to 1Gi across all environments"
  duration: "2m10s"
  generatedAt: "2026-02-16T10:32:10Z"
  # Novos campos de enrichment (preenchidos automaticamente pelo operator)
  metricSnapshots:
    - name: "memory_usage"
      value: "498000000"
      timestamp: "2026-02-16T10:30:00Z"
      phase: "during"
    - name: "memory_usage"
      value: "312000000"
      timestamp: "2026-02-16T10:35:00Z"
      phase: "after"
  blastRadius:
    - resource:
        kind: Service
        name: api-gateway-svc
        namespace: production
      impact: "5xx responses during pod restarts"
      severity: "high"
  gitCorrelation:
    commitSHA: "a1b2c3d4e5f6"
    commitMessage: "feat: add webhook handler for notifications"
    author: "dev@team.com"
    timestamp: "2026-02-16T09:15:00Z"
    confidence: 0.82
    filesChanged:
      - "internal/webhook/handler.go"
      - "internal/webhook/handler_test.go"
  trending:
    occurrenceCount: 3
    windowDays: 30
    relatedPostMortems:
      - "pm-api-gateway-oom-20260205"
      - "pm-api-gateway-oom-20260210"
    pattern: "Recurring oom_kill on Deployment/api-gateway (3 occurrences in 30 days)"
  gitOpsContext: "Helm release 'api-gateway' chart=api-gw version=2.1.0 status=deployed revision=15"
  logAnalysisSummary: "1 Go panic stack trace; 8 critical error patterns (resource/connectivity)"
  cascadeChain:
    - "production/api-gateway(root_cause)"
    - "production/frontend(victim)"
  # Feedback do dev (preenchido manualmente após revisão)
  feedback:
    overrideRootCause: ""          # vazio = concorda com a IA
    remediationAccuracy: 4         # 1-5 scale
    comments: "Boa análise, mas poderia ter sugerido AdjustResources antes do restart"
    providedBy: "sre@team.com"
    providedAt: "2026-02-17T09:00:00Z"
```

#### Campos do PostMortem Status

| Campo                | Tipo                | Descrição                                                                     |
| -------------------- | ------------------- | ----------------------------------------------------------------------------- |
| `state`              | PostMortemState     | Estado: Open, InReview, Closed                                                |
| `summary`            | string              | Resumo do incidente gerado pela IA                                            |
| `rootCause`          | string              | Causa raiz determinada pela IA                                                |
| `impact`             | string              | Impacto do incidente                                                          |
| `timeline`           | \[]TimelineEvent    | Linha do tempo (detected, analyzed, action\_executed, resolved)               |
| `actionsExecuted`    | \[]ActionRecord     | Ações executadas com resultado                                                |
| `lessonsLearned`     | \[]string           | Lições aprendidas                                                             |
| `preventionActions`  | \[]string           | Ações preventivas sugeridas                                                   |
| `duration`           | string              | Duração total do incidente                                                    |
| `generatedAt`        | Time                | Quando o PostMortem foi gerado                                                |
| `reviewedAt`         | Time                | Quando o PostMortem foi revisado por humano                                   |
| `metricSnapshots`    | \[]MetricSnapshot   | Métricas Prometheus capturadas antes/durante/depois do incidente              |
| `blastRadius`        | \[]BlastRadiusEntry | Serviços e recursos impactados pelo incidente                                 |
| `gitCorrelation`     | GitCorrelation      | Commit suspeito correlacionado ao incidente (SHA, autor, arquivos, confiança) |
| `sliImpact`          | string              | Impacto nos SLIs e error budgets                                              |
| `errorBudgetBurned`  | float64             | Percentual de error budget consumido                                          |
| `trending`           | TrendingInfo        | Informação de padrão recorrente (contagem, janela, PostMortems relacionados)  |
| `feedback`           | DevFeedback         | Feedback humano (override de causa raiz, accuracy 1-5, comentários)           |
| `gitOpsContext`      | string              | Estado do Helm/ArgoCD/Flux no momento do incidente                            |
| `logAnalysisSummary` | string              | Resumo dos achados da análise de logs                                         |
| `cascadeChain`       | \[]string           | Cadeia de cascade failure se aplicável                                        |

#### Matching de Runbooks (Tiered)

```text theme={"system"}
Tier 1: SignalType + Severity + ResourceKind (match exato, preferido)
Tier 2: Severity + ResourceKind (fallback quando signal não bate)
```

#### Prioridade de Remediação

```text theme={"system"}
1. Runbook manual existente (match tiered)
2. Runbook auto-gerado pela IA (materializado como CR reutilizável)
3. Remediação agêntica por IA (loop observe-decide-act, gera PostMortem + Runbook)
4. Escalonamento (apenas quando agêntico falha após max tentativas)
```

### SourceRepository (Code-Aware Diagnostics)

Vincula um workload Kubernetes ao seu repositório de código-fonte. Quando configurado, a IA recebe contexto de código durante análise de incidentes: commits recentes correlacionados ao timestamp, trechos de código referenciados em stack traces, e arquivos de configuração (Dockerfile, values.yaml).

<Note>
  **Validação de entrada (hardening):** `spec.url` aceita apenas as formas `https://`, `ssh://` ou `git@host:path`, e `spec.branch` é restrito a `[A-Za-z0-9._/-]` sem `-` inicial — fechando o vetor de injeção de argumento no git (ex.: `--upload-pack`). Leitura de trechos referenciados em stack traces é confinada ao clone do repositório via `os.Root` (sem traversal nem escape por symlink). URLs ou branches fora do padrão fazem o sync falhar com erro explícito no status.
</Note>

<Tabs>
  <Tab title="Token Auth (GitHub PAT)">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: SourceRepository
    metadata:
      name: api-gateway-repo
      namespace: production
    spec:
      url: "https://github.com/myorg/api-gateway.git"
      branch: main
      authType: token
      secretRef: git-token       # Secret com key "token"
      resource:
        kind: Deployment
        name: api-gateway
        namespace: production
      paths: ["cmd/", "internal/"]
      dockerfile: "Dockerfile"
      language: "Go"
      syncIntervalMinutes: 30
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: git-token
      namespace: production
    type: Opaque
    stringData:
      token: "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    ```
  </Tab>

  <Tab title="SSH Key">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: SourceRepository
    metadata:
      name: payment-service-repo
      namespace: production
    spec:
      url: "git@github.com:myorg/payment-service.git"
      branch: main
      authType: ssh
      secretRef: git-ssh-key     # Secret com key "ssh-key"
      resource:
        kind: Deployment
        name: payment-service
        namespace: production
      language: "Java"
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: git-ssh-key
      namespace: production
    type: Opaque
    data:
      ssh-key: <base64-encoded-private-key>
    ```
  </Tab>

  <Tab title="Basic Auth">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: SourceRepository
    metadata:
      name: worker-repo
      namespace: batch
    spec:
      url: "https://gitlab.internal.com/team/worker.git"
      branch: develop
      authType: basic
      secretRef: git-basic-auth  # Secret com keys "username" e "password"
      resource:
        kind: Deployment
        name: worker
        namespace: batch
      paths: ["src/"]
      language: "Python"
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: git-basic-auth
      namespace: batch
    type: Opaque
    stringData:
      username: "deploy-bot"
      password: "xxxxxxxxxxxx"
    ```
  </Tab>

  <Tab title="Public Repo (no auth)">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: SourceRepository
    metadata:
      name: oss-frontend-repo
      namespace: staging
    spec:
      url: "https://github.com/myorg/frontend.git"
      branch: main
      authType: none             # repo público, sem auth
      resource:
        kind: Deployment
        name: frontend
        namespace: staging
      paths: ["src/", "pages/"]
      language: "TypeScript"
      syncIntervalMinutes: 60    # sync menos frequente para staging
    ```
  </Tab>

  <Tab title="StatefulSet (Database)">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: SourceRepository
    metadata:
      name: postgres-migrations-repo
      namespace: databases
    spec:
      url: "https://github.com/myorg/db-migrations.git"
      branch: main
      authType: token
      secretRef: git-token
      resource:
        kind: StatefulSet         # funciona com qualquer resource kind
        name: postgres
        namespace: databases
      paths: ["migrations/", "schemas/"]
      dockerfile: "Dockerfile.migrate"
    ```
  </Tab>
</Tabs>

**O que o operator faz com o SourceRepository:**

1. **Clone shallow** do repositório (depth 50) e sync periódico (configurável via `syncIntervalMinutes`)
2. **Indexa** linguagens detectadas, entrypoints (main.go, app.py, index.ts, etc.), config files (Dockerfile, values.yaml, Chart.yaml)
3. **Correlação temporal**: encontra commits nos 30 min antes do incidente
4. **Commit suspeito**: identifica o commit mais provável de ter causado o problema (score por proximidade temporal + volume de mudanças)
5. **Extração de código**: quando stack traces referenciam arquivos (ex: `handler.go:42`), extrai trechos com contexto de 5 linhas antes/depois
6. **Feed para IA**: todo o contexto é incluído no prompt de análise

<Note>
  O repositório é clonado localmente no operator pod. Para repos privados, crie um Secret com a chave correspondente ao `authType` escolhido e referencie em `secretRef`. O operator suporta repos **HTTPS** (token/basic) e **SSH** (ssh-key).
</Note>

***

## Correlation Engine

O motor de correlação agrupa anomalias em issues usando:

### Risk Scoring

Cada tipo de sinal tem um peso:

| Sinal            | Peso |
| ---------------- | ---- |
| `oom_kill`       | 30   |
| `error_rate`     | 25   |
| `deploy_failing` | 25   |
| `latency_spike`  | 20   |
| `pod_restart`    | 20   |
| `pod_not_ready`  | 20   |

O risk score é a soma dos pesos das anomalias correlacionadas (máximo 100).

### Classificação de Severidade

| Risk Score | Severidade |
| ---------- | ---------- |
| >= 80      | Critical   |
| >= 60      | High       |
| >= 40      | Medium     |
| \< 40      | Low        |

### Agrupamento

* Anomalias no **mesmo recurso** (deployment + namespace) dentro da **mesma janela temporal** são agrupadas no mesmo Issue
* **Incident ID** deterministico: hash do recurso + tipo de sinal (evita duplicatas)

## WatcherBridge

O `WatcherBridge` e o componente que conecta o servidor ChatCLI ao operator:

* **Polling**: Consulta `GetAlerts` do servidor a cada 30 segundos
* **Descoberta**: Localiza o servidor via Instance CRs (primeiro Instance com endpoint gRPC pronto)
* **Dedup**: Hash SHA256 do tipo+deployment+namespace (sem componente temporal — um problema contínuo gera apenas uma Anomaly). TTL de 2 horas
* **Invalidação de dedup**: Quando Issue atinge estado terminal (Resolved/Escalated), entradas de dedup para o recurso são removidas, permitindo detecção imediata de recorrência
* **Poda**: Remove hashes expirados automaticamente (> 2h)
* **Criação**: Converte alertas em Anomaly CRs com nomes K8s válidos

## Exemplos de Uso

<Tabs>
  <Tab title="Minimo (sem AIOps)">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: Instance
    metadata:
      name: chatcli-simple
    spec:
      provider: OPENAI
      apiKeys:
        name: chatcli-api-keys
    ```
  </Tab>

  <Tab title="AIOps Completo">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: Instance
    metadata:
      name: chatcli-aiops
    spec:
      provider: CLAUDEAI
      apiKeys:
        name: chatcli-api-keys
      server:
        port: 50051
      watcher:
        enabled: true
        interval: "15s"
        maxContextChars: 32000
        targets:
          - deployment: api-gateway
            namespace: production
            metricsPort: 9090
            metricsFilter: ["http_*", "grpc_*"]
          - deployment: auth-service
            namespace: production
            metricsPort: 9090
          - deployment: worker
            namespace: batch
          - deployment: ml-inference
            namespace: ml
            metricsPort: 8080
      resources:
        requests:
          cpu: 200m
          memory: 256Mi
        limits:
          cpu: "1"
          memory: 1Gi
      persistence:
        enabled: true
        size: 5Gi
    ```
  </Tab>

  <Tab title="Com Fallback Multi-Provider">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: Instance
    metadata:
      name: chatcli-resilient
      namespace: chatcli-system
    spec:
      provider: OPENAI
      model: gpt-4o
      fallback:
        enabled: true
        providers:
          - name: CLAUDEAI
            model: claude-sonnet-4-20250514
          - name: GOOGLEAI
            model: gemini-2.0-flash
        maxRetries: 2
        cooldownBase: "30s"
        cooldownMax: "5m"
      apiKeys:
        name: chatcli-api-keys
      watcher:
        enabled: true
        targets:
          - deployment: api-gateway
            namespace: production
    ---
    # Secret com keys de TODOS os providers do fallback
    apiVersion: v1
    kind: Secret
    metadata:
      name: chatcli-api-keys
      namespace: chatcli-system
    type: Opaque
    stringData:
      OPENAI_API_KEY: "sk-xxx"
      ANTHROPIC_API_KEY: "sk-ant-xxx"
      GOOGLEAI_API_KEY: "xxx"
    ```

    Quando o OpenAI falha (rate limit, timeout), o sistema tenta automaticamente Claude, depois Google AI. Cada provedor tem até 2 retentativas antes de ir para o próximo. Após falha, o provedor entra em cooldown exponencial (30s → 1m → 2m → ... até 5m max).
  </Tab>

  <Tab title="Runbook Manual (opcional)">
    ```yaml theme={"system"}
    apiVersion: platform.chatcli.io/v1alpha1
    kind: Runbook
    metadata:
      name: oom-kill-runbook
      namespace: production
    spec:
      description: "Procedure for OOMKilled containers"
      trigger:
        signalType: oom_kill
        severity: critical
        resourceKind: Deployment
      steps:
        - name: Restart pods
          action: RestartDeployment
          description: "Restart to reclaim leaked memory"
        - name: Scale up
          action: ScaleDeployment
          description: "Add replicas to distribute memory pressure"
          params:
            replicas: "5"
      maxAttempts: 2
    ```
  </Tab>

  <Tab title="Secret de API Keys">
    ```yaml theme={"system"}
    apiVersion: v1
    kind: Secret
    metadata:
      name: chatcli-api-keys
    type: Opaque
    stringData:
      ANTHROPIC_API_KEY: "sk-ant-xxx"
      # OPENAI_API_KEY: "sk-xxx"
      # GOOGLEAI_API_KEY: "xxx"
    ```
  </Tab>
</Tabs>

## Status e Monitoramento

<AccordionGroup>
  <Accordion title="Verificar Instancias">
    ```bash theme={"system"}
    kubectl get instances
    ```

    ```text theme={"system"}
    NAME            READY   REPLICAS   PROVIDER    AGE
    chatcli-aiops   true    1          CLAUDEAI    5m
    ```
  </Accordion>

  <Accordion title="Verificar Issues Ativos">
    ```bash theme={"system"}
    kubectl get issues -A
    ```

    ```text theme={"system"}
    NAME                                    SEVERITY   STATE         RISK   AGE
    api-gateway-pod-restart-1771276354      high       Remediating   65     2m
    worker-oom-kill-3847291023              critical   Analyzing     90     30s
    ```
  </Accordion>

  <Accordion title="Verificar Insights da IA">
    ```bash theme={"system"}
    kubectl get aiinsights -A
    ```

    ```text theme={"system"}
    NAME                                           ISSUE                                   PROVIDER   CONFIDENCE   AGE
    api-gateway-pod-restart-1771276354-insight      api-gateway-pod-restart-1771276354      CLAUDEAI   0.87         1m
    ```
  </Accordion>

  <Accordion title="Verificar Planos de Remediação">
    ```bash theme={"system"}
    kubectl get remediationplans -A
    ```

    ```text theme={"system"}
    NAME                                          ISSUE                                   ATTEMPT   STATE       AGE
    api-gateway-pod-restart-1771276354-plan-1      api-gateway-pod-restart-1771276354      1         Completed   1m
    ```
  </Accordion>

  <Accordion title="Verificar PostMortems">
    ```bash theme={"system"}
    kubectl get postmortems -A
    ```

    ```text theme={"system"}
    NAME                                          ISSUE                                   SEVERITY   STATE   AGE
    pm-api-gateway-pod-restart-1771276354         api-gateway-pod-restart-1771276354      high       Open    30s
    ```
  </Accordion>

  <Accordion title="Verificar Anomalias">
    ```bash theme={"system"}
    kubectl get anomalies -A
    ```

    ```text theme={"system"}
    NAME                                               SIGNAL        SOURCE    SEVERITY   AGE
    watcher-highrestartcount-api-gateway-1234567890     pod_restart   watcher   warning    3m
    watcher-oomkilled-worker-9876543210                 oom_kill      watcher   critical   1m
    ```
  </Accordion>
</AccordionGroup>

## Desenvolvimento

```bash theme={"system"}
cd operator

# Build
go build ./...

# Testes (130 funções de teste, 185 com subtests)
go test ./... -v

# Docker (deve ser construído a partir do root do repositório)
docker build -f operator/Dockerfile -t myregistry/chatcli-operator:dev .

# Deploy via Helm (recomendado)
helm install chatcli-operator ../deploy/helm/chatcli-operator/ \
  --namespace chatcli-system --create-namespace \
  --set image.repository=myregistry/chatcli-operator \
  --set image.tag=dev

# Ou deploy via kubectl (alternativa)
make deploy IMG=myregistry/chatcli-operator:dev
```

## Segurança

O Operator implementa múltiplas camadas de segurança por padrão, seguindo o princípio de **fail-closed** (negar por padrão):

### Autenticação da REST API

A API REST opera em modo **fail-closed** por padrão -- não há modo dev sem autenticação. Toda requisição deve incluir um header `X-API-Key` válido com role mapeada (viewer/operator/admin).

As API keys são carregadas com a seguinte ordem de prioridade e recarregadas automaticamente a cada 30 segundos:

1. **Secret** `chatcli-operator-secrets` (prioridade) — campo `api-keys` com lista YAML `{key, role, description}`
2. **ConfigMap** `chatcli-operator-config` (fallback) — mesmo campo `api-keys`
3. Rejeita a requisição (ou aceita em dev-mode se `CHATCLI_OPERATOR_DEV_MODE=true`)

<Note>
  **Dois Secrets distintos no projeto** — não confunda com as LLM keys do servidor (`chatcli-api-keys` consumido pelo chatcli server via `Instance.spec.apiKeys.name`). Tabela comparativa em [Segurança — Autenticação](/pt/features/security#auten%C3%A7%C3%A3o-do-operator).

  O Secret `chatcli-operator-secrets` precisa estar **no mesmo namespace que o pod do operator** (o controller resolve via `POD_NAMESPACE` env / arquivo do ServiceAccount, com fallback `chatcli-system`). Se você fez `helm install --namespace <X>`, crie o Secret em `<X>`.
</Note>

<Tip>
  Alterações nas API keys -- tanto no Secret quanto no ConfigMap -- são detectadas automaticamente a cada 30s. Nenhum restart do operator é necessário.
</Tip>

### Allowlist de Tipos de Recurso

O Operator classifica tipos de recurso Kubernetes em duas categorias:

<Tabs>
  <Tab title="17 Tipos Seguros (permitidos)">
    Pods, Deployments, StatefulSets, DaemonSets, Services, ConfigMaps, Ingresses, Jobs, CronJobs, ReplicaSets, Endpoints, PersistentVolumeClaims, HorizontalPodAutoscalers, NetworkPolicies, ServiceAccounts, Namespaces, Events.
  </Tab>

  <Tab title="18 Tipos Perigosos (bloqueados)">
    Secrets, ClusterRoles, ClusterRoleBindings, Roles, RoleBindings, CustomResourceDefinitions, MutatingWebhookConfigurations, ValidatingWebhookConfigurations, PodSecurityPolicies, Nodes, PersistentVolumes, StorageClasses, CSIDrivers, CSINodes, VolumeAttachments, CertificateSigningRequests, TokenReviews, SubjectAccessReviews.
  </Tab>
</Tabs>

### Scrubbing de Logs

Antes de enviar logs de aplicação ao LLM para análise, o Operator remove **18 padrões sensíveis**, incluindo:

* Tokens JWT/Bearer, API keys, senhas
* Endereços de e-mail, IPs internos, URLs com credenciais
* Números de cartão de crédito, SSNs, certificados PEM

### TLS e RBAC

* **TLS 1.3** obrigatório em todas as conexões do servidor ChatCLI
* **ClusterRoles** com privilégio mínimo (read-only por padrão)
* **NetworkPolicy** configurável para restringir tráfego de rede ao namespace do Operator
* **Hardening H5 — RBAC sem escalonamento em runtime**: o operator nunca cria ou altera `ClusterRole`/`ClusterRoleBinding` em runtime. As ClusterRoles compartilhadas (`chatcli-watcher`, `chatcli-role-*`) são pré-provisionadas pelo Helm chart, e o SA do operator tem o verb `bind` restrito a esses nomes via `resourceNames`. Um operator comprometido não consegue referenciar uma ClusterRole mais privilegiada em um novo `ClusterRoleBinding`.

### Auditoria

* **AuditEvent CRD** para trilha de auditoria imutável (append-only)
* Logs estruturados com Request ID para correlação
* Integração com `CHATCLI_AUDIT_LOG_PATH` via `extraEnv`

```yaml theme={"system"}
spec:
  extraEnv:
    - name: CHATCLI_AGENT_SECURITY_MODE
      value: "strict"
    - name: CHATCLI_AUDIT_LOG_PATH
      value: "/var/log/chatcli/audit.jsonl"
```

<Warning>
  Em modo `strict`, o agent security bloqueia qualquer operação de escrita no cluster que não esteja na allowlist. Isso é recomendado para ambientes de produção.
</Warning>

## Próximo Passo

<CardGroup cols={2}>
  <Card title="AIOps Platform" icon="brain" href="/pt/features/aiops-platform">
    Deep-dive na arquitetura AIOps
  </Card>

  <Card title="K8s Watcher" icon="binoculars" href="/pt/features/k8s-watcher">
    Detalhes de coleta e budget
  </Card>

  <Card title="Modo Servidor" icon="server" href="/pt/features/server-mode">
    RPCs GetAlerts e AnalyzeIssue
  </Card>

  <Card title="Monitoramento K8s" icon="book" href="/pt/cookbook/k8s-monitoring">
    Receita: Monitoramento K8s com IA
  </Card>
</CardGroup>
