Claude Code читает CLAUDE.md в начале каждой сессии, но запрет из этого файла агент всё равно может нарушить. В issue #46779 описаны случаи, когда агент раз за разом удалял данные сверх запроса, хотя запреты в файле были написаны прямо.
Практический вывод, с которого стоит начать: CLAUDE.md задаёт намерение, а не политику доступа. Между «агенту сказано не удалять файлы» и «агент не может удалить файлы» лежит слой разрешений и проверок, которого в текстовом файле нет. Как устроен сам инструмент и где у него границы, разобрано в материале Claude Code в 2026 году.
Почему CLAUDE.md не гарантирует безопасность Claude Code
Claude Code загружает CLAUDE.md в начале каждой сессии. По руководству Anthropic, после сжатия диалога он перечитывает файл, поэтому текст правил из контекста не пропадает. Деталь важная: проблема не в забывании инструкции. Инструкция остаётся текстом в контексте и не превращается в механизм, который не даёт выполнить опасный вызов.
Компакция контекста происходит в длинных сессиях, когда окно заполняется выводом команд и правками файлов. Файл правил подгружается заново, но это восстанавливает доступ к тексту, а не принуждение к его исполнению.
Что CLAUDE.md делает и чего не делает
| Делает | Не делает |
|---|---|
| Попадает в контекст на старте сессии | Не блокирует вызовы инструментов |
| Перечитывается после сжатия диалога | Не проверяет команды на соответствие запрету |
| Задаёт конвенции проекта: стиль, структуру, формат коммитов | Не работает как политика доступа к файлам и сети |
| Фиксирует уже случившиеся сбои и выводы из них | Не гарантирует соблюдение правила на длинной сессии |
Записи в CLAUDE.md идут через тот же канал, что и остальная переписка: модель их видит и может проигнорировать. Правило в settings.json или в хуке срабатывает до того, как действие случится, и не зависит от того, как модель поняла задачу.
Кейс issue #46779: запрет написан, а данные удалены
В issue #46779 автор сообщает, что Claude Code раз за разом удалял данные сверх запроса, хотя запреты в CLAUDE.md были написаны прямо. Подробностей о версии, окружении и точных командах в описании нет, зато показателен сам шаблон сбоя: агент формально знал ограничение и всё равно вышел за рамки задачи. Разбор на Habr приводит этот случай как основной аргумент против текстовых запретов.
Если ошибка необратима, текстового запрета недостаточно. Удалённые файлы не вернёт ни одна формулировка в промпте и ни одно перечитывание файла правил на старте сессии.
Как делить правила по цене нарушения: текст, разрешения, хуки, проверка кодом
Критерий один: сколько стоит откатить ошибку. Если минуты разговора и правки, хватит строки в CLAUDE.md. Если ошибка стоит денег, раскрывает ключи или запускает работу без подтверждения, нужны разрешения, хук или проверка кодом.
| Цена нарушения | Пример | Чем закрывать |
|---|---|---|
| Минуты | Стиль кода, формат коммита, структура папок | Строка в CLAUDE.md |
| Деньги | Автоповтор задачи после лимита подписки, лишние платные вызовы | ask в settings.json плюс проверка перед запуском |
| Ключи | Чтение .env, коммит с токеном | deny на чтение и вывод плюс хук |
| Необратимые данные | Рекурсивное удаление, миграции, drop table | deny плюс подтверждение |
| Работа без подтверждения | Публикация пакета, деплой, push в защищённую ветку | ask |
Правила за минуты: что действительно можно оставить в CLAUDE.md
Стиль кода, формат коммитов, структура файлов, конвенции именования, напоминания про принятые в проекте библиотеки. Такие ошибки дешево правятся, а жёсткий механизм под каждую мелочь превращает конфигурацию в отдельный проект, который нужно поддерживать.
Текст выигрывает гибкостью: модель понимает формулировку, а не список шаблонов, поэтому «не добавляй зависимости без обсуждения» работает шире любого правила в permissions. Ограничение в том же: гибкость означает, что соблюдение зависит от модели.
Правила за деньги, ключи и необратимые действия
- Удаление данных сверх запроса. deny на рекурсивное удаление и отдельное подтверждение на операции с базой.
- Раскрытие ключей. deny на чтение .env и приватных ключей, хук перед коммитом и push, который ищет секреты в индексе.
- Запуск работы без подтверждения. ask на деплой, публикацию пакета и push в защищённую ветку.
- Автоматический повтор после лимита подписки. проверка кодом перед стартом задачи: если бюджет исчерпан, запуск не происходит.
Если ошибка дорого обойдётся, подробнее согласуйте ограничения и критерии приёмки до старта: точная постановка задачи экономит больше, чем ещё один абзац запретов. В Agentic Design Patterns это описано как спецификация наперёд.
Разрешения allow/ask/deny в settings.json: как закрепить запрет кодом
В settings.json Claude Code задаются разрешения на инструменты и команды. Работают три режима: allow выполняет действие без вопросов, ask останавливается и ждёт подтверждения, deny отказывает. Для безопасности важнее всего deny: он срабатывает на уровне механизма и не зависит от того, что модель решила про вашу инструкцию.
Иллюстративный пример settings.json с allow/ask/deny
Пример ниже показывает структуру, а не готовый конфиг. Точный формат шаблонов и полный набор поддерживаемых полей сверяйте с актуальной документацией Claude Code: между версиями синтаксис меняется.
{
"permissions": {
"deny": [
"Bash(rm -rf:*)",
"Bash(git push --force:*)",
"Read(.env)",
"Read(**/*.pem)"
],
"ask": [
"Bash(git push:*)",
"Bash(npm publish:*)",
"Bash(docker run:*)",
"WebFetch"
],
"allow": [
"Bash(git status)",
"Bash(git diff:*)",
"Read(src/**)"
]
}
}
Логика конфигурации простая. Список deny закрывает то, что нельзя откатить или нельзя показывать: рекурсивное удаление, force-push, чтение файлов с секретами. Список ask тормозит операции с побочными эффектами. Список allow снимает лишние подтверждения с рутины вроде git status, иначе человек устанет жать Enter.
Как выбрать между allow, ask и deny
deny оставляйте для необратимого и дорогого: удаление, чтение секретов, force-push. ask для действий, которые меняют внешнее состояние: публикация, деплой, сетевые вызовы. allow для частой безопасной рутины.
Риск перебора с ask конкретный: если подтверждение приходит каждые две минуты, человек начинает подтверждать не глядя, и защита превращается в формальность. Держите список ask коротким. Второе ограничение: конфигурацию нужно ревьюить вместе с кодом, иначе она устаревает и начинает пропускать то, что раньше закрывала.
Хуки на события сессии: контроль на примере Stop
Хуки запускают ваш код в заданной точке работы агента. Событие Stop срабатывает, когда Claude Code собирается завершить сессию. Удобная точка для финальной проверки: остались ли незакоммиченные секреты, проходят ли тесты, не брошена ли задача на середине.
Чем хук отличается от разрешения
Permissions решают, можно ли выполнить конкретное действие. Хуки реагируют на события сессии и встраивают проверку в процесс. Вместе они закрывают разные дыры: deny не даёт агенту прочитать .env, а хук на Stop ловит ключ, который попал в индекс другим путём, например через сгенерированный конфиг.
#!/usr/bin/env bash
# иллюстративный скрипт хука на событие Stop
set -euo pipefail
# 1. секреты в индексе
if git diff --cached | grep -Eiq '(api[_-]?key|secret|token)[[:space:]]*[:=][[:space:]]*[A-Za-z0-9_-]{16,}'; then
echo "Похоже на секрет в индексе: уберите ключ перед завершением сессии" >&2
exit 2
fi
# 2. тесты
if ! pytest -q >/dev/null 2>&1; then
echo "Тесты падают: сначала почините, потом завершайте сессию" >&2
exit 2
fi
Точный формат данных, которые Claude Code передаёт хуку, и семантику кодов выхода сверяйте с документацией: от версии зависит, увидит агент текст из stderr и заблокируется ли остановка. Готовые реализации трёх хуков с разбором подводных камней и найденного бага есть в материале Принудительные хуки для Claude Code.
Границы честно: хук зависит от того, что именно вы проверяете. Он ловит известные вам сценарии и не заменяет ревью результата. Скрипт, который никто не обновлял полгода, пропустит новый способ утечки или новую команду сборки.
Почему правило, которое можно нарушить, со временем нарушается
Дрейф поведения - это режим отказа, при котором модель помнит ограничение, но перестаёт ему следовать. В бенчмарке StateTrack-Bench с конференции EMNLP 2026 авторы отнесли к нему 88,6% сбоев в длинных диалогах. Почти девять сбоев из десяти.
Дрейф поведения: правило в контексте, но не в действиях
Развести «забыл» и «перестал следовать» полезно, потому что лечатся они по-разному. Против забывания работает перечитывание файла и напоминания. Против дрейфа внутри контекста не работает ничего: нужен барьер снаружи, который не спрашивает модель о её намерениях. Перечитывание CLAUDE.md после сжатия диалога от дрейфа, скорее всего, не спасает: правило в контексте и так есть. Источник формулирует это как предположение, а не как измеренный результат.
Отдельно Microsoft Research показала общий спад качества у всех протестированных топовых моделей в многоходовых диалогах. Публичный разбор обрывается на этом выводе, поэтому конкретные метрики спада не привожу. Направление совпадает с данными StateTrack-Bench: длинная сессия сама по себе ухудшает соблюдение ограничений.
Что это значит для CLAUDE.md на практике
Чем длиннее сессия и чем дороже ошибка, тем меньше надежды на текст. Отсюда перенос критичных правил в permissions, хуки и проверку кодом. CLAUDE.md при этом не бесполезен: он задаёт конвенции и фиксирует выводы из сбоев. Просто это не гарантия соблюдения.
CLAUDE.md как журнал сбоев: как его вести
Полезная рамка: CLAUDE.md - журнал уже случившихся сбоев, а не декларация ценностей проекта. Запись появляется после конкретной ошибки, а не из желания описать идеальный процесс.
Когда добавлять правило и когда удалять
Справка Anthropic советует добавлять запись, когда Claude пришлось поправить в одном и том же второй раз: первый сбой обычно разовый. По той же справке файл стоит держать короче 200 строк, назначить ему владельца и проверять правки как код. Устаревшая запись вредит сильнее, чем её отсутствие: она уводит агента в неверную подсказку. Все эти рекомендации приведены в пересказе источника, а не по первоисточнику, так что сверяйте их с актуальной документацией Anthropic.
Один из способов сократить файл без потери смысла описан в разборе как выжать максимум из подписки на кодинг-агенты: там речь о чистке CLAUDE.md и AGENTS.md вместе с оркестрацией моделей.
Пример правила, продиктованного ценой нарушения
Запрет автоматически повторять задачу после исчерпания лимита подписки появился в CLAUDE.md как правило, продиктованное ценой ошибки. С включёнными usage credits, то есть дополнительным платным балансом, работа на лимите не останавливается и продолжается за счёт кредитов, поэтому автоматический повтор ещё и стоит денег. Ответ владельца: не повторять. Разбор приводит этот случай как пример правила, которое родилось из конкретного инцидента.
По логике статьи такое правило стоит дополнительно закрыть механизмом: проверка перед запуском смотрит на остаток бюджета и не даёт агенту стартовать повтор без явного подтверждения. Текст объясняет причину, код делает соблюдение независимым от того, как модель поняла просьбу.
Чек-лист: переносим правила из CLAUDE.md в код
- Выпишите все правила из CLAUDE.md отдельным списком.
- Разметьте каждое по цене нарушения: минуты, деньги, ключи, необратимость, работа без подтверждения.
- Дешёвые оставьте текстом, чтобы не тащить поддержку конфигурации ради мелочей.
- Дорогие перенесите в settings.json: deny для необратимого и секретов, ask для операций с побочными эффектами.
- Добавьте хук на событие сессии, например Stop, для проверки итога.
- Добавьте отдельную проверку кодом перед запуском работы: бюджет, подтверждение, готовность задачи.
- Назначьте владельца CLAUDE.md и ревьюйте правки как код.
- Если ошибка дорого обойдётся, подробнее согласуйте ограничения и критерии приёмки до старта.
Про последний пункт подробнее писалось выше, и он же самый недооценённый: точная постановка задачи снижает число сбоев сильнее, чем ещё один абзац запретов в файле правил.
Ограничения подхода держите в голове. Permissions и хуки настраивают люди, и они устаревают вместе с проектом. Хук не абсолютная гарантия, а дополнительный барьер. Ни один механизм не отменяет ревью через git diff перед тем, как принять результат работы агента.