Regras e Hooks: Equipando o Codex com 'Pontos de Verificação' e 'Gatilhos'
📚 Navegação da Série: A anterior 23 Plugins ensinou você a instalar capacidades empacotadas por outros no Codex com um clique. Esta fala sobre duas coisas mais fundamentais e mais "sob o seu controle" — regras (Rules) controlam "quais comandos podem rodar fora da sandbox", e hooks (Hooks) controlam "a execução automática de um script em um ponto fixo do fluxo de trabalho". Um é a comporta, o outro é o gatilho. Uma vez configurados, você não precisará mais se preocupar com tarefas repetitivas que exigiam atenção e digitação manual constante. A próxima 25 Isolamento de Paralelismo com Worktrees explicará como fazer múltiplos Codex trabalhar de forma independente, sem interferir uns nos outros.
Primeiro, vamos reconstruir uma conversa real que tive no mês passado. Eu e um colega estávamos investigando um problema de CI que vivia falhando:
Eu: "Esta semana, depois que deixei o Codex alterar o código, a quantidade de vezes que tive que rodar manualmente o
ruff formatpara complementar foi de pelo menos uma dezena de vezes." Colega: "Você não escreveu no seu AGENTS.md 'lembre-se de formatar após alterar'?" Eu: "Escrevi. Mas de cada três vezes, ele esquece de fazer uma — isso é um pedido, não uma garantia. Se falhar uma vez, a verificação de formatação do CI me manda de volta para rodar tudo de novo." Colega: "Então configure um hook. Assim que o evento for disparado, o script rodará obrigatoriamente, não importa se ele se lembra ou não."
Essa frase me abriu os olhos. Voltei e configurei um hook PostToolUse e, desde então, toda vez que o Codex altera um arquivo, a formatação roda automaticamente. Nunca mais digitei isso manualmente, e nunca mais fui rejeitado pelo CI. Este artigo explicará essas duas coisas, regras e hooks, desde o "o que são" até "como configurar e depurar".
Ao terminar de ler este artigo, você obterá:
- Uma explicação clara e rápida sobre o que as regras e os hooks controlam e por que eles alcançam a "certeza" que o AGENTS.md não consegue oferecer
- Como escrever regras (arquivos
.rules+prefix_rule) para permitir permanentemente ou proibir diretamente certos comandos, e como usarcodex execpolicy checkpara validar antes de usar - Onde configurar hooks, e quais pontos do ciclo de vida (
PreToolUse/PostToolUse/Stop/SessionStart, etc.) podem ser utilizados - O mecanismo de confiança exclusivo dos hooks do Codex — por que novos hooks não rodam por padrão e exigem que você os "assine" primeiro em
/hooks - Como os hooks conversam com o Codex (JSON no stdin, códigos de saída, JSON no stdout) e algumas diferenças contraintuitivas em relação ao Claude Code
- Dois exemplos reais prontos para copiar: formatação automática após alterações e bloqueio de comandos perigosos; além de como diagnosticar quando um hook não é disparado
⚠️ Qualquer comando específico, item de configuração ou valor padrão mencionado abaixo segue a documentação oficial do Codex (Hooks / Rules). As regras (Rules) são marcadas oficialmente como "experimentais e sujeitas a alterações", e os nomes e comportamentos das configurações podem mudar dependendo da versão local que você estiver usando.
01 Primeiro, diferencie: Regras controlam a "comporta", Hooks controlam o "gatilho"
Para começar, vamos definir claramente a divisão de tarefas entre os dois, pois seus nomes são abstratos e os iniciantes costumam confundi-los.
- Regras (Rules) resolvem se "este comando tem ou não permissão para rodar fora da sandbox" — elas funcionam como uma comporta que monitora os comandos que você deseja executar e decide entre "permitir / perguntar primeiro / proibir diretamente" com base nas normas que você definiu.
- Hooks (Hooks) resolvem a questão de "quando o fluxo de trabalho atingir determinado ponto, rodar automaticamente um script para mim" — eles funcionam como um gatilho associado a momentos específicos do ciclo de vida. Assim que o evento ocorre, o gatilho é disparado, independentemente de o Codex querer ou não executá-lo.
Analogia: Dois sistemas na entrada de um condomínio — as regras do cartão de acesso e a luz com sensor de presença. No controle de acesso, há uma lista de "quem pode entrar, quem precisa de registro, quem é barrado diretamente" — essas são as regras: toda vez que alguém passa o cartão, o sistema verifica a lista. A lâmpada com sensor no corredor, que acende assim que alguém passa, é o hook: ela não quer saber quem você é ou para onde vai, basta ocorrer o evento "alguém passou" para que ela acenda. Um atua na decisão de acesso, o outro na resposta automática — duas coisas distintas, não confunda.
E qual a diferença entre eles e o arquivo AGENTS.md (o manual de instruções do projeto, abordado no artigo 11) que você já sabe escrever? A diferença está em um ponto fundamental:
O que é escrito no AGENTS.md is um pedido; o que é configurado como regra ou hook é uma garantia.
Em suma:
- Escrever no AGENTS.md "lembre-se de formatar após alterar" ou "não mexa no banco de dados de produção" — isso é algo que você pede para o Codex fazer. Ele provavelmente obedecerá, mas em cada etapa ele estará "decidindo por si próprio", o que significa que ele pode esquecer ou deixar passar.
- Formatação configurada como hook, proibições configuradas como regras — contanto que a condição seja acionada, a ação certamente será executada (ou bloqueada), sem qualquer relação com o que o Codex deseja ou lembra.
Esse é o cerne da conversa inicial: "executar a formatação após alterações" no AGENTS.md é um pedido (falha uma em cada três vezes); configurado como um hook é uma garantia (não falha nenhuma vez).
Veja alguns cenários onde você provavelmente desejará aplicar uma "garantia":
- "Uso o comando
gh pr viewtodo dia, pare de me pedir aprovação toda vez" — use regras para abrir uma exceção de "sempre permitir" - "Comandos como
rm -rfougit push --forcedevem ser bloqueados friamente para qualquer um" — use regras ou hooks para bloqueá-los com certeza, sem depender de prompts - "Sempre que alterar arquivos, rodar automaticamente formatação / lint" — use hooks, pare de digitar manualmente e não dependa da boa vontade do Codex
💡 Resumo em uma frase: Regras são comportas para "permitir ou não a execução de um comando", hooks são gatilhos para "rodar scripts automaticamente em determinados momentos"; o valor de ambos reside em elevar os pedidos no AGENTS.md a garantias infalíveis.
02 Regras (Rules): Estabelecendo regras para comandos individuais
⚠️ Experimental, sujeito a alterações. As regras são explicitamente marcadas como recurso experimental na documentação oficial do Codex. Os campos e comportamentos abaixo seguem o padrão oficial.
Primeiro, o problema que as regras resolvem. Como discutido no artigo 15, a sandbox é um limite abrangente definido em círculos — você pode agir livremente dentro do círculo, mas fora dele precisa de permissão. No entanto, às vezes você quer um controle refinado por comando: "Mesmo fora do círculo, permita diretamente o comando gh pr view, não me perturbe" ou "Proíba o grep completamente, forçando-me a usar o rg". Expandir a sandbox inteira para isso seria muito agressivo; escrever uma regra é o caminho correto.
Analogia: Dar ao segurança uma lista de "autorizados / banidos". A sandbox é la regra padrão do segurança ("todos os estranhos devem ser registrados primeiro"), e as regras são dois bilhetes extras que você entrega a ele: um diz "deixe estes conhecidos entrarem, não os bloqueie", e o outro diz "se estas pessoas vierem, expulse-as imediatamente". O segurança agir de acordo com a lista é muito mais fácil do que perguntar a você a cada vez, além de ser mais seguro do que "remover o portão de entrada".
O que isso significa na prática:
- Comandos somente leitura de alta frequência na equipe, como
ghoumake test, criando exceções na lista branca para economizar dezenas de cliques de aprovação por dia - Marcar comandos como
grepoufindcomo desativados (pois existem alternativas melhores), forçando todos a usarrgoufd - No nível organizacional, definir diretamente prefixos de alto risco como
rm -rf /ou alterações em~/.sshcomoforbidden, estabelecendo limites invioláveis para a equipe
Onde ficam e como são os arquivos de regras
As regras são escritas em arquivos .rules, que devem ser colocados na pasta rules/ ao lado de uma camada de configuração ativa, sendo o mais comum o arquivo de nível de usuário ~/.codex/rules/default.rules. A sintaxe se parece com Python, mas na verdade é Starlark (uma linguagem de configuração projetada para execução segura sem interferir indevidamente no seu sistema de arquivos).
Uma regra simples se parece com isto — "pergunte-me antes de executar gh pr view fora da sandbox":
# 运行带 `gh pr view` 前缀的命令前,先弹审批问我。
prefix_rule(
# 要匹配的命令前缀(按参数逐个写)。
pattern = ["gh", "pr", "view"],
# 匹配到时的动作:allow(直接放行)/ prompt(先问)/ forbidden(直接拦死)。
decision = "prompt",
# 可选:写清这条规则为什么存在,审批弹窗里可能给你看。
justification = "查看 PR 允许,但要我点头",
# 可选的「内联单元测试」:举例哪些命令该命中、哪些不该,加载时 Codex 会替你验。
match = [
"gh pr view 7888",
"gh pr view --repo openai/codex",
],
not_match = [
# 不命中:pattern 必须是「精确前缀」,这条把 view 挪后面了。
"gh pr --repo openai/codex view 7888",
],
)Alguns dos campos mais importantes a entender em prefix_rule:
| Campo | Função | Observação |
|---|---|---|
pattern (obrigatório) | Prefixo do comando a ser correspondido, listado argumento por argumento | Os elementos podem ser literais como "pr", ou alternativas (OU) como ["view", "list"] |
decision (padrão allow) | O que fazer ao corresponder | allow / prompt / forbidden, a decisão mais rígida vence |
justification (opcional) | O motivo para esta regra | Pode ser exibido durante a aprovação / rejeição |
match / not_match (opcional) | Exemplos para validar se a regra está correta | O Codex executa ao carregar para detectar erros de escrita com antecedência |
Três opções para decision, com a prioridade rigidamente definida oficialmente — a mais estrita vence (forbidden > prompt > allow):
| decision | Efeito |
|---|---|
allow | Executa diretamente fora da sandbox, sem perguntar |
prompt | Pergunta primeiro a cada correspondência |
forbidden | Bloqueia diretamente, sem perguntar nem executar |
Depois de escrever o arquivo .rules, não se esqueça de reiniciar o Codex para aplicar as alterações. Outro detalhe que você notará naturalmente: ao adicionar manualmente um comando à "lista de permissões" no TUI, o Codex o gravará automaticamente no arquivo ~/.codex/rules/default.rules. Assim, esse arquivo frequentemente não é escrito do zero por você, mas cresce sozinho à medida que você o utiliza.
Um design de segurança crucial: Comandos compostos serão avaliados separadamente
Isso é extremamente importante, mencionado no artigo 15 e detalhado aqui. Quando se depara com algo como git add . && rm -rf /, que junta múltiplos comandos em uma única linha, o Codex usa o tree-sitter para desmembrá-lo em comandos individuais e avaliá-los um a um sob premissas de segurança, aplicando então a "decisão mais estrita":
["bash", "-lc", "git add . && rm -rf /"]serão avaliados separadamente como dois comandos individuais:
["git", "add", "."]
["rm", "-rf", "/"]O ponto crucial está aqui: Mesmo que você tenha configurado allow para o git add, o rm -rf / será bloqueado individualmente, impedindo que a linha inteira passe. Isso fecha a brecha de "esconder comandos perigosos atrás de comandos seguros para burlar a segurança".
Mas atenção — apenas "cadeias lineares limpas de comandos" serão desmembradas. Se o script contiver redirecionamento (>), substituição de variáveis ($(...)), atribuição de variáveis de ambiente (FOO=bar), caracteres curinga (*) ou outros recursos avançados, o Codex não irá desmembrá-lo, mas avaliará o trecho inteiro como um único bash -lc "<script completo>". Portanto, não espere que as regras detectem qualquer shell arbitrariamente complexo — o sistema verifica detalhadamente quando é "seguro desmembrar" e adota uma postura conservadora quando "não é possível desmembrar".
Após alterar las regras, valide primeiro com execpolicy check
Não vá direto para a prática. Depois de alterar os arquivos de regras, teste com codex execpolicy check em um comando para ver como ele será avaliado:
codex execpolicy check --pretty \
--rules ~/.codex/rules/default.rules \
-- gh pr view 7888 --json title,body,commentsEle retornará um JSON informando qual foi a decisão mais estrita e quais regras foram correspondidas (incluindo a justification). Eu mesmo criei o hábito ao escrever regras forbidden: validar primeiro com execpolicy check se "o que deve ser bloqueado foi bloqueado e se nada foi prejudicado por engano", antes de reiniciar o Codex. Certa vez, para poupar esforço, apliquei direto, e uma regra forbidden genérica demais acabou bloqueando até o git log que a equipe usava com frequência, o que gerou reclamações de colegas — rodar o execpolicy check teria evitado isso.
💡 Resumo em uma frase: As regras usam o
prefix_rulenos arquivos.rulespara definir normas para prefixos de comandos (allow/prompt/forbidden, a mais estrita vence); comandos compostos são desmembrados com segurança e avaliados separadamente para evitar truques; após alterações, valide comcodex execpolicy checke reinicie.
03 Hooks (Hooks): Quais pontos do ciclo de vida podem ser utilizados
Após falar sobre regras, passamos para os hooks. Os hooks não podem ser configurados em qualquer momento, eles precisam ser associados a "momentos específicos" no fluxo de trabalho do Codex — chamados oficialmente de eventos (events). O primeiro passo para usá-los bem é entender "quando eu quero que esta ação aconteça".
Lembre-se do "ciclo do agente" mencionado no artigo 02 — o trabalho do Codex é um ciclo de "pensar → agir → observar". Esses eventos estão distribuídos ao longo desse ciclo. Primeiro, vejamos uma imagem ilustrando onde os eventos mais comuns estão situados:

