title: Архитектура description: “Как работают обработчик хука, загрузка конфигурации и оценка политик” icon: sitemap
Этот документ объясняет, как failproofai работает внутри: как система хуков перехватывает вызовы инструментов агента, как загружается и объединяется конфигурация, как оцениваются политики и как панель мониторинга отслеживает активность агента.Обзор
failproofai состоит из двух независимых подсистем:- Обработчик хука — быстрый CLI подпроцесс, который Claude Code вызывает при каждом вызове инструмента агента. Оценивает политики и возвращает решение.
- Agent Monitor (Dashboard) — веб-приложение Next.js для мониторинга сеансов агента и управления политиками.
~/.failproofai/ и директории .failproofai/ проекта, но запускаются как отдельные процессы и взаимодействуют только через файловую систему.
Обработчик хука
Интеграция с Claude Code
Когда вы запускаетеfailproofai policies --install, она записывает записи вроде этой в ~/.claude/settings.json:
failproofai --hook PreToolUse как подпроцесс перед каждым вызовом инструмента, передавая JSON-полезную нагрузку на stdin.
Формат полезной нагрузки
PostToolUse полезная нагрузка также содержит tool_result с выводом инструмента.
Обработчик устанавливает лимит stdin в 1 МБ. Полезные нагрузки, превышающие это значение, отбрасываются и все политики неявно разрешают.
Формат ответа
Deny (PreToolUse):- Код выхода:
2 - Причина записана в stderr (не stdout)
- Код выхода:
0 - Пустой stdout
allow(message) позволяет политике отправить информационный контекст обратно Claude, даже когда операция разрешена. Обработчик хука записывает следующий JSON в stdout (не в файл конфигурации — это ответ обработчика Claude Code, как и ответы deny и instruct выше):
- Код выхода:
0(операция разрешена) - Когда несколько политик возвращают
allowс сообщением, их сообщения объединяются с переводами строк в одну строкуadditionalContext - Если ни одна политика не предоставляет сообщение, stdout пустой (как раньше)
Конвейер обработки
src/hooks/handler.ts реализует полный конвейер:
Загрузка конфигурации
src/hooks/hooks-config.ts реализует загрузку конфигурации с тремя областями.
enabledPolicies— дедуплицированное объединение всех трех файловpolicyParams— по ключу политики, первый файл, который его определяет, побеждает полностьюcustomPoliciesPath— первый файл, который его определяет, побеждаетllm— первый файл, который его определяет, побеждает
readHooksConfig() (только глобальная) для чтения и записи, так как она не вызывается с cwd проекта.
Оценка политик
src/hooks/policy-evaluator.ts запускает политики по порядку.
Для каждой политики:
- Ищет схему
paramsполитики (если она есть). - Читает
policyParams[policy.name]из объединенной конфигурации. - Объединяет предоставленные пользователем значения над значениями по умолчанию схемы для создания
ctx.params. - Вызывает
policy.fn(ctx)с разрешенным контекстом. - Если результат
deny, останавливается немедленно и возвращает это решение. - Если результат
instruct, накапливает сообщение и продолжает. - Если результат
allow, продолжает к следующей политике.
- Если был возвращен какой-либо
deny, выдает ответ deny. - Если были собраны возвращаемые
instruct, выдает один ответ instruct со всеми сообщениями объединены. - В противном случае выдает ответ allow (пустой stdout, выход 0).
Встроенные политики
src/hooks/builtin-policies.ts определяет все 39 встроенных политик как объекты BuiltinPolicyDefinition:
params, объявляют PolicyParamsSchema с типами и значениями по умолчанию для каждого параметра. Оценщик политик внедряет разрешенные значения в ctx.params перед вызовом fn. Функции политик читают ctx.params без защиты от нулевых значений, потому что значения по умолчанию всегда применяются сначала.
Сопоставление паттернов внутри политик использует проанализированные токены команды (argv), а не сопоставление по сырой строке. Это предотвращает обход с помощью инъекции оператора оболочки (например, паттерн для sudo systemctl status * не может быть обойден добавлением ; rm -rf / к команде).
Пользовательские политики
src/hooks/custom-hooks-registry.ts реализует реестр, основанный на globalThis:
src/hooks/custom-hooks-loader.ts загружает файл политики пользователя:
- Читает
customPoliciesPathиз конфигурации; пропускает, если отсутствует. - Разрешает абсолютный путь; проверяет, существует ли файл.
- Переписывает все импорты
from "failproofai"на фактический путь dist, чтобыcustomPoliciesразрешился на один и тот же реестрglobalThis. - Рекурсивно переписывает переходящие локальные импорты для обеспечения совместимости ESM.
- Записывает временные файлы
.mjsиimport()файл записи. - Вызывает
getCustomHooks()для получения зарегистрированных хуков. - Очищает все временные файлы в блоке
finally.
~/.failproofai/hook.log и загрузчик возвращает пустой массив. Встроенные политики не затрагиваются.
Пользовательские политики оцениваются после всех встроенных политик. deny пользовательской политики все еще вызывает короткое замыкание для дальнейших пользовательских политик (но все встроенные уже выполнены к этому моменту).
Логирование активности
После каждого события хука обработчик добавляет строку JSONL в~/.failproofai/hook-activity.jsonl:
Архитектура панели
Панель является приложением Next.js 16 с использованием App Router с React Server Components и Server Actions.- Компоненты страниц вызывают
lib/projects.tsиlib/log-entries.tsдля чтения данных проекта/сеанса непосредственно из файловой системы (нет уровня API для чтения). - Страница Policies использует Server Actions для всех изменений (переключение, обновление параметров, установка/удаление).
- Просмотрщик сеанса парсит формат стенограммы JSONL Claude и отображает хронологию сообщений и вызовов инструментов.
- Нет базы данных — все постоянное состояние находится в обычных файлах (
~/.failproofai/,~/.claude/projects/). - Server Actions для изменений — REST API не требуется для операций CRUD.
- React Server Components для страниц чтения — более быстрая начальная загрузка, нет клиентского пакета для выборки данных.
- Клиентские компоненты только там, где требуется интерактивность (переключатели политик, поиск активности, просмотр журнала).

