@andreias.ai · por baixo do capô

Instrução é contexto. Trava é configuração.

O agente lê o CLAUDE.md como contexto, não como regra imposta. O que não pode falhar vai para permissão e hook. Copie os três blocos e adapte ao seu projeto.

01CLAUDE.md enxuto

Curto de propósito: ele entra em toda sessão. Detalhe fica em arquivos referenciados.

# Projeto <nome>

## Como rodar
- Testes: npm test
- Tipos e lint: npm run check

## Regras da casa
- Toda mudança entra por pull request; nada de push direto na main.
- Antes de dizer que terminou, rode os testes e mostre o resultado.
- Segredos nunca entram na conversa nem no código.

## Onde está o resto
- Arquitetura: @docs/arquitetura.md
- Como fazer deploy: @docs/deploy.md

02.claude/settings.json

Regra deny é avaliada antes de ask e allow. Ela bloqueia a leitura pela ferramenta, mas não um script que abra o arquivo por conta própria: para isso, use sandbox.

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{ "type": "command", "command": "node .claude/hooks/barra-destrutivo.mjs" }]
      }
    ]
  }
}

03.claude/hooks/barra-destrutivo.mjs

Roda antes de cada comando no terminal. Recusa com motivo, que volta para o agente.

// Lê a chamada da ferramenta no stdin e recusa comando destrutivo.
let entrada = "";
process.stdin.on("data", (c) => (entrada += c));
process.stdin.on("end", () => {
  const comando = JSON.parse(entrada).tool_input?.command ?? "";
  const perigoso = /rm\s+-rf|git\s+push\s+.*--force|drop\s+table/i.test(comando);
  if (!perigoso) return;
  console.log(JSON.stringify({
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Comando destrutivo bloqueado pelo hook do projeto. Peça a uma pessoa."
    }
  }));
});

04Confira no seu projeto

Marque o que já está no lugar.