Esta imagem detalha o fluxo "pensar → agir → observar": ao iniciar a sessão ocorre SessionStart, quando você digita algo ocorre UserPromptSubmit, e depois entramos no ciclo "usar ou não ferramentas" — cada vez que uma ferramenta é acionada, roda PreToolUse antes e PostToolUse depois, finalizando a rodada no Stop. Dependendo de onde você quer que a ação aconteça, associe-a ao evento correspondente.
O Codex suporta outros eventos (como PreCompact/PostCompact antes e depois da compressão, SubagentStart/SubagentStop para inicialização e encerramento de subagentes, PermissionRequest ao solicitar aprovações, etc.), mas para iniciantes, dominar estes quatro cobre 90% dos cenários:
| Evento | Quando é acionado | Uso mais típico |
|---|---|---|
PreToolUse | Antes da execução de uma ferramenta | Bloquear comandos perigosos, modificar comandos (pode impedir a operação) |
PostToolUse | Depois que a ferramenta retorna um resultado | Formatar arquivos automaticamente / rodar lint |
Stop | Quando o Codex conclui uma rodada de respostas | Fazer ele "rodar mais uma vez" (por exemplo, corrigir testes falhos novamente) |
SessionStart | Ao iniciar / restaurar a sessão | Injetar o status do projeto no contexto (como os commits mais recentes) |
O quinto evento relevante é o PermissionRequest (acionado imediatamente antes de exibir a janela de aprovação), que permite autorizar ou recusar automaticamente — usado junto com as regras apresentadas na Seção 02, ele é mais flexível do que apenas regras isoladas, ideal para o cenário de "evitar aprovação de comandos de alta frequência".
Dica para memorizar esta tabela: observe os prefixos Pre e Post no nome — Pre significa "antes", logo, apenas ele pode bloquear antes que a ação aconteça; Post significa "depois", a ferramenta já terminou de rodar e não há como desfazer efeitos colaterais gerados, restando apenas "tomar uma providência a posteriori" (formatar, registrar logs ou devolver o resultado para nova análise do modelo).

