> ## 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.

# Segurança do Modo Coder (Governanca)

> Entenda como funciona o sistema de governanca e permissões do Modo Coder.

O ChatCLI foi projetado para ser uma ferramenta poderosa, mas o poder exige controle. No **Modo Coder** (`/coder`), a IA tem capacidade de ler, escrever, criar e executar comandos no seu sistema. Para garantir que você esteja sempre no comando, implementamos um sistema de governanca inspirado no ClaudeCode.

***

## Como Funciona?

Toda a vez que a IA sugere uma ação (como criar um arquivo ou rodar um script), o ChatCLI verifica as suas regras de segurança locais antes de executar.

### Os 3 Estados de Permissao

<CardGroup cols={3}>
  <Card title="Allow (Permitido)" icon="circle-check">
    A ação e executada automaticamente, sem interrupcao. Ideal para comandos de leitura (`read`, `tree`, `search`) e Git read-only (`git-status`, `git-diff`, `git-log`, `git-changed`, `git-branch`).
  </Card>

  <Card title="Deny (Bloqueado)" icon="circle-xmark">
    A ação e bloqueada silenciosamente (ou com erro para a IA). Ideal para proteger arquivos sensiveis ou comandos destrutivos.
  </Card>

  <Card title="Ask (Perguntar)" icon="circle-question">
    O ChatCLI pausa e exibe um menu interativo para você decidir. Este e o **padrão** para ações não configuradas.
  </Card>
</CardGroup>

### Ordem de prioridade do policy\_manager

Quando o agente solicita uma ação, o `policy_manager` avalia as regras na ordem abaixo (a primeira que aplica vence):

1. **Deny rules** — regras explícitas do usuário sempre ganham
2. **Safety-immune** — operações que SEMPRE pedem confirmação (`@coder exec`)
3. **Allow vs Ask explícito** — padrão mais longo (`longest pattern wins`)
4. **Read-only exec heuristic** — `@coder exec` com comando comprovadamente read-only auto-allow
5. **Capability gate** (novo) — plugins que declaram `IsReadOnly=true` via interface de capability auto-allow
6. **Default** — Ask

A camada 5 cobre `@read`, `@search`, `@tree`, `@websearch`, `@webfetch` (GET), `@scheduler query/list`, `@coder read/search/tree` — todos passam **sem prompt** enquanto write/exec continuam gated.

<Tip>
  Deny rules sempre ganham do capability gate. Você pode bloquear `@websearch` em ambiente corporativo via regra `@websearch → Deny` mesmo que o plugin advertise read-only.
</Tip>

### Proteção contra typeahead (input guard)

Quando o LLM está streamando e a security box aparece, qualquer caractere que você tenha digitado **antes** do prompt mostrar é descartado automaticamente. Três camadas:

* **Flush kernel TTY** — `TCIFLUSH` (Linux), `TIOCFLUSH` (BSD/Darwin), `FlushConsoleInputBuffer` (Windows) descarta bytes na fila do kernel.
* **Drain channel** — esvazia o canal centralizado de stdin não-bloqueante (10 linhas de buffer).
* **Intent debounce** — descarta qualquer input que chegue nos primeiros 250ms após o prompt aparecer (humanos não respondem tão rápido a uma UI nova).

Sem isso, digitar acidentalmente durante o stream do LLM faria a security box consumir os bytes prontos como resposta de y/n.

***

## Menu de Aprovação Interativo

Quando uma ação cai no estado "Ask", você vera uma caixa de segurança com informações contextuais sobre a acao:

```text theme={"system"}
+========================================================+
|              SECURITY CHECK                             |
+========================================================+
 Acao:   Escrever arquivo
         arquivo: main.go
 Regra:  nenhuma regra para '@coder write'
 --------------------------------------------------------
 Escolha:
   [y] Sim, executar (uma vez)
   [a] Permitir sempre (@coder write)
   [n] Não, pular
   [d] Bloquear sempre (@coder write)

 > _
```

O prompt exibe a **acao em linguagem humana** (ex.: "Escrever arquivo", "Executar comando no shell", "Modificar arquivo (patch)") e os **detalhes parseados** dos argumentos JSON, em vez de mostrar JSON bruto.

#### Tipos de Ação Reconhecidos

| Subcomando | Label no Prompt                | Detalhes Exibidos                 |
| ---------- | ------------------------------ | --------------------------------- |
| `exec`     | Executar comando no shell      | `$ <comando>`, `dir: <cwd>`       |
| `test`     | Executar testes                | `$ <comando>`, `dir: <cwd>`       |
| `write`    | Escrever arquivo               | `arquivo: <path>`                 |
| `patch`    | Modificar arquivo (patch)      | `arquivo: <path>`                 |
| `read`     | Ler arquivo                    | `arquivo: <path>`                 |
| `search`   | Pesquisar no código            | `termo: <pattern>`, `dir: <path>` |
| `tree`     | Listar estrutura de diretorios | `dir: <path>`                     |

### Prompt com Contexto no Modo Paralelo

Quando a ação e solicitada por um **worker do modo multi-agent**, o prompt inclui informações adicionais sobre qual agent está requisitando:

```text theme={"system"}
+========================================================+
|              SECURITY CHECK                             |
+========================================================+
 Agent:  shell
 Tarefa: Executar testes do modulo auth
 --------------------------------------------------------
 Acao:   Executar comando no shell
         $ go test ./pkg/auth/...
 Regra:  nenhuma regra para '@coder exec'
 --------------------------------------------------------
```

<Info>Isso permite que você saiba **exatamente** qual agent está solicitando a ação e por que, facilitando decisoes de segurança informadas.</Info>

### Opcoes

<Steps>
  <Step title="y (Yes)">
    Executa apenas desta vez. Na proxima, perguntara novamente.
  </Step>

  <Step title="a (Always)">
    Cria uma regra permanente de **ALLOW** para esse comando (ex: libera todas as escritas com `@coder write`).
  </Step>

  <Step title="n (No)">
    Pula a execução. A IA recebe um erro informando que o usuário negou.
  </Step>

  <Step title="d (Deny)">
    Cria uma regra permanente de **DENY**. A ação será bloqueada automaticamente no futuro.
  </Step>
</Steps>

<Note>Para comandos `exec`, as opções "Always" e "Deny Forever" não são disponibilizadas, pois cada execução e única e requer aprovação individual.</Note>

***

## Gerenciamento de Regras

As regras são salvas localmente em `~/.chatcli/coder_policy.json`. Você pode editar esse arquivo manualmente se desejar, mas o menu interativo e a forma mais facil de configurar.
O matching usa o subcomando efetivo do `@coder` mesmo quando `args` e JSON (ex.: `{"cmd":"read"}` vira `@coder read`).

### Policy Local (Por Projeto)

Você pode adicionar uma policy local no diretório do projeto:

* Local: `./coder_policy.json`
* Global: `~/.chatcli/coder_policy.json`

<Tabs>
  <Tab title="Com merge (local + global)">
    Se `merge: true`, as regras locais **mesclam** com a global (local sobrescreve padroes iguais).

    ```json theme={"system"}
    {
      "merge": true,
      "rules": [
        { "pattern": "@coder write", "action": "ask" },
        { "pattern": "@coder exec --cmd 'rm -rf'", "action": "deny" }
      ]
    }
    ```
  </Tab>

  <Tab title="Sem merge (somente local)">
    Se `merge: false` ou ausente, **somente** a policy local e usada.

    ```json theme={"system"}
    {
      "rules": [
        { "pattern": "@coder read", "action": "allow" },
        { "pattern": "@coder write", "action": "ask" }
      ]
    }
    ```
  </Tab>
</Tabs>

### Exemplo de Política (coder\_policy.json)

```json theme={"system"}
{
  "rules": [
    {
      "pattern": "@coder read",
      "action": "allow"
    },
    {
      "pattern": "@coder git-status",
      "action": "allow"
    },
    {
      "pattern": "@coder write",
      "action": "ask"
    },
    {
      "action": "deny",
      "pattern": "@coder exec --cmd 'rm -rf'"
    }
  ]
}
```

***

## Matching com Word Boundary

O sistema de policies usa **matching com word boundary**, garantindo que regras não casem parcialmente com subcomandos diferentes:

| Regra                            | Comando                          | Resultado                   |
| -------------------------------- | -------------------------------- | --------------------------- |
| `@coder read` = allow            | `@coder read file.txt`           | Permitido                   |
| `@coder read` = allow            | `@coder readlink /tmp`           | **Não casa** (vai para Ask) |
| `@coder read --file /etc` = deny | `@coder read --file /etc/passwd` | Deny (path-prefix match)    |

<Tip>Isso significa que `@coder read` **nunca** vai liberar `@coder readlink` ou `@coder readwrite` acidentalmente.</Tip>

***

## Validação de Comandos (50+ Padroes)

Alem da governanca de policies, o `@coder exec` válida cada comando contra **50+ padroes regex** que detectam:

<CardGroup cols={2}>
  <Card title="Destruicao de dados" icon="trash">
    `rm -rf`, `dd if=`, `mkfs`, `drop database`
  </Card>

  <Card title="Execução remota" icon="globe">
    `curl | bash`, `base64 | sh`
  </Card>

  <Card title="Injecao de código" icon="syringe">
    `python -c`, `eval`, `$(curl ...)`
  </Card>

  <Card title="Substituicao de processos" icon="arrows-left-right">
    `<(cmd)`, `>(cmd)`
  </Card>

  <Card title="Manipulacao de kernel" icon="microchip">
    `insmod`, `modprobe`, `rmmod`
  </Card>

  <Card title="Evasao" icon="mask">
    `${IFS;cmd}`, `VAR=x; bash`
  </Card>
</CardGroup>

Você pode adicionar padroes customizados via `CHATCLI_AGENT_DENYLIST`:

```bash theme={"system"}
export CHATCLI_AGENT_DENYLIST="terraform destroy;kubectl delete namespace"
```

<Info>Para a lista completa de protecoes de segurança do ChatCLI, veja a [documentação de Segurança e Hardening](/pt/features/security).</Info>

***

## Deduplicação de Tool Calls

O ChatCLI possui um mecanismo de deduplicação que garante que cada tool call seja verificada e executada **exatamente uma vez**.

### O Problema

Quando a IA responde com tool calls em formato XML (ex: `<tool_call name="@coder" args='{"cmd":"read",...}' />`), o parser do ChatCLI usa dois métodos de extracao:

1. **Parser XML** — extrai tags `<tool_call>` completas
2. **Parser JSON** — procura objetos JSON que representem tool calls (para modelos que respondem em JSON puro)

O JSON embutido dentro do atributo `args` do XML (ex: `{"cmd":"read",...}`) poderia ser incorretamente reconhecido pelo parser JSON como uma segunda tool call. Sem deduplicação, isso causaria:

* Security check exibido **duas vezes** para a mesma acao
* A mesma ação executada **duas vezes**

### A Solucao

O `ParseToolCalls` aplica deduplicação automatica: tool calls extraidas pelo parser JSON que já existam como parte de uma tool call XML são descartadas. A comparacao usa o nome da tool, os argumentos e o texto bruto para detectar duplicatas.

<Info>Esse mecanismo e transparente — você não precisa fazer nada. O security check aparece exatamente uma vez por acao.</Info>

***

## Boas Praticas

<Steps>
  <Step title="Inicie com Cautela">
    Mantenha os comandos de escrita (`write`, `patch`, `exec`) como `ask` até sentir confianca no agente.
  </Step>

  <Step title="Libere Leituras">
    Geralmente, e seguro dar "Always" para `coder read`, `coder tree`, `coder search` e Git read-only (`git-status`, `git-diff`, `git-log`).
  </Step>

  <Step title="Seja Especifico">
    O matching usa word boundary para prefixos de subcomando e path-prefix para argumentos. Você pode liberar `coder exec --cmd 'ls` mas bloquear `coder exec --cmd 'rm`.
  </Step>

  <Step title="Exec Seguro">
    O `@coder exec` bloqueia padroes perigosos por padrão (50+ regras). Use `--allow-unsafe` apenas quando necessário.
  </Step>
</Steps>

***

## Governanca no Modo Multi-Agent (Paralelo)

As policies de segurança são **totalmente respeitadas** pelos workers do modo multi-agent. Quando o `/coder` ou `/agent` opera em modo paralelo, cada worker verifica as regras do `coder_policy.json` antes de executar qualquer acao.

### Comportamento

| Regra     | Ação no Worker                                                                           |
| --------- | ---------------------------------------------------------------------------------------- |
| **allow** | Ação executada automaticamente pelo worker                                               |
| **deny**  | Ação bloqueada; o worker recebe `[BLOCKED BY POLICY]` e continua seu fluxo               |
| **ask**   | O worker **pausa**, o spinner de progresso e suspenso, e o prompt de segurança e exibido |

<Note>Os prompts de segurança de múltiplos workers são **serializados** -- apenas um prompt por vez e exibido, evitando sobreposicao visual. Regras criadas durante a sessão (via "Always" ou "Deny") são imediatamente visiveis para todos os workers subsequentes.</Note>

***

## UI do Modo Coder

Você pode controlar o estilo e o banner do `/coder` via variáveis de ambiente:

| Variável               | Valores                    | Descrição                   |
| ---------------------- | -------------------------- | --------------------------- |
| `CHATCLI_CODER_UI`     | `full` (padrão), `minimal` | Estilo da interface         |
| `CHATCLI_CODER_BANNER` | `true` (padrão), `false`   | Mostra/oculta o cheat sheet |

<Tip>Essas configurações aparecem em `/status` e `/config`.</Tip>
