How I use Claude Code hooks in my own SDLC harness to automate safety, observability, and parallel-agent coordination
Quando comecei a executar agentes Claude Code de forma autônoma durante a noite, ficava descobrindo problemas na manhã seguinte — um arquivo escrito no lugar errado, um comando shell que rodou quando não deveria, uma longa sessão que eu não tinha como saber que havia terminado. Meu harness SDLC executa múltiplos agentes em worktrees git paralelos, cada um implementando uma tarefa diferente de uma onda ordenada por dependência. Sem visibilidade sobre o que cada agente estava realmente fazendo, eu estava voando às cegas.
Os hooks do Claude mudaram isso. Eles me dão cinco pontos específicos para interceptar, observar ou bloquear a atividade do agente: antes de uma ferramenta rodar, após ela rodar, quando o Claude precisa de atenção, quando uma sessão termina e quando um sub-agente termina. Uso-os todos os dias em produção. Este módulo percorre exatamente o que construí e por quê, começando pela verificação de segurança mais simples e chegando a uma camada de coordenação completa.
O que estamos construindo: Uma configuração de hook fundamentada em um harness SDLC multi-agente real rodando num Mac Mini atrás de um Cloudflare Tunnel — não um exemplo de brinquedo, mas a estrutura real que uso ao spawnar agentes de codificação paralelos.
Pense em hooks como os disjuntores e a camada de observabilidade do seu pipeline de agentes. Sem eles, um agente é uma caixa preta — você vê entrada e saída, mas nada no meio. Com hooks, cada chamada de ferramenta se torna um evento observável e interceptável.
O design fundamental é simples: hooks rodam como comandos shell. Eles leem contexto de variáveis de ambiente, podem escrever no stdout para logging, e controlam a execução pelo seu código de saída. Uma saída diferente de zero de um hook PreToolUse bloqueia a ferramenta completamente. Essa única regra — o código de saída determina se a ferramenta roda — desbloqueia uma quantidade enorme de controle sem modificar o Claude Code em si.
O Claude Code dispara cinco eventos de hook em pontos específicos do ciclo de vida. Cada um fornece um conjunto diferente de variáveis de ambiente e um tipo diferente de controle.
PreToolUse dispara antes de qualquer ferramenta rodar. Um código de saída diferente de zero bloqueia a ferramenta de executar. O hook recebe TOOL_NAME (como Bash ou Edit) e TOOL_COMMAND para invocações bash. É aqui que a lógica de segurança fica.
O campo matcher é uma regex correspondida ao nome da ferramenta. Use "Bash" para comandos shell, "Edit|Write" para operações de arquivo, ou ".*" para interceptar tudo.
PostToolUse dispara após uma ferramenta completar. O código de saída não tem efeito — a ferramenta já rodou. Este é o lugar certo para logging e observabilidade.
Notification dispara quando o Claude pausa no meio de uma sessão esperando pelo usuário. Conecto isso ao comando say integrado do macOS para receber um alerta de áudio quando me afasto de uma execução longa.
Stop dispara quando o Claude termina sua resposta. Uso-o para salvar a transcrição da sessão e executar uma verificação final de lint para capturar qualquer coisa que o agente perdeu.
SubagentStop dispara quando um sub-agente completa em uma sessão multi-agente. No meu harness SDLC, cada worktree paralelo roda como um sub-agente. Quando um termina, SubagentStop dispara imediatamente — sem necessidade de polling.
Padrão: Use SubagentStop para rastrear o progresso de tarefas paralelas. Cada conclusão de worktree dispara o hook, permitindo que você construa um contador simples — "3 de 5 tarefas concluídas" — sem nenhuma infraestrutura de monitoramento separada.
Checkpoint de conhecimento: Qual evento de hook bloqueia uma ferramenta de rodar quando sai com código diferente de zero — PreToolUse ou PostToolUse? Qual você usaria para registrar arquivos modificados durante uma sessão sem afetar a execução do agente?
Hooks de segurança compartilham uma estrutura comum: ler contexto de ferramenta de variáveis de ambiente, avaliar contra uma regra e sair com código diferente de zero para bloquear se a regra falhar.
A verificação de segurança mais simples bloqueia padrões perigosos específicos. Por aqui se começa — fácil de escrever, fácil de auditar, e captura os erros mais comuns.
Duas coisas a notar: a saída antecipada para ferramentas não-Bash (você não quer bloquear leituras de arquivo), e a saída mínima no stdout (útil para depuração ao revisar logs).
Uma lista de bloqueio captura comandos conhecidamente ruins mas perde os novos. No meu harness SDLC, onde agentes trabalham em worktrees paralelos, quero confiança de que apenas comandos reconhecidos rodem sem supervisão. Uma lista de permissões inverte a lógica: apenas comandos que correspondem a padrões conhecidamente seguros são permitidos automaticamente.
Comece com a lista de bloqueio: Uma lista de permissões excessivamente restritiva bloqueará trabalho legítimo do agente e fará o agente tentar novamente ou desistir. Construa a lista de permissões gradualmente revisando comandos bloqueados nos seus logs e adicionando padrões para os legítimos.
Controles de segurança protegem você de maus resultados. Observabilidade ajuda você a entender o que realmente aconteceu em uma sessão. Em um sistema multi-agente, isso importa ainda mais — qual agente escreveu qual arquivo, quando e em que ordem?
Um log JSONL (um objeto JSON por linha) é fácil de fazer stream, grep e parsear. Conecto isso a cada operação Edit e Write para construir uma trilha de auditoria completa de cada sessão.
Usar Path.home() / '.claude' / 'logs' mantém os logs de hook em um local consistente entre máquinas. A chamada mkdir(parents=True, exist_ok=True) significa que o hook funciona mesmo em uma máquina nova.
Para sessões com muitas chamadas de ferramenta, verificar entradas brutas de log é tedioso. Adiciono uma etapa de sumarização usando claude-haiku-4-5 — barato o suficiente para rodar em cada chamada de ferramenta e rápido o suficiente para não desacelerar o agente.
Custo em escala: O Claude Haiku 4.5 custa $1 por milhão de tokens de entrada. Um dia inteiro de trabalho ativo multi-agente pode gerar 300-500 chamadas de hook — bem abaixo de um dólar — e os resumos legíveis por humanos tornam a revisão de log significativamente mais rápida do que verificar strings de comando brutas.
Com segurança e logging implementados, hooks podem lidar com tarefas de coordenação em todo o sistema de agentes. Aqui está o padrão que uso para rastrear progresso em worktrees paralelos.
Meu harness SDLC executa 4-6 agentes em paralelo, cada um em um worktree git isolado, cada um implementando uma tarefa diferente de uma onda ordenada por dependência. Quando qualquer agente terminar, quero notificação imediata e uma contagem atualizada.
Todos os cinco hooks conectados. Mantenho isso em ~/.claude/settings.json para que se aplique globalmente em todos os projetos no meu Mac Mini.
uv run em vez de python: Cada script de hook pode declarar dependências inline em um bloco # /// script. O uv run as instala no primeiro uso. Sem necessidade de gerenciamento de ambiente virtual — hooks permanecem autocontidos e portáteis entre máquinas.
Reflexão: Pense nos seus próprios fluxos de trabalho de agentes. Que informação você precisaria para responder "por que esse agente demorou tanto na tarefa 3?" — e quais eventos de hook lhe dariam esses sinais? O que você mudaria na configuração acima se seus worktrees precisassem coordenar acesso a arquivos em vez de apenas rastrear conclusão?
Construa uma configuração de hook para um projeto em que você está ativamente trabalhando. Três alvos concretos:
Segurança: Escreva um hook PreToolUse que registra mas não bloqueia comandos não reconhecidos por padrão. Adicione uma flag --strict que muda para o modo de bloqueio. Isso lhe dá "modo de aviso" para exploração e "modo de execução" para execuções de produção.
Observabilidade: Estenda o logger de mudança de arquivo para também registrar um campo size_bytes — o tamanho do arquivo após a escrita. Isso permite que você veja de relance quais arquivos tiveram grandes mudanças versus pequenas.
Coordenação: Escreva um hook Stop que adiciona uma linha de resumo de sessão a um agent-log.txt de nível de projeto: ID da sessão, timestamp e o número de arquivos escritos (lido do log JSONL que o hook PostToolUse mantém).
Desafio extra: Conecte esses três hooks para que o hook Stop leia o log JSONL de mudanças, calcule o arquivo mais modificado da sessão e o inclua na linha de resumo.
1. Um script de hook PreToolUse sai com código 0. O que acontece com a chamada de ferramenta?
Correct Answer: B
Código de saída 0 significa sucesso — a ferramenta roda. Um código de saída diferente de zero (como sys.exit(1)) bloqueia a ferramenta. Esta é a convenção Unix padrão: 0 = sucesso/permitir, diferente de zero = falha/bloquear. Hooks PreToolUse usam isso para controlar a execução de ferramentas.
2. Você quer registrar cada comando Bash que roda durante uma sessão, incluindo os que você não está bloqueando. Qual hook é mais apropriado?
Correct Answer: B
PostToolUse é certo para registrar o que realmente rodou. Se um hook de segurança PreToolUse bloqueia um comando, você registraria um evento que nunca foi executado. PostToolUse dispara apenas após execução bem-sucedida, então o log reflete com precisão as ações concluídas.
3. Seu hook de segurança por lista de permissões está bloqueando comandos que o agente legitimamente precisa. Qual é a correção mais adequada?
Correct Answer: C
A correção certa é revisar seus logs de observabilidade e adicionar padrões específicos. Mudar para uma lista de bloqueio troca segurança por permissividade — só captura padrões conhecidamente ruins. Desabilitar o hook remove toda a proteção. Timeouts são irrelevantes: o hook está bloqueando na avaliação de política, não no tempo decorrido.
4. Em uma sessão multi-agente com 5 tarefas paralelas rodando como sub-agentes, qual hook dispara quando cada tarefa individual completa?
Correct Answer: B
SubagentStop dispara especificamente quando um sub-agente completa em uma sessão multi-agente. Stop dispara apenas ao final da sessão do orquestrador principal. Para rastrear progresso entre tarefas paralelas, SubagentStop fornece sinais por conclusão que você pode contar e agregar.
5. O código abaixo gera um AttributeError em tempo de execução. Qual é a substituição correta?\n\nclient = anthropic.Client()
Correct Answer: B
O SDK Python do Anthropic usa anthropic.Anthropic() — não anthropic.Client(). A classe Client não existe no SDK v1.x. O padrão correto é: from anthropic import Anthropic; client = Anthropic(). O construtor lê ANTHROPIC_API_KEY do ambiente por padrão.
6. Um hook PostToolUse sai com código 1 após registrar uma escrita de arquivo. Qual é o efeito sobre o arquivo que foi escrito?
Correct Answer: B
Hooks PostToolUse rodam após a ferramenta já ter executado e não podem afetá-la. O código de saída não tem efeito sobre a escrita concluída. É por isso que PostToolUse é o hook certo para logging e alertas — e por que PreToolUse é necessário se você precisa prevenir uma operação antes que aconteça.