Esta imagem distribui os quatro eventos acima ao longo do ciclo de vida de uma sessão do Codex: Início da sessão / Antes da chamada da ferramenta / Depois da chamada da ferramenta / Fim da sessão encadeados verticalmente como eixo principal, com um script de hook associado a cada ponto fixo. Assim que o fluxo chega a esse ponto, o script associado roda automaticamente. Essa é a essência do hook como "gatilho": você apenas o configura, e o momento determina o disparo.
Um ponto comum de erro que deve ser destacado: diferente do Claude Code, a configuração decision: "block" no evento Stop no Codex não significa "rejeitar esta rodada", mas o oposto — informa ao Codex para "não parar e rodar mais uma vez", usando a reason que você forneceu como a próxima instrução do usuário. Da mesma forma, decision: "block" em PostToolUse não desfaz o comando já executado, mas envia o feedback de volta para que o modelo continue raciocinando. O block do Codex nesses dois eventos atua como "continuar rodada / devolver para revisão", e não como "rejeição"; não aplique a intuição do Claude Code aqui.
💡 Resumo em uma frase: Hooks são associados a eventos específicos no ciclo de vida do Codex; iniciantes devem dominar primeiro
PreToolUse(antes, pode bloquear),PostToolUse(depois, complementar),Stop(após responder, pode continuar outra rodada) eSessionStart(abertura); observe que oblockdo Codex emStop/PostToolUsefunciona como "continuar / devolver para revisão", e não "rejeição".
04 Onde configurar hooks e como limitá-los com matcher
Agora que sabemos quais eventos podem ser usados, vejamos onde e como escrevê-los.
Em quais arquivos colocar os hooks
O Codex busca por hooks em dois formatos: arquivos hooks.json independentes ou na tabela [hooks] integrada no config.toml. De acordo com o padrão oficial, os quatro locais mais usados são:
| Arquivo de Configuração | Escopo de Efeito | Pode ser compartilhado com a equipe? |
|---|---|---|
~/.codex/hooks.json | Todos os seus projetos | Não, apenas em sua máquina local |
~/.codex/config.toml | Todos os seus projetos | Não |
<repo>/.codex/hooks.json | Apenas o projeto atual | Sim, pode ser enviado ao git |
<repo>/.codex/config.toml | Apenas o projeto atual | Sim |
A lógica é igual à explicada sobre configurações no artigo 15: hooks que toda a equipe deve compartilhar (como "sempre formatar após alterações") são gravados na pasta .codex/ do projeto e enviados ao git; hooks que você quer apenas para si são escritos em ~/.codex/. Atente-se a dois detalhes:
- Hooks de múltiplas fontes serão todos carregados e executados juntos — camadas de configuração de maior prioridade não substituem os hooks de menor prioridade; eles se acumulam.
- Não escreva ao mesmo tempo
hooks.jsone a tabela[hooks]integrada na mesma camada; o Codex irá mesclá-los, mas exibirá um aviso ao inicializar. A recomendação oficial é usar apenas um formato por nível. - Hooks de nível de projeto são carregados apenas se o diretório
.codex/atual for considerado "confiável" (o que é confiança será explicado na próxima seção); em projetos não confiáveis, o Codex continuará carregando os hooks globais do usuário e do sistema.
Como é uma configuração de hook
Vejamos um exemplo mínimo e completo — "sempre que o Codex rodar um comando com Bash, acionar um script", escrito no arquivo .codex/hooks.json na raiz do projeto:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use.py\"",
"timeout": 30,
"statusMessage": "Reviewing Bash output"
}
]
}
]
}
}Não se assuste com o aninhamento; são apenas três níveis de profundidade, fáceis de entender ao desmembrar:
"PostToolUse"— qual evento associar (aqui: após a ferramenta retornar resultados)."matcher": "Bash"— limitar a qual ferramenta disparará o hook (aqui: apenas após usarBash).- O array interno
hooks— a ação que realmente será executada:"type": "command"indica a execução de um comando shell, e"command"contém esse comando.
Aqui estão alguns valores padrão do Codex que são frequentemente presumidos de forma errada, por isso vamos destacá-los:
- A unidade do
timeouté "segundos", não milissegundos; se omitido, o padrão é 600 segundos. - Atualmente, apenas executores do tipo
type: "command"rodam de verdade; os tiposprompteagent"podem ser analisados, mas serão ignorados"; hooks comasync: truetambém serão ignorados (suporte a hooks assíncronos ainda não implementado). - Se houver múltiplos hooks correspondentes no mesmo evento, eles rodarão em paralelo — o seu hook de bloqueio não impedirá que outro hook associado ao mesmo evento execute simultaneamente. Esta é mais uma diferença entre o Codex e o Claude Code: ao escrever lógica de bloqueio no
PreToolUse, não presuma que ele "terminará de rodar antes de decidir se outros hooks serão executados". - O diretório de trabalho do comando é o
cwdda sessão. Portanto, para hooks no repositório, a recomendação oficial é não usar caminhos relativos como.codex/hooks/..., pois o Codex pode ser iniciado a partir de subdiretórios — use$(git rev-parse --show-toplevel)para obter um caminho absoluto robusto a partir da raiz do git (como feito no exemplo acima). - Se quiser usar comandos diferentes no Windows, adicione o campo opcional
command_windows(também aceitacommandWindowsno TOML) para sobrescrever.
⚠️ É importante esclarecer algumas diferenças em relação ao Claude Code para evitar que você copie notas de lá e cometa erros: o
timeoutdo hook no Codex é em segundos (no Claude Code é em milissegundos), não existe a variável$CLAUDE_PROJECT_DIR(use a raiz do git no lugar) e não há um interruptor geral comodisableAllHooks(para desligar, mude para[features] hooks = false). Nomes semelhantes com significados diferentes, não confunda.
Escrever de forma equivalente em formato integrado no config.toml se parece com isto:
[[hooks.PostToolUse]]
matcher = "^Bash$"
[[hooks.PostToolUse.hooks]]
type = "command"
command = '/usr/bin/python3 "$(git rev-parse --show-toplevel)/.codex/hooks/post_tool_use.py"'
timeout = 30
statusMessage = "Reviewing Bash output"matcher:Fazendo o hook "disparar apenas quando necessário"
O matcher é o campo mais importante a compreender na configuração de hooks. Em resumo: sem ele, o hook disparará "toda vez" que o evento ocorrer; com ele, você limita o escopo.
Analogia: A lâmpada com sensor no corredor novamente — você precisa ajustar a área de detecção. Se o sensor cobrir o andar inteiro, a luz acenderá toda vez que alguém andar no apartamento vizinho, desperdiçando energia. Você deve ajustar a área de detecção para "apenas o trecho do corredor na frente da sua porta". O matcher desempenha exatamente essa função de "limitar a área de detecção".
Há uma diferença fundamental entre o matcher do Codex e o do Claude Code: no Codex ele é uma string de expressão regular (regex). Para eventos do tipo ferramenta (PreToolUse/PostToolUse), ele realiza correspondência com o nome da ferramenta. Veja os formatos de escrita na tabela abaixo:
| matcher Configurado | Significado | Exemplo |
|---|---|---|
"Bash" | Corresponde à ferramenta Bash | Disparado apenas ao rodar comandos Bash |
"^apply_patch$" | Correspondência exata via regex | Disparado apenas ao alterar arquivos |
"Edit|Write" | Alias para alteração de arquivos (| é o operador "OU" da regex) | Disparado apenas depois de editar / gravar arquivos |
"mcp__filesystem__.*" | Correspondência de múltiplos caminhos de ferramentas MCP via regex | Todas as ferramentas desse MCP server |
"*" / "" / Omitido | Corresponde a todos | Executado sempre que o evento ocorrer |
Algumas das armadilhas mais comuns para iniciantes:
- O nome real da ferramenta para alterar arquivos é
apply_patch, nãoEdit/Write. O Codex altera arquivos por meio do mecanismoapply_patch— você pode usar qualquer um deEdit,Writeouapply_patchnomatcher(são aliases), mas otool_nameno stdin recebido pelo hook sempre indicará"apply_patch". Se for fazer validação de nome de ferramenta no script, procure porapply_patch. - Nem todos os eventos aceitam o
matcher. Os eventosUserPromptSubmiteStopignoram omatcher; mesmo que você o escreva, ele será ignorado porque não há um "nome de ferramenta" para filtrar, disparando sempre. No entanto,SubagentStopé diferente, seumatcheratua noagent_typee é suportado — não confundaSubagentStopcomStop. OmatcheremSessionStartnão faz correspondência com nomes de ferramentas, mas sim com "como a sessão foi iniciada" (startup/resume/clear/compact). PreToolUsenão bloqueia todos os comandos. A documentação oficial é bem direta: trata-se de um "guard-rail, não uma barreira de segurança impenetrável" — atualmente ele bloqueia apenas chamadas simples de shell,apply_patche ferramentas MCP; shells mais complexos (que utilizamunified_exec) ou buscas comoWebSearchnão são interceptados. Portanto, não use oPreToolUsecomo sua única linha de defesa de segurança; ele é apenas uma "comporta extra", não uma "muralha impenetrável".
💡 Resumo em uma frase: Hooks são gravados em
~/.codex/ou no diretório.codex/do projeto em arquivoshooks.jsonouconfig.toml, contendo apenas três camadas — evento, matcher, ação; memorize as regras exclusivas do Codex: a unidade dotimeouté segundos (padrão 600), a ferramenta de alteração de arquivo éapply_patch, omatcherusa regex e use a raiz do git para estruturar caminhos.
05 Mecanismo de Confiança: Por que seus novos hooks "não rodam por padrão"
Esta seção aborda a maior diferença entre os hooks do Codex e do Claude Code, e também o ponto onde iniciantes se confundem com mais frequência: você configurou o hook perfeitamente, mas ele não rodou — porque o Codex não confia nele por padrão.
Primeiro, o motivo dessa restrição. Hooks são scripts shell executados com suas permissões completas de usuário, capazes de excluir qualquer arquivo acessível por você ou enviar dados pela rede. Se você copiar um plugin da internet ou clonar um repositório que traga um hook embutido e ele rodar automaticamente, seria o equivalente a permitir que qualquer pessoa executasse códigos ocultos na sua máquina. Por isso, o Codex adicionou uma etapa de "assinatura visual obrigatória".
Analogia: Um novo aplicativo solicitando permissões pela primeira vez exige que você clique em "Permitir". Ao instalar um aplicativo novo que queira usar a câmera ou enviar notificações, o sistema operacional não libera as permissões por padrão; ele exibe uma janela perguntando "Permitir?" — se você não clicar, o aplicativo não conseguirá utilizá-los. O mecanismo de confiança de hooks do Codex funciona da mesma forma: hooks de comando não gerenciados precisam que você "dê uma olhada e confie neles" primeiro; caso contrário, serão ignorados indefinidamente e não rodarão.
As regras oficiais são muito claras:
- O Codex registra a confiança com base no hash atual da definição do hook. Logo, hooks recém-adicionados ou modificados serão marcados como "pendentes de revisão", sendo ignorados sistematicamente até que você os declare confiáveis. Modificar um único caractere altera o hash, exigindo aprovação novamente.
- Use o comando
/hookspara visualizar as fontes dos hooks, revisar adições/modificações, aprová-los ou desativar hooks não gerenciados específicos. - Se houver hooks pendentes de revisão ao iniciar, o Codex exibirá um alerta instruindo você a abrir
/hooks.
Portanto, o procedimento padrão após configurar um hook pela primeira vez é: configurar → iniciar o Codex (você poderá ver um aviso de "hooks pendentes") → digitar /hooks → encontrar o seu hook, garantir que o comando está correto → aprová-lo como confiável. Só então ele passará a disparar. Quando configurei meu primeiro hook de formatação, acabei ignorando esse passo; o Codex alterava arquivos, mas a formatação não rodava de jeito nenhum. Achei que meu matcher estava incorreto e passei muito tempo depurando até perceber — ele simplesmente não estava aprovado e, por isso, não executava.
/hooksResultado esperado: Uma interface de gerenciamento de hooks será exibida, listando todas as fontes de hooks e sinalizando quais estão pendentes ("review"), confiáveis ou gerenciados ("managed"). Hooks gerenciados (provenientes do sistema, MDM, requirements.toml corporativos, etc.) são confiáveis "por política de diretiva" e não podem ser desativados nesta interface — eles são bloqueados administrativamente.
Há também uma alternativa de uso único: se você estiver rodando em um ambiente como CI, onde "as fontes dos hooks já foram revisadas fora do Codex", pode usar a flag --dangerously-bypass-hook-trust na inicialização para pular a verificação. O termo dangerously no nome serve para alertar — não use isso no dia a dia na sua máquina local, pois desativa essa importante proteção de segurança.
⚠️ Retornando às diretrizes de segurança (artigo 16): sempre revise linha por linha o comando de qualquer hook no
/hooksantes de ativá-lo, e nunca confie cegamente em trechos inteiros copiados de plugins ou repositórios desconhecidos. O mecanismo de confiança é a última linha de defesa que o Codex estabelece para você, mas a decisão final ao clicar em "confiar" é totalmente sua.
💡 Resumo em uma frase: Os hooks do Codex possuem um mecanismo de confiança — hooks não gerenciados não rodam por padrão; após adição/modificação, você precisa "revisar e confiar" neles via
/hooks(verificado via hash; qualquer caractere alterado exige nova aprovação); essa é a maior diferença em relação ao Claude Code e a principal causa de "hooks não disparando".
06 Como os hooks conversam com o Codex: stdin, códigos de saída e stdout
Esta seção é a chave para entender todo o funcionamento. Como o script recebe os detalhes do comando? Como um hook consegue "bloquear" a execução de um comando? As respostas estão nesse "mecanismo de comunicação", que segue os mesmos princípios de entrada e saída descritos no artigo 16.
O funcionamento é simples e usa três canais de fluxo: o Codex envia os dados do evento via stdin para o seu script → o script executa → o script instrui o Codex sobre o que fazer a seguir usando uma combinação de "código de saída + stdout".
Entrada: O Codex entrega um JSON via stdin
Assim que o evento ocorre, o Codex envia os dados relacionados a esse evento no formato JSON pelo fluxo de entrada padrão (stdin) para o seu comando. Todos os hooks recebem alguns campos em comum:
| Campo | Significado |
|---|---|
session_id | ID da sessão atual |
cwd | Diretório de trabalho da sessão |
hook_event_name | Nome do evento atual |
transcript_path | Caminho do arquivo de histórico da sessão (pode ser null) |
model | Slug do modelo ativo no momento (extensão exclusiva do Codex para tratamentos específicos dependendo do modelo) |
permission_mode | Modo de permissão atual (disponível na maioria dos eventos, pode estar ausente em alguns eventos específicos) |
Eventos associados a ferramentas também contam com os campos tool_name (por exemplo, "Bash", "apply_patch") e tool_input (a entrada específica da ferramenta; para Bash e apply_patch, o comando fica em tool_input.command). Por exemplo, ao executar um comando Bash, o hook de PreToolUse receberá algo semelhante a isto:
{
"session_id": "abc123",
"cwd": "/Users/sarah/myproject",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf /tmp/x"
}
}Viu só? — O que o Codex fará, qual ferramenta utilizará e quais parâmetros passará está tudo detalhado ali. Seu script só precisa extrair o tool_input.command desse JSON para avaliar se deve ou não bloquear o comando.
Saída: Usando "códigos de saída" para controlar o Codex
Depois de executar o trabalho, o script sinaliza a ação básica para o Codex por meio do código de saída (exit code):
| Código de Saída | Significado | Efeito |
|---|---|---|
0 | Sem objeções, prosseguir normalmente | A operação continua; ausência de saída é considerada sucesso |
2 | Sinalização especial | Bloqueio / continuação de rodada, etc. (o comportamento varia por evento, veja abaixo) |
| Outros | Sem definição oficial explícita | Segue o comportamento prático observado |
O ponto principal é o exit 2, mas ele possui significados diferentes em eventos distintos. Essa característica varia entre o Codex e o Claude Code, portanto preste muita atenção:
- No
PreToolUse/UserPromptSubmit:exit 2+ escrever o motivo no stderr = bloqueia a operação/prompt atual. - No
PostToolUse/Stop/SubagentStop:exit 2+ stderr não significa "bloquear" (a ferramenta já foi executada), mas sim devolver essa explicação como feedback — oPostToolUsea usa para substituir o resultado da ferramenta e fazer o modelo reavaliar, enquanto oStopinstrui o Codex a rodar mais uma rodada (veja a Seção 03 para detalhes).
Em outras palavras, apenas eventos da categoria Pre podem "bloquear"; receber exit 2 em Post/Stop serve apenas para "devolver/continuar", sem poder desfazer ações que já foram concluídas.
Avançado: Retornando JSON via stdout para controle refinado
Os códigos de saída oferecem apenas controle básico. Para obter um controle refinado (como bloquear e simultaneamente informar o motivo, ou injetar informações no contexto), utilize exit 0 e exiba um JSON no stdout. Vejamos dois dos cenários mais comuns:
① PreToolUse deseja bloquear a ação informando um motivo — retorne permissionDecision: "deny":
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "这条命令会动生产库,已拦截"
}
}O Codex também aceita a sintaxe legada
{"decision": "block", "reason": "..."}, com o mesmo efeito. Ambos funcionam, mas a nova sintaxe tem semântica mais clara.
② SessionStart deseja injetar informações no contexto — retorne additionalContext, que será alimentado para o modelo como "contexto adicional de desenvolvedor":
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "编辑前先读一遍本仓库的代码规范。"
}
}Existem algumas armadilhas de convenção de saída no Codex a serem observadas:
- Textos puros enviados ao stdout no
PreToolUseserão ignorados — para injetar contexto use o campoadditionalContextdo JSON; para bloquear, usepermissionDecisionouexit 2. Fazer apenasechode uma mensagem não terá efeito. - Saídas de texto puro no stdout para
SessionStarteUserPromptSubmitserão tratadas como contexto e inseridas no fluxo (comportamento especial destes dois); porém,StopeSubagentStopexigem obrigatoriamente um JSON, e texto puro resultará em erro. - O
PreToolUsenão aceita campos comocontinue/stopReason. Se você tentar retorná-los, o Codex sinalizará o hook como falho, registrará um erro, mas prosseguirá da mesma forma com a execução da ferramenta — portanto, não conte comcontinue: falsenoPreToolUsepara tentar bloquear ações.
💡 Resumo em uma frase: Hooks e o Codex conversam através de três canais — JSON via stdin, códigos de saída para diretivas e JSON via stdout para controle refinado; decore as regras do Codex:
exit 2em eventos do tipoPresignifica "bloquear", enquanto emPost/Stopsignifica "devolver/continuar rodada"; alteração de arquivo é identificada comoapply_patch; texto puro no stdout paraPreToolUseé ignorado.
07 Dois exemplos reais prontos para copiar
Basta de teoria. Vejamos dois dos hooks mais úteis e prontos para uso. Cada um indica claramente "qual evento associar, onde delimitar e em qual arquivo configurar".
Exemplo 1: Formatação automática de arquivos após alterações (PostToolUse)
Este é o hook que resolve o problema de "esquecer de formatar" citado no início. É extremamente prático e livre de riscos, por isso é altamente recomendável configurá-lo em todos os projetos.
Passo 1: Escreva a lógica de formatação no script .codex/hooks/format.py (lê o JSON do stdin, obtém os caminhos dos arquivos modificados e os repassa para a ferramenta de formatação). Estrutura mínima de exemplo:
#!/usr/bin/env python3
import json, subprocess, sys
data = json.load(sys.stdin)
# apply_patch 的 tool_input.command 里是补丁内容;实际项目里
# 通常直接对整个工作区跑格式化,简单稳妥:
subprocess.run(["ruff", "format", "."])Passo 2: Registre o hook no arquivo .codex/hooks.json na raiz do projeto, associando-o ao PostToolUse de apply_patch (você pode usar Edit|Write ou apply_patch no matcher, pois são aliases):
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/format.py\"",
"timeout": 30,
"statusMessage": "格式化改动文件"
}
]
}
]
}
}Passo 3 (Crítico, não se esqueça): Após iniciar o Codex, execute /hooks e declare o hook como confiável — sem isso, ele não executará (conforme explicado na Seção 05). A partir daí, sempre que o Codex alterar arquivos, a formatação rodará de forma automática. O mesmo fluxo funciona substituindo ruff format por prettier --write ., gofmt -w . ou black ..
Exemplo 2: Bloquear comandos perigosos (PreToolUse + script)
Este exemplo utiliza a intercepção com exit 2. Quando as regras de validação são complexas, estruturar a lógica em um script dedicado é muito mais limpo do que inseri-la diretamente no JSON de configuração.
Passo 1: Salve o script em .codex/hooks/block-dangerous.py:
#!/usr/bin/env python3
import json, sys
data = json.load(sys.stdin)
command = data.get("tool_input", {}).get("command", "")
if "rm -rf" in command:
print("Blocked: 检测到 rm -rf,已拦截", file=sys.stderr) # 写 stderr,反馈给 Codex
sys.exit(2) # exit 2 = 拦住这次调用
sys.exit(0) # 其余命令放行,走正常审批流程Passo 2: Registre o hook no arquivo .codex/hooks.json, associando-o ao PreToolUse do Bash:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/block-dangerous.py\"",
"statusMessage": "检查 Bash 命令"
}
]
}
]
}
}Passo 3: Aprove a confiança no /hooks. A partir desse momento, se o Codex tentar executar um comando Bash contendo rm -rf, o hook retornará exit 2 para bloqueá-lo e enviará a justificativa de volta para o modelo.
⚠️ Tanto regras quanto hooks são capazes de bloquear comandos perigosos — regras com
forbiddensão mais leves (exigem apenas uma declaração de linha, sem necessidade de escrever scripts), enquanto hooks oferecem mais flexibilidade (permitem rodar qualquer lógica complexa e tomar decisões analisando o JSON completo). Prefira regras para proibições simples de prefixos de comandos; use hooks caso precise realizar avaliações refinadas sobre o conteúdo dos comandos (como "bloquear apenas comandosrmque afetem diretórios específicos"). Evite configurar a mesma regra em ambos os sistemas para não gerar confusões.
| Dimensão | Exemplo 1: Formatação Automática | Exemplo 2: Bloquear Comandos Perigosos |
|---|---|---|
| Evento associado | PostToolUse (a posteriori) | PreToolUse (a priori) |
| matcher | Edit|Write (= apply_patch) | Bash |
| Mecanismo principal | Formata após a execução, não bloqueia | Bloqueia retornando exit 2 |
| Riscos | Livre de riscos, acessível a todos | Erros no script podem bloquear comandos válidos |
| Pode ser feito via regras? | Não (regras lidam apenas com permissão de comandos) | Sim, prefira regras para proibições simples |
💡 Resumo em uma frase: Dois exemplos de hooks com risco incremental — formatação (
PostToolUse, livre de riscos, altamente recomendado para todos) e bloqueio de comandos (PreToolUse+ script +exit 2); use$(git rev-parse --show-toplevel)para construir caminhos seguros para os scripts, e lembre-se de aprová-los via/hooks; prefira usar regras no lugar de hooks para bloqueio de comandos simples.
08 Prática: Configure um hook em 5 minutos e veja-o disparar em tempo real
Apenas ler sem praticar não ajuda a fixar. Abaixo, acompanharemos a configuração do hook mais seguro e com efeito visual imediato — sempre que o Codex rodar um comando Bash, gravar esse comando em um arquivo de log. Esse procedimento não afeta em nada seus códigos e usa apenas configurações simples que você poderá testar e validar pessoalmente.
⚠️ Nota sobre plataformas: O script é escrito em Python e roda no Mac, Linux ou Windows (no Windows, substitua
python3porpy -3ou utilize o campocommand_windows). Abaixo, tomamos o Mac / Linux como exemplo.
Passo 1: Crie uma pasta de testes e adicione o script e a configuração do hook
Escolha qualquer pasta vazia (não faça isso em projetos de produção) e crie dois arquivos dentro dela. O script em .codex/hooks/log-bash.py:
#!/usr/bin/env python3
import json, sys, os
data = json.load(sys.stdin)
command = data.get("tool_input", {}).get("command", "")
log = os.path.expanduser("~/codex-bash-log.txt")
with open(log, "a") as f:
f.write(command + "\n")O arquivo de configuração em .codex/hooks.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/log-bash.py\"",
"statusMessage": "记录 Bash 命令"
}
]
}
]
}
}Nota: O campo
commandusagit rev-parse --show-toplevelpara resolver o caminho; portanto, essa pasta de testes precisa ser inicializada como um repositório git (git init), caso contrário o comando falhará ao buscar a raiz do repositório. Se preferir pular essa etapa, pode substituir o trecho pelo caminho absoluto direto do script.
Passo 2: Inicie o Codex a partir desta pasta e aprove a confiança do hook
codexUma vez iniciado, digite /hooks:
/hooksResultado esperado: A interface de gerenciamento de hooks abrirá e você visualizará o hook de PostToolUse configurado, provavelmente marcado como "pendente de revisão" (review). Selecione-o, confirme que o comando está correto e declare-o confiável (a etapa crucial descrita na Seção 05). Ver o status mudar de "review" para confiável significa que o hook está pronto para disparar.
Passo 3: Peça para o Codex rodar um comando Bash para acionar o hook
Retorne à janela de diálogo e peça para executar um comando simples e inofensivo:
帮我用 ls 看一下当前目录有哪些文件Ele acionará a ferramenta Bash para executar ls. Isso disparará o hook de PostToolUse. (A execução bem-sucedida de um hook normalmente ocorre de forma "silenciosa", sem exibir notificações adicionais no terminal — este é o comportamento esperado.)
Passo 4: Valide se o hook realmente rodou verificado o arquivo de log
Abra uma nova janela de terminal e verifique os logs:
cat ~/codex-bash-log.txtResultado esperado: O arquivo listará o comando ls executado há pouco (junto com quaisquer outros comandos Bash rodados na sessão). Ver o comando registrado indica que o hook realmente dispara automaticamente após o uso do Bash, confirmando que sua automação está ativa.
Passo 5: Limpeza (Opcional)
Para remover o teste é simples: exclua a respectiva seção no .codex/hooks.json (hooks não possuem comandos de desinstalação específicos; basta removê-los do arquivo de configuração) e delete o arquivo de log usando rm ~/codex-bash-log.txt.
Ao completar esses cinco passos, você experimentou pessoalmente o ciclo completo de "escrever configuração → aprovar confiança no /hooks → acionar o evento → verificar efeitos colaterais". Qualquer hook que você venha a configurar no futuro seguirá esse mesmo fluxo básico, alterando apenas o evento, o matcher ou o script de ação — mas lembre-se: nunca se esqueça da etapa de aprovação no /hooks no Codex.
💡 Resumo em uma frase: Testar configurações com hooks inofensivos como o de "gravar logs de comandos Bash" é a forma mais segura — grave no
.codex/hooks.json, aprove no/hooks, peça para rodar um comando e verifique o arquivo de logs; o Codex introduz a barreira de aprovação de confiança ausente no Claude Code, por isso é importante passar pelo fluxo completo para evitar problemas futuros.
09 O que fazer se o hook não disparar ou retornar erro
Hooks que não funcionam após a configuração são um dos pontos onde iniciantes mais se deparam com dificuldades. Evite adivinhações e siga a ordem de verificação abaixo para localizar a falha, estruturada em formato "Sintoma → O que verificar":
| Sintoma | Causa mais provável / O que verificar |
|---|---|
| O hook não dispara de forma alguma | ① Será que ele não foi aprovado como confiável no /hooks? Essa é a armadilha número um do Codex (Seção 05); ② Se o hook foi alterado, o hash mudou e exige aprovação de confiança novamente; ③ O evento ou o matcher foi selecionado incorretamente |
O hook configurado sequer aparece no /hooks | ① O formato JSON está inválido (vírgulas pendentes ao final ou comentários não são permitidos); ② O local do arquivo ou o nome do arquivo está incorreto (hooks.json ou formato [hooks] integrado no config.toml); ③ Múltiplos formatos configurados no mesmo nível foram mesclados gerando avisos; ④ Reinicie a aplicação após as alterações |
Erro de command not found / Script não localizado | Caminho incorreto. O diretório de execução dos comandos é o cwd da sessão; use $(git rev-parse --show-toplevel) para obter um caminho absoluto e evite caminhos relativos como .codex/hooks/... |
| O hook deveria bloquear a ação, mas não bloqueou | ① Provavelmente foi associado ao evento incorreto (bloqueios exigem o PreToolUse, o PostToolUse não é capaz de interromper); ② O PreToolUse nativamente não bloqueia shells complexos ou WebSearch (Seção 04); ③ O bloqueio exige retornar exit 2 ou permissionDecision: "deny"; texto simples impresso não tem efeito |
| O hook foi finalizado por timeout | A unidade do timeout é segundos (padrão 600), não confunda com milissegundos; aumente o limite para execuções mais longas |
Destacamos duas das ferramentas de diagnóstico mais úteis:
① Alimentar dados fictícios manualmente para testar o script. Você não precisa disparar o fluxo real dentro do Codex; crie uma entrada JSON estruturada e envie-a via pipe para o script, validando o código de retorno obtido:
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /tmp/x"}}' | python3 .codex/hooks/block-dangerous.py
echo $? # 看退出码:拦截脚本这里应该输出 2Esta é a prática padrão para calibrar hooks de intercepção — valide o comportamento correto do script isoladamente antes de integrá-lo ao Codex, poupando tentativas desnecessárias em sessões ativas.
② Validar regras usando codex execpolicy check (ótima ferramenta de diagnóstico para regras, detalhada na Seção 02). Se uma regra não permitir ou bloquear uma chamada conforme o esperado, execute o teste com o respectivo comando para descobrir a decisão lógica aplicada, eliminando suposições.
Outra dica de utilidade prática: se quiser desativar temporariamente todos os hooks, o Codex não possui um interruptor dedicado como disableAllHooks do Claude Code. Em vez disso, altere o config.toml:
[features]
hooks = false💡 Resumo em uma frase: Se o hook falhar, a primeira providência é verificar "se ele foi aprovado no
/hooks" (a armadilha principal e exclusiva do Codex), e em seguida verificar se o matcher, o evento e os caminhos com raiz do git estão corretos; se o bloqueio falhar, veja se não foi associado erroneamente aoPostToolUseou se oexit 2não foi retornado; para problemas com regras, valide com oexecpolicy check.
10 Resumo
Este artigo percorreu todo o caminho sobre regras e hooks, desde os conceitos fundamentais até a escrita e diagnóstico — ambos são ferramentas que equipam o Codex com "comportas" e "gatilhos": regras monitoram quais comandos rodam fora da sandbox, enquanto hooks disparam automaticamente em momentos fixos do ciclo de vida, elevando os simples pedidos descritos no AGENTS.md a garantias robustas.
Revisão consolidada dos pontos fundamentais:
| O que você deseja fazer | O que usar | Ponto-chave |
|---|---|---|
| Permitir ou bloquear um comando permanentemente | Regras em prefix_rule | allow/prompt/forbidden, a mais estrita vence; valide com execpolicy check após alterações |
| Escolher o ponto de disparo correto do hook | Eventos do ciclo de vida | Pre consegue bloquear, Post faz complementos, Stop estende a rodada e SessionStart faz a inicialização |
| Escrever um hook | Configure no hooks.json ou config.toml | Três níveis: evento + matcher (regex) + ação; a unidade do timeout é segundos |
| Fazer o novo hook rodar de verdade | Aprovação no /hooks | Exclusivo do Codex: hooks não gerenciados não rodam por padrão; qualquer caractere alterado exige nova aprovação |
| Fazer o hook e o Codex se comunicarem | stdin / código de saída / stdout | exit 2 em Pre bloqueia, enquanto em Post/Stop devolve ou continua a rodada |
| O hook não está funcionando | Diagnosticar em ordem | Primeiro verifique a aprovação de confiança, depois matcher, evento e caminhos |
Agora você deve ser capaz de: explicar o escopo de atuação de regras e hooks, apontando a diferença conceitual em relação a "pedidos definidos no AGENTS.md" (garantia vs pedido); escrever regras via prefix_rule e testá-las com execpolicy check; saber situar PreToolUse/PostToolUse/Stop/SessionStart no fluxo de trabalho do Codex; registrar um hook com matcher estruturado no hooks.json, lembrando-se de aprová-lo no /hooks; compreender o fluxo de comunicação do hook via stdin / código de saída / stdout com o Codex, discernindo as diferenças contraintuitivas em relação ao Claude Code (timeout em segundos, ferramenta apply_patch, comportamento de block estendendo rodada e validação de confiança). A tarefa penosa de "rodar a formatação manualmente dezenas de vezes por semana" descrita no início agora pode ser resolvida definitivamente por você usando um hook.
💡 Resumo em uma frase: Regras são "comportas" e hooks são "gatilhos"; a combinação de ambos eleva os pedidos no AGENTS.md a garantias invioláveis. O mecanismo de confiança exclusivo do Codex, hooks executados de forma concorrente,
timeoutem segundos e o identificadorapply_patchsão as principais particularidades em relação ao Claude Code nas quais é fácil cometer erros.
A próxima 25 Isolamento de Paralelismo com Worktrees — até aqui, você manteve o fluxo de "um Codex fazendo uma coisa por vez". Mas quando o ritmo de desenvolvimento acelera, você pode se perguntar: será possível ter um Codex corrigindo um bug e outro implementando uma nova funcionalidade simultaneamente, sem que eles interfiram um no outro? Abrir duas sessões ativas no mesmo repositório pode facilmente sobrescrever as modificações de cada um. O próximo artigo discutirá o Git worktree, uma técnica clássica e extremamente eficiente — criar áreas de trabalho independentes para cada tarefa, permitindo que múltiplos Codex trabalhem em paralelo de verdade. Pense nisso: hoje, se você precisa trabalhar em duas tarefas simultaneamente, precisa finalizar uma para começar a outra?