Pular para o conteúdo principal
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

Allow (Permitido)

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

Deny (Bloqueado)

A ação e bloqueada silenciosamente (ou com erro para a IA). Ideal para proteger arquivos sensiveis ou comandos destrutivos.

Ask (Perguntar)

O ChatCLI pausa e exibe um menu interativo para você decidir. Este e o padrão para ações não configuradas.

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

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 TTYTCIFLUSH (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.
Quando uma ação cai no estado “Ask”, você vera uma caixa de segurança com informações contextuais sobre a acao:
+========================================================+
|              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

SubcomandoLabel no PromptDetalhes Exibidos
execExecutar comando no shell$ <comando>, dir: <cwd>
testExecutar testes$ <comando>, dir: <cwd>
writeEscrever arquivoarquivo: <path>
patchModificar arquivo (patch)arquivo: <path>
readLer arquivoarquivo: <path>
searchPesquisar no códigotermo: <pattern>, dir: <path>
treeListar estrutura de diretoriosdir: <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:
+========================================================+
|              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'
 --------------------------------------------------------
Isso permite que você saiba exatamente qual agent está solicitando a ação e por que, facilitando decisoes de segurança informadas.

Opcoes

1

y (Yes)

Executa apenas desta vez. Na proxima, perguntara novamente.
2

a (Always)

Cria uma regra permanente de ALLOW para esse comando (ex: libera todas as escritas com @coder write).
3

n (No)

Pula a execução. A IA recebe um erro informando que o usuário negou.
4

d (Deny)

Cria uma regra permanente de DENY. A ação será bloqueada automaticamente no futuro.
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.

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
Se merge: true, as regras locais mesclam com a global (local sobrescreve padroes iguais).
{
  "merge": true,
  "rules": [
    { "pattern": "@coder write", "action": "ask" },
    { "pattern": "@coder exec --cmd 'rm -rf'", "action": "deny" }
  ]
}

Exemplo de Política (coder_policy.json)

{
  "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:
RegraComandoResultado
@coder read = allow@coder read file.txtPermitido
@coder read = allow@coder readlink /tmpNão casa (vai para Ask)
@coder read --file /etc = deny@coder read --file /etc/passwdDeny (path-prefix match)
Isso significa que @coder read nunca vai liberar @coder readlink ou @coder readwrite acidentalmente.

Validação de Comandos (50+ Padroes)

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

Destruicao de dados

rm -rf, dd if=, mkfs, drop database

Execução remota

curl | bash, base64 | sh

Injecao de código

python -c, eval, $(curl ...)

Substituicao de processos

<(cmd), >(cmd)

Manipulacao de kernel

insmod, modprobe, rmmod

Evasao

${IFS;cmd}, VAR=x; bash
Você pode adicionar padroes customizados via CHATCLI_AGENT_DENYLIST:
export CHATCLI_AGENT_DENYLIST="terraform destroy;kubectl delete namespace"
Para a lista completa de protecoes de segurança do ChatCLI, veja a documentação de Segurança e Hardening.

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.
Esse mecanismo e transparente — você não precisa fazer nada. O security check aparece exatamente uma vez por acao.

Boas Praticas

1

Inicie com Cautela

Mantenha os comandos de escrita (write, patch, exec) como ask até sentir confianca no agente.
2

Libere Leituras

Geralmente, e seguro dar “Always” para coder read, coder tree, coder search e Git read-only (git-status, git-diff, git-log).
3

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

Exec Seguro

O @coder exec bloqueia padroes perigosos por padrão (50+ regras). Use --allow-unsafe apenas quando necessário.

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

RegraAção no Worker
allowAção executada automaticamente pelo worker
denyAção bloqueada; o worker recebe [BLOCKED BY POLICY] e continua seu fluxo
askO worker pausa, o spinner de progresso e suspenso, e o prompt de segurança e exibido
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.

UI do Modo Coder

Você pode controlar o estilo e o banner do /coder via variáveis de ambiente:
VariávelValoresDescrição
CHATCLI_CODER_UIfull (padrão), minimalEstilo da interface
CHATCLI_CODER_BANNERtrue (padrão), falseMostra/oculta o cheat sheet
Essas configurações aparecem em /status e /config.