Правила и хуки (Rules & Hooks): точки контроля и триггеры для Codex
📚 Навигация по серии: Предыдущая статья [23 · Плагины (Plugins)] научила вас устанавливать готовые пакеты функций одной командой. В этой главе мы поговорим о более фундаментальных механизмах, управление которыми полностью в ваших руках: правила (Rules) определяют разрешения на запуск консольных команд вне песочницы, а хуки (Hooks) настраивают автоматический запуск фоновых скриптов на определенных этапах рабочего процесса. Первые служат барьерами контроля, а вторые — системными триггерами. Их настройка избавит вас от необходимости контролировать выполнение рутины вручную. В следующей главе [25 · Изоляция рабочих копий Worktrees] мы разберем запуск нескольких параллельных сессий Codex без взаимных конфликтов.
Начнем с реального диалога, который произошел у меня в прошлом месяце при отладке постоянно падающей сборки CI:
Я: «На этой неделе после работы Codex мне приходилось вручную запускать форматирование через
ruff formatуже раз десять». Коллега: «Но разве у тебя вAGENTS.mdне прописано правило „всегда форматировать код после правок“?» Я: «Прописано. Но в одном случае из трех он забывает это сделать. Запись вAGENTS.md— это рекомендация, а не гарантия. Стоит пропустить один файл, и линтер в CI заворачивает всю сборку». Коллега: «Так настрой системный хук! При наступлении события скрипт запустится автоматически, независимо от памяти модели».
Эта мысль оказалась верной. Я настроил хук на событие PostToolUse. С тех пор после изменения любого файла Codex автоматически запускает форматирование. Я больше ни разу не вводил команду вручную, а сборки CI проходят без ошибок. В этой главе мы детально разберем устройство правил и хуков: от теории к практике настройки.
После прочтения этой статьи вы получите:
- Различия между правилами (Rules) и хуками (Hooks), их отличие от рекомендаций в
AGENTS.md - Синтаксис написания правил в файлах
.rulesс помощью функцииprefix_rule, управление режимами согласования и проверка черезexecpolicy check - Список системных событий жизненного цикла (
PreToolUse,PostToolUse,Stop,SessionStart) для запуска фоновых скриптов - Устройство встроенного механизма доверия к хукам в Codex: почему новые скрипты заблокированы по умолчанию и как подтвердить их в
/hooks - Обмен данными между Codex и скриптом: парсинг JSON в stdin, коды возврата и структура выходного JSON в stdout
- Два готовых примера автоматизации: автоматическое форматирование кода и фильтрация опасных вызовов в консоли
⚠️ Все консольные команды, ключи конфигурации и значения по умолчанию приведены согласно официальной документации Codex (Hooks / Rules). Система правил находится на этапе тестирования, синтаксис параметров может меняться.
01 Различия: правила как барьеры, хуки как триггеры
Начнем с главного:
- Правила (Rules) определяют допуски запуска команд вне песочницы. Это системный барьер, оценивающий каждую вызываемую команду по принципу «разрешить / спросить / заблокировать».
- Хуки (Hooks) отвечают за автоматический запуск скриптов на определенных этапах жизненного цикла сессии. Это триггер, который сработает в установленный момент независимо от логики модели.
Аналогия: правила доступа на КПП vs автоматическое освещение в подъезде. База данных охранника на КПП содержит список жильцов («кого впускать без вопросов, у кого проверять документы, кого блокировать на входе»). Это правила: охранник сверяется со списком при каждом обращении. Датчик движения, включающий свет в подъезде при прохождении человека — это хук. Датчику не важно, кто именно идет и с какой целью, событие прохождения человека является системным триггером для включения лампы. Охранник ограничивает доступ, датчик — автоматически реагирует. Не путайте эти понятия.
Чем они отличаются от инструкций в AGENTS.md (глава 11)? Разница принципиальна:
写进 AGENTS.md 的,是请求;配成规则或钩子的,是保证。
Простыми словами:
- Инструкции в
AGENTS.md(«всегда форматируй код», «не изменяй файлы конфигурации») являются просьбами к Codex. Агент постарается их выполнить, но в процессе работы может забыть или пропустить шаг. - Хуки и правила выполняются на системном программном уровне. Запуск скрипта или блокировка команды произойдут в 100% случаев, независимо от логики модели.
Использование системных барьеров и триггеров решает частые проблемы рутины:
- «Я часто использую команду
gh pr view, избавьте меня от постоянных кликов подтверждения» — пропишите правило автоматического пропуска; - «Команды удаления
rm -rfили форсированного пушаgit push --forceдолжны быть полностью заблокированы для AI» — пропишите запрет в правилах; - «Код должен форматироваться автоматически после каждого изменения» — настройте хук, не надеясь на память модели.
💡 Резюме одной фразой: правила выступают в роли барьеров безопасности для команд консоли, а хуки — триггеров фонового запуска скриптов. Их общая задача — перевести рекомендации из
AGENTS.mdв категорию гарантированно выполняемых системных правил.
02 规则(Rules):给单条命令立规矩
⚠️ Экспериментальная функция. Система правил находится на этапе тестирования, синтаксис параметров может меняться.
Песочница ограничивает права Codex «по областям» (глава 15): запись разрешена внутри рабочей директории и запрещена за ее пределами. Но иногда требуется точечный контроль команд: «команда gh pr view безопасна и должна выполняться без вопросов даже за рамками рабочей области», а «утилита grep устарела, заставьте Codex использовать rg». Для этого настраиваются правила.
Аналогия: список исключений для охранника. Общие правила песочницы гласят: «все незнакомцы должны регистрироваться на входе». Вы даете охраннику два списка: «этих людей впускай без регистрации» (белый список правил) и «этих людей не впускай ни при каких условиях» (черный список). Это упрощает контроль и повышает безопасность.
Сферы применения правил:
- Автоматический пропуск частых утилит (
gh,make test), экономящий время на клики в чате; - Блокировка устаревших команд (
grep,find) с предложением современных аналогов; - Жесткий запрет деструктивных вызовов (
rm -rf /, изменение ключей~/.ssh).
Синтаксис и место хранения файлов
Правила прописываются в файлах с расширением .rules, которые должны находиться в папке rules/ каталога настроек. Глобальные правила пользователя хранятся по пути ~/.codex/rules/default.rules. Синтаксис правил написан на языке Starlark (безопасный диалект Python, изолированный от файловой системы).
Пример правила автоматического согласования просмотра PR:
# 运行带 `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",
],
)Параметры функции prefix_rule:
| Параметр | Назначение | Описание |
|---|---|---|
pattern (обязательно) | Шаблон префикса команды в виде массива аргументов | Может содержать точные строки или логическое «или» в виде вложенного массива |
decision (по умолчанию allow) | Действие при совпадении | Значения: allow (пропустить), prompt (запросить), forbidden (заблокировать). Приоритет у строгого правила |
justification (опционально) | Текстовое обоснование правила | Выводится пользователю в диалоге согласования |
match / not_match (опционально) | Примеры для встроенных тестов | Используются для внутренней проверки корректности регулярного выражения при загрузке |
Приоритеты режимов decision определены системой по принципу «строгий переопределяет мягкий» (forbidden > prompt > allow):
| decision | Системное поведение |
|---|---|
allow | Запуск вне песочницы без запроса подтверждения |
prompt | Вывод запроса подтверждения при каждом вызове |
forbidden | Блокировка команды без вывода запросов |
После изменения .rules файлов перезапустите сессию Codex для применения настроек. При ручном одобрении часто вызываемых утилит в CLI Codex может автоматически дописывать правила пропуска в файл ~/.codex/rules/default.rules.
Анализ составных команд
Важный аспект безопасности: если Codex пытается запустить объединенную цепочку команд (например, git add . && rm -rf /), парсер tree-sitter разбивает строку на отдельные вызовы и оценивает каждый из них независимо:
git add .
rm -rf /Блокировка forbidden для команды rm -rf остановит запуск всей цепочки, даже если вызов git add был разрешен флагом allow. Это предотвращает попытки скрыть опасную команду внутри безопасных вызовов.
Однако автоматический разбор работает только для простых линейных цепочек. При использовании сложных скриптов с перенаправлениями потоков (>), переменными среды (FOO=bar) или подстановочными знаками (*) Codex оценивает всю строку целиком как один вызов bash -lc. Учитывайте это при составлении правил.
Предварительная проверка через execpolicy check
Перед перезапуском сессии проверьте корректность написанных правил с помощью команды codex execpolicy check:
codex execpolicy check --pretty \
--rules ~/.codex/rules/default.rules \
-- gh pr view 7888 --json title,body,commentsУтилита выведет структуру JSON с информацией о том, какие именно правила сработали для данной команды и какое итоговое решение применит система. Это страхует от синтаксических ошибок и ложных блокировок (например, случайной блокировки команды git log).
💡 Резюме одной фразой: правила в файлах
.rulesиспользуют функциюprefix_ruleдля контроля вызовов по префиксу аргументов (allow/prompt/forbiddenс приоритетом более строгого значения). Сложные цепочки команд безопасно разбиваются парсером. Проверка конфигурации выполняется черезcodex execpolicy checkперед перезапуском.
03 Хуки (Hooks): доступные события жизненного цикла
Хуки привязываются к определенным точкам выполнения задач в Codex, называемым системными событиями (events). Для эффективного использования хуков разберитесь с картой событий.
Напомним структуру цикла работы агента (глава 02): «планирование → действие → анализ результатов». События хуков привязаны к этим шагам:

Схема показывает последовательность вызовов: старт сессии вызывает SessionStart, отправка запроса разработчиком — UserPromptSubmit, а при вызове инструментов запускается цикл предобработки PreToolUse и постобработки PostToolUse. По окончании шага логики срабатывает триггер Stop.
Спецификация Codex содержит множество событий, но для большинства задач автоматизации достаточно освоить следующие четыре:
| Событие | Время вызова | Типовой сценарий |
|---|---|---|
PreToolUse | До запуска инструмента | Блокировка небезопасных вызовов, модификация аргументов (позволяет прервать операцию) |
PostToolUse | После возврата результатов | Автоматический запуск форматирования или линтера файлов |
Stop | По завершении шага логики | Запрос повторного анализа (например, повторный прогон тестов после правок) |
SessionStart | При старте или восстановлении сессии | Передача в контекст модели статуса репозитория (например, истории коммитов) |
Хук PermissionRequest срабатывает перед выводом диалога согласования прав доступа и позволяет автоматизировать ответы на запросы.
Префиксы событий указывают на логику их работы: события группы Pre выполняются до действия и могут заблокировать его; события группы Post срабатывают после действия и используются для анализа логов или корректировки результатов на диске.
Наглядно точки вызова показаны на схеме:

События жизненного цикла сессии выстроены по оси времени: старт сессии → вызов инструмента → выполнение → завершение. К каждой точке привязывается соответствующий хук-скрипт, запускаемый операционной системой автоматически.
Важная особенность Codex: возврат флага decision: "block" в событиях Stop или PostToolUse не блокирует выполнение (так как инструмент уже завершил работу). Этот флаг указывает Codex продолжить анализ результатов и запустить еще один цикл рассуждений, передавая текст из поля reason в качестве нового промпта. В отличие от других клиентов, block в пост-событиях Codex означает возврат шага логики, а не запрет.
💡 Резюме одной фразой: хуки привязываются к событиям жизненного цикла Codex. Ключевые точки:
PreToolUse(до вызова, позволяет заблокировать),PostToolUse(после выполнения),Stop(по окончании шага, позволяет продолжить) иSessionStart(на старте). Флагblockв событияхStopиPostToolUseсигнализирует о возврате шага, а не о блокировке.
04 Размещение хуков и фильтрация вызовов через matcher
Рассмотрим правила описания конфигураций хуков и пути их сохранения.
Расположение файлов конфигурации
Хуки могут описываться во внешних файлах hooks.json или непосредственно в основном конфигурационном файле config.toml (секция [hooks]).
Где хранить настройки:
| Файл конфигурации | Область действия | Возможность публикации в Git |
|---|---|---|
~/.codex/hooks.json | Все сессии на вашем ПК | Нет, локальный файл |
~/.codex/config.toml | Все сессии на вашем ПК | Нет, локальный файл |
<repo>/.codex/hooks.json | Только текущий проект | ✅ Да, фиксируется в Git репозитория |
<repo>/.codex/config.toml | Только текущий проект | ✅ Да, фиксируется в Git репозитория |
Локальные хуки репозитория сохраняются в подкаталог .codex/ и попадают в Git для синхронизации работы команды. Глобальные личные хуки хранятся в домашнем каталоге.
Особенности слияния:
- Хуки со всех уровней конфигураций объединяются при загрузке и запускаются последовательно;
- Не используйте одновременно описание хуков в
hooks.jsonиconfig.tomlна одном уровне настроек, чтобы не вызывать предупреждений системы; - Локальные хуки проекта игнорируются, если проекту не выражено доверие.
Пример конфигурации хука
Рассмотрим пример описания хука в файле .codex/hooks.json для вызова скрипта после работы консоли Bash:
{
"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"
}
]
}
]
}
}Разберем структуру по уровням:
"PostToolUse"— точка вызова (событие постобработки инструмента);"matcher": "Bash"— фильтр вызовов (хук сработает только при использовании консолиBash);- Вложенный массив
hooksсодержит логику: тип запускаcommand, строку вызова скрипта и лимит времени.
Важные системные требования к параметрам:
- Параметр
timeoutзадается в секундах (по умолчанию 600 секунд при отсутствии ключа); - На текущем этапе поддерживается только синхронный запуск команд (
type: "command"), ключиprompt,agentи асинхронные вызовыasyncигнорируются; - Хуки на одном событии запускаются параллельно, выполнение одного скрипта не блокирует старт другого;
- Рабочий каталог скрипта привязан к текущей папке сессии (
cwd). Всегда вычисляйте абсолютный путь к файлам через утилиту Git (например,$(git rev-parse --show-toplevel)), иначе скрипт не запустится при вызовах из подпапок; - Для кроссплатформенной работы в Windows пропишите альтернативную строку вызова в ключе
command_windows(илиcommandWindowsдля TOML).
Отличия от Claude Code: в Codex лимиты
timeoutзадаются в секундах (а не миллисекундах), переменная$CLAUDE_PROJECT_DIRне поддерживается (используйте вызов корня Git), глобальный флаг отключения всех хуков отсутствует (для отключения используйте секцию[features] hooks = falseвconfig.toml).
Аналогичная запись в формате TOML внутри config.toml:
[[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 для фильтрация вызовов
Параметр matcher содержит регулярное выражение (regex) для фильтрации вызовов по имени используемого инструмента. Это защищает систему от лишних фоновых запусков.
Регулярные выражения matcher:
| Регулярное выражение matcher | Назначение | Пример совпадения |
|---|---|---|
"Bash" | Точное совпадение с утилитой Bash | Вызывается только при запусках консоли |
"^apply_patch$" | Точное регулярное выражение | Вызывается строго при изменении файлов |
"Edit|Write" | Алиасы записи (логическое «или» в регулярном выражении) | Вызывается после записи или редактирования файлов |
"mcp__filesystem__.*" | Шаблон для группы инструментов MCP | Охватывает любые вызовы сервера файловой системы MCP |
* / "" / (опущено) | Совпадение со всеми инструментами | Вызывается при любой операции на данном шаге |
Важные нюансы:
- Системный инструмент записи файлов в Codex называется
apply_patch. Вы можете использовать алиасыEditилиWriteв фильтрах matcher для удобства, но в потоке данных stdin имя инструмента всегда будет передаваться какapply_patch; - События
UserPromptSubmitиStopигнорируют фильтрmatcher, поскольку они привязаны к шагам диалога, а не к вызовам утилит; - Учитывайте ограничения: хук
PreToolUseперехватывает вызовы простых shell-команд,apply_patchи инструментов MCP. Сложные вложенные скриптыunified_execили вызовы интернет-поиска не фильтруются. Не рассматривайте хуки как единственный рубеж защиты.
💡 Резюме одной фразой: параметры хуков сохраняются в файлы
hooks.jsonилиconfig.toml(глобально или локально) и содержат три уровня описания: событие, фильтр matcher и выполняемый скрипт. Помните:timeoutзадается в секундах (по умолчанию 600), регулярные выражения используются в matcher, а инструмент изменения файлов называетсяapply_patch.
05 Механизм доверия: почему новый хук не запускается по умолчанию
Специфика Codex накладывает жесткие рамки на безопасность выполнения фоновых скриптов: после добавления или изменения хука он не запустится до тех пор, пока вы явно не выразите ему доверие.
Хуки запускаются с правами вашей учетной записи операционной системы и могут нанести вред при клонировании ненадежных репозиториев со скрытыми скриптами автоматизации. В целях защиты в Codex встроен механизм верификации:
- Система отслеживает контрольные суммы (хэш) файлов конфигураций хуков. Любые новые или измененные блоки помечаются как «требующие проверки» и автоматически пропускаются;
- Для подтверждения хуков используется консольная команда
/hooks; - При обнаружении несогласованных хуков Codex выведет предупреждение при запуске сессии.
После написания или изменения конфигурации хука запустите сессию и введите команду:
/hooksОткроется меню верификации хуков. Найдите ваш новый хук, изучите строку запуска команды и выберите статус «Доверять». После этого хук начнет выполняться. Системные и административные хуки помечаются как «управляемые» (managed), выразить им недоверие или отключить в этом интерфейсе нельзя.
Для запуска задач в системах CI (где ручное подтверждение невозможно) используйте параметр запуска --dangerously-bypass-hook-trust для отключения верификации. Не используйте этот флаг на рабочей машине.
💡 Резюме одной фразой: в Codex реализован механизм доверия к хукам — новые и измененные скрипты не запускаются автоматически до подтверждения в меню
/hooks(проверка идет по хэшу файла). Это ключевое отличие от аналогов и основная причина сбоев запуска хуков.
06 Взаимодействие хука с Codex: потоки ввода-вывода и коды возврата
Разберем логику обмена данными между Codex и запущенным фоновым скриптом. Данные передаются по трем стандартным каналам: передача JSON в stdin → выполнение логики → возврат кода ошибки и вывод JSON в stdout.
Входные данные: получение JSON через stdin
При срабатывании триггера Codex передает параметры события на вход скрипта в формате JSON:
| Поле | Назначение |
|---|---|
session_id | Уникальный идентификатор текущей сессии |
cwd | Текущий рабочий каталог сессии |
hook_event_name | Имя вызвавшего событие шага жизненного цикла |
transcript_path | Путь к файлу транскрипта сессии (может отсутствовать) |
model | Имя используемой в сессии модели |
permission_mode | Текущий режим прав доступа песочницы |
Для событий инструментов в JSON добавляются поля tool_name (например, Bash, apply_patch) и структура параметров tool_input (например, tool_input.command для консоли). Пример данных на входе скрипта PreToolUse при вызове удаления файлов:
{
"session_id": "abc123",
"cwd": "/Users/sarah/myproject",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf /tmp/x"
}
}Скрипт может распарсить JSON, извлечь строку команды и принять решение о блокировке.
Выходные данные: возврат кодов завершения
Скрипт сообщает о результатах работы с помощью кода возврата процесса (exit code):
| Код возврата | Назначение | Системный результат |
|---|---|---|
0 | Успешно | Операция продолжается в штатном режиме |
2 | Системный сигнал | Блокировка или продолжение (зависит от события) |
Логика обработки кода exit 2:
- В событиях до выполнения (
PreToolUse,UserPromptSubmit): останавливает запуск команды. Текст ошибки из потокаstderrвыводится в чат Codex; - В событиях после выполнения (
PostToolUse,Stop): запуск отменить нельзя. Текст ошибки изstderrпередается модели в качестве обратной связи для корректировки действий (возврат шага).
Тонкое управление через возврат JSON в stdout
Для более гибкой логики (например, блокировки с обоснованием или внедрения контекста) верните код exit 0 и выведите JSON-структуру в поток stdout.
1. Блокировка вызова в PreToolUse с выводом причины:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "这条命令会动生产库,已拦截"
}
}Система также поддерживает устаревший формат вывода {"decision": "block", "reason": "..."}.
2. Передача контекста в сессию при SessionStart:
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "编辑前先读一遍本仓库的代码规范。"
}
}Ограничения вывода:
- Скрипт
PreToolUseигнорирует простой текстовый вывод вstdout(для блокировки используйте формат JSON или код возвратаexit 2); - События
SessionStartиUserPromptSubmitпринимают обычный текст изstdoutкак контекст; - Параметры
continueиstopReasonне поддерживаются в обработчикеPreToolUse, их возврат вызовет системную ошибку с продолжением выполнения команды.
💡 Резюме одной фразой: обмен данными идет по трем каналам: получение JSON через stdin, возврат кодов ошибок для управления и передача JSON в stdout для настройки параметров. Код
exit 2в событияхPreблокирует действие, а вPost/Stop— возвращает шаг. СкриптPreToolUseигнорирует текстовый вывод в stdout.
07 Готовые примеры хуков
Рассмотрим два практических примера автоматизации рабочих процессов.
Пример 1: Автоматическое форматирование кода (PostToolUse)
Позволяет автоматически форматировать измененные файлы. Рекомендуется к установке в рабочих проектах.
Шаг 1. Создаем скрипт обработки по пути .codex/hooks/format.py:
#!/usr/bin/env python3
import json, subprocess, sys
data = json.load(sys.stdin)
# Запуск утилиты форматирования в текущей папке
subprocess.run(["ruff", "format", "."])Шаг 2. Регистрируем хук в файле .codex/hooks.json репозитория:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/format.py\"",
"timeout": 30,
"statusMessage": "格式化改动文件"
}
]
}
]
}
}Шаг 3. Подтверждаем доверие к хуку через команду /hooks в чате. После этого при любых изменениях файлов Codex будет автоматически вызывать форматирование.
Пример 2: Блокировка вызовов опасных команд (PreToolUse)
Использует код завершения exit 2 для отмены выполнения небезопасных команд Bash.
Шаг 1. Создаем скрипт фильтрации по пути .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) # Вывод ошибки в чат
sys.exit(2) # Отмена выполнения
sys.exit(0) # Разрешение вызоваШаг 2. Регистрируем хук в .codex/hooks.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 \"$(git rev-parse --show-toplevel)/.codex/hooks/block-dangerous.py\"",
"statusMessage": "检查 Bash 命令"
}
]
}
]
}
}Шаг 3. Подтверждаем доверие к хуку в меню /hooks. Любые попытки вызвать rm -rf в Bash будут прерваны с выводом сообщения в чат.
Сравнение инструментов: простые запреты команд эффективнее описывать в правилах Rules (раздел 02), поскольку они не требуют написания скриптов. Используйте хуки только при необходимости сложного анализа параметров.
| Параметр | Пример 1 (форматирование) | Пример 2 (блокировка) |
|---|---|---|
| Событие | PostToolUse (после операции) | PreToolUse (до операции) |
| matcher | Edit|Write (алиас apply_patch) | Bash |
| Логика | Форматирование по завершении правок | Прерывание запуска по коду exit 2 |
| Риски | Отсутствуют, безопасно для работы | Ошибки фильтрации могут заблокировать работу |
| Альтернатива в Rules | Нет (Rules не форматирует файлы) | ✅ Да, простые запреты лучше настраивать через Rules |
💡 Резюме одной фразой: мы разобрали два сценария: форматирование (
PostToolUse, безопасно и практично) и блокировка (PreToolUseсо скриптом и кодомexit 2). Прописывайте абсолютные пути через git-корень. Активация хука требует подтверждения доверия в меню/hooks.
08 Практика: создание и тестирование хука логирования за 5 минут
Создадим безопасный хук, сохраняющий историю всех выполненных Codex команд в текстовый лог-файл на диске.
Шаг 1. Создаем скрипт логирования по пути .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")И конфигурационный файл .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 命令"
}
]
}
]
}
}Папка должна находиться под управлением Git (выполните
git init), чтобы утилита смогла корректно вычислить корень репозитория.
Шаг 2. Активация хука
Запустите сессию и введите команду:
codex
/hooksОжидаемый результат: в открывшемся списке хуков появится запись PostToolUse в статусе «待审» (требует проверки). Подтвердите доверие к хуку.
Шаг 3. Вызов события
Отправьте Codex запрос на просмотр содержимого текущей папки:
帮我用 ls 看一下当前目录有哪些文件Codex вызовет инструмент Bash для выполнения команды ls.
Шаг 4. Проверка лог-файла
В отдельной консоли откройте лог-файл:
cat ~/codex-bash-log.txtОжидаемый результат: в файле запишется строка с командой ls. Логирование работает корректно.
Для удаления хука просто сотрите его секцию из файла .codex/hooks.json.
💡 Резюме одной фразой: выполните на практике последовательность «создание конфигурации логирования в Git-папке → подтверждение доверия в
/hooks→ вызов команды Bash в чате → проверка логов на диске».
09 Отладка: почему хук не запускается или завершается с ошибкой
При сбоях в работе хуков сверяйтесь со списком частых проблем:
| Проблема | Причина / Способ проверки |
|---|---|
| Хук не запускается | 1. Не выражено доверие в меню /hooks (главная системная причина). 2. Изменился хэш файла после правок (требуется повторное согласование). 3. Ошибка в имени события или matcher. |
Хук отсутствует в меню /hooks | 1. Ошибка синтаксиса JSON (комментарии и висящие запятые запрещены). 2. Ошибка в пути к файлу или имени (hooks.json). 3. Одновременное использование hooks.json и toml на одном уровне. 4. Требуется перезапуск сессии. |
Ошибка command not found или файл не найден | Некорректный путь. Рабочая папка привязана к cwd сессии. Используйте абсолютный путь через корень Git. |
| Блокировка не сработала | 1. Хук привязан к событию PostToolUse вместо PreToolUse. 2. Инструмент консоли не поддерживается PreToolUse. 3. Отсутствует код возврата exit 2 или параметр permissionDecision: "deny". |
| Завершение хука по таймауту | Параметр timeout задается в секундах (по умолчанию 600). Увеличьте значение для тяжелых скриптов. |
Методы отладки:
- Локальное тестирование скрипта. Подайте тестовые данные на вход скрипта напрямую в консоли и проверьте код завершения:
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /tmp/x"}}' | python3 .codex/hooks/block-dangerous.py
echo $? # Должен вернуть код 2 при блокировке- Проверка правил через
execpolicy check(для отладки блокировок Rules, раздел 02).
Для временного отключения всех хуков пропишите в config.toml параметр [features] hooks = false.
💡 Резюме одной фразой: при сбоях в работе хуков в первую очередь проверьте статус согласования в
/hooks. Тестируйте скрипты локально через передачу JSON в консоли.
10 Итоги
Мы разобрали архитектуру правил и хуков в Codex, события жизненного цикла сессий и логику взаимодействия скриптов с системой.
Повторим ключевые выводы:
| Задача | Инструмент | Ключевой нюанс |
|---|---|---|
| Управление доступом к командам | Правила prefix_rule | Режимы allow/prompt/forbidden с приоритетом строгого. Проверка через execpolicy check |
| Выбор события запуска | События жизненного цикла | PreToolUse для блокировок, PostToolUse для правок, Stop для продолжения сессии |
| Создание хука | Файлы hooks.json или config.toml | Три уровня: событие, matcher (регулярное выражение), скрипт. Время задается в секундах |
| Активация | Подтверждение в меню /hooks | Фоновые хуки заблокированы по умолчанию и требуют согласования по хэшу файла |
| Обмен данными | Потоки ввода-вывода и коды ошибок | Получение JSON, управление по кодам возврата (код exit 2 возвращает шаг в Post) |
| Отладка хуков | Пошаговый аудит | Проверьте статус согласования в /hooks, регулярное выражение matcher и пути файлов |
Теперь вы умеете: отличать задачи правил от хуков, настраивать ограничения вызовов Rules и проверять их через execpolicy check, выбирать события жизненного цикла для привязки триггеров хуков, описывать конфигурации hooks.json с использованием matcher, подтверждать доверие к хукам в /hooks и анализировать потоки ввода-вывода скриптов. Хуки переводят контроль за качеством кода и безопасностью операций в автоматический системный режим.
Помните о специфике Codex: все хуки требуют ручной авторизации в меню /hooks, лимиты времени задаются в секундах, а блокировка в PostToolUse возвращает шаг логики.
В следующей статье — [25 · Изоляция рабочих копий Worktrees]. Мы научились настраивать окружение и автоматизировать проверку сессий для одного Codex. В следующей главе мы разберем логику параллельной работы: как запустить несколько сессий Codex в независимых рабочих копиях Git (Worktrees), исключая взаимные конфликты версий кода.