MÓDULO 2.7

🔒 As Seis Camadas de Segurança

Proteções que evitam o usuário ficar preso. Cada camada captura um tipo diferente de falha. Princípio: o usuário NUNCA fica preso.

6 Camadas de Segurança

Falha aberta em todos os lugares. O usuário nunca fica preso.

1

🛡️ Fail-open

Se o hook quebrar (script com bug, dependência sumiu, permissão negada), a saída padrão é ALLOW, não BLOCK. Por quê? Porque hook quebrado bloqueando o Claude deixaria o usuário preso sem saber o porquê.

trap 'exit 0' ERR  # qualquer erro = ALLOW

# Lógica do hook aqui
# Se quebrar em qualquer linha, exit 0 = Claude sai limpo

Captura: bugs no próprio hook, ambiente quebrado, ferramenta indisponível.

2

⚛️ Escritas atômicas (TMP + RENAME)

O state.yaml não pode ser lido pela metade. Se o hook escreve enquanto outro processo lê, o leitor pega lixo. Solução: escreve em state.yaml.tmp, depois renomeia.

# Errado:
echo "$novo_estado" > state.yaml  # pode ser lido na metade

# Certo:
echo "$novo_estado" > state.yaml.tmp
mv state.yaml.tmp state.yaml      # rename é atômico

Captura: arquivo de estado lido pela metade, corrupção de YAML.

3

🔄 CAS de fase (Compare-and-Swap)

Antes de mudar a fase, verifica se o estado atual é exatamente o esperado. Se não for, recusa a mudança. Evita transições inválidas.

# Em vez de simplesmente "phase = reviewing":
SE phase == "drafting" ENTÃO phase = "reviewing"
SENÃO erro: transição inválida

# Garante: drafting → reviewing → summarizing → done
# Recusa: pular fase ou voltar fase

Captura: dois caminhos tentando avançar o mesmo loop simultaneamente.

4

🔐 Lockfile + PID liveness

Um arquivo de lock impede que dois processos mexam no mesmo ciclo simultaneamente. Mas o lock também guarda o PID do processo dono — se ele morreu, o lock é liberado automaticamente.

# state.yaml.lock contém:
PID: 12345

# Antes de pegar o lock, hook verifica:
SE PID 12345 ainda vivo: outra execução em andamento, abortar
SENÃO: lock antigo, liberar e prosseguir

Captura: loop morto mantendo lock fantasma, dois Claude Code abertos no mesmo projeto.

5

🧹 Varredor de loops estagnados

Loops abandonados (você fechou o terminal no meio) ficariam pra sempre travados. O hook tem um varredor que limpa estados abandonados após 15 minutos sem atividade.

# Toda vez que o hook roda, verifica:
SE state.yaml.mtime > 15min:
  loop morto, limpar arquivos:
    state.yaml, state.yaml.lock, runner.sh
  iniciar novo ciclo do zero

Captura: loop abandonado bloqueando novos ciclos, terminal fechado no meio.

6

📍 Validação de CWD

Antes de qualquer ação, o hook verifica se está rodando no diretório certo. Se você invocou Claudex no projeto A e depois mudou pro projeto B, o hook recusa operar no estado errado.

CWD esperado: /home/user/projeto-a
CWD atual:    /home/user/projeto-b

# Hook recusa, evita corromper estado de outro projeto
exit 0  # fail-open

Captura: hook disparando no projeto errado, mistura de estados entre projetos.

📌 Resumo

Fail-open — qualquer erro vira ALLOW. Usuário nunca fica preso.
Escritas atômicas — TMP + RENAME evita leitura parcial.
CAS de fase — só transita se estado é o esperado.
Lockfile + PID — impede concorrência, libera lock de processo morto.
Varredor de loops — limpa loops abandonados >15min.
Validação de CWD — recusa operar no diretório errado.

🎉 Você terminou a Trilha 2!

Agora você conhece a anatomia completa do Claudex. Próximas trilhas:

  • Trilha 3 — Uso: instalação, comandos com flags, exemplos completos
  • Trilha 4 — Avançado: customização, debugging, métricas