
Falha aberta em todos os lugares. O usuário nunca fica preso.
🛡️ 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.
⚛️ 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.
🔄 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.
🔐 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.
🧹 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.
📍 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
🎉 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