Положите несколько сайтов в один репозиторий, разложите правила для ИИ (CLAUDE.md или AGENTS.md) по папкам сайтов — и ИИ будет следовать правилам нужного сайта. Так кажется естественным, но ни Claude Code, ни Codex не «всегда читают» правила во вложенных папках. Если запустить их из корня репозитория, Claude Code не загрузит эти правила, пока не обратится к файлам в этой папке, а Codex не загрузит их автоматически (ИИ может открыть их сам, но гарантии нет). В этой статье мы по официальной документации обоих инструментов сравниваем по пунктам, когда загружаются эти файлы и как проверить, загрузились ли они, а затем показываем, как обеспечить соблюдение правил автоматическими проверками, а не документами. Статья выросла из того, что мы узнали, проектируя такую схему в среде, где ИИ-агенты ведут работу с серверами и несколькими проектами.

Когда загружаются правила в папке каждого сайта? (запуск из корня репозитория)

repo/ ├─ CLAUDE.md, AGENTS.md ← правила всего репозитория └─ sites/ ├─ blog/CLAUDE.md, AGENTS.md ← правила blog ├─ shop/CLAUDE.md, AGENTS.md ← правила shop └─ shared/ ← общие компоненты

Claude Code

  • При запускеCLAUDE.md в корне
  • При обращенииЗагружает CLAUDE.md сайта blog, когда читает, записывает или редактирует файл в sites/blog/
  • Пока нетПравила папки, к которой он ещё не обращался (shop), не загружены

Codex

  • При запускеAGENTS.md в корне
  • Без гарантииAGENTS.md в sites/blog/ не загружается автоматически (Codex не ищет ниже папки, из которой его запустили)
  • Без гарантииAGENTS.md в sites/shop/ (то же самое)

Поэтому работу над сайтом запускайте из папки этого сайта, а то, что обязательно к соблюдению, не доверяйте документам. Запускайте автоматическую проверку, которая «останавливает выпуск, если изменилось что-то за пределами закреплённой папки», и задавайте зону ответственности каждого агента настройкой для каждого worktree. Документы с правилами оставьте для того, чтобы объяснять ИИ причины и порядок действий.

Источники: How Claude remembers your project от Anthropic и Custom instructions with AGENTS.md от OpenAI (оба проверены 1 ноября 2026 года).

1. Что мы узнали, разложив правила по папкам сайтов

В среде, где ИИ-агенты занимаются работой с серверами и несколькими сайтами, мы рассматривали схему, в которой несколько сайтов лежат в одном репозитории, а правила каждого сайта — в его папке (подробности, по которым можно определить места и названия, не раскрываются, техническое содержание обобщено). Цель — разделение труда: ИИ, отвечающий за blog, читает только правила blog и никогда не трогает shop.

Но, сверившись с официальной документацией обоих инструментов, мы увидели, что разложенные правила не обязательно загружаются до начала работы. Какие правила загрузятся, зависит от того, из какой папки выполнен запуск. Кроме того, в документации Claude Code CLAUDE.md описан как контекст, а не как принудительно применяемая настройка. Даже если правила загружены, ничто не гарантирует, что им будут следовать.

  1. !

    Разложить правила по папкам недостаточно, чтобы разделить ответственность

    Риск
    ИИ, запущенный из корня, меняет файлы, не прочитав правила этого сайта или ещё до того, как их прочитал
    Решение
    Запускать работу над сайтом из папки сайта и останавливать изменения вне зоны ответственности проверкой перед выпуском (раздел 4)
    Проверка
    Средствами инструментов убедиться, какие правила загружены (раздел 3), и намеренно изменить что-то вне зоны, чтобы увидеть, остановится ли выпуск

Общие причины, по которым ИИ игнорирует правила, и способы это исправить разобраны в статье «Почему ИИ игнорирует правила: проверяем CLAUDE.md, Cursor Rules и AGENTS.md». Здесь речь о том, что происходит, когда вы разносите правила по папкам. Ещё две предосторожности из той же среды — о передаче ИИ нескольких репозиториев — в разделе 5.

2. Когда загружаются правила из папок?

Загрузятся ли правила из папки каждого сайта, зависит от того, из какой папки выполнен запуск и какой инструмент используется. Ниже — что говорит официальная документация обоих инструментов, рядом.

ПунктClaude CodeCodex
Загружается при запускеВсе CLAUDE.md и CLAUDE.local.md в папке запуска и во всех папках выше неёОт корня проекта (обычно корень git) до папки запуска, по одному файлу на папку: AGENTS.override.md, а если его нет — AGENTS.md
Ниже папки запускаПри запуске не загружаются; загружаются, когда Claude читает, записывает или редактирует другой файл в этой папкеАвтоматически не загружаются (поиск останавливается на папке запуска; ИИ может открыть их сам)
Добавляются ли во время сеанса?Да (правила из папок, к которым он обращается, добавляются позже)Нет (собираются один раз в начале каждого запуска)
Ограничения по размеруОриентир — до 200 строк на файл (более длинным файлам следуют менее надёжно); у CLAUDE.md во вложенных папках всё сверх 40 000 символов на файл (при контексте 200K токенов) отрезается, и передаётся только началоНичего не добавляется, когда общий объём превышает 32 KiB (значение project_doc_max_bytes по умолчанию)
Файл правил другого инструментаЧитает AGENTS.md, если в папке запуска и выше нет CLAUDE.md, .claude/CLAUDE.md или CLAUDE.local.md (по умолчанию)Не читает CLAUDE.md (читаются только имена, добавленные в project_doc_fallback_filenames)

Источники: How Claude remembers your project и Monorepos and large repos от Anthropic, Custom instructions with AGENTS.md от OpenAI (проверено 1 ноября 2026 года). Ограничение Claude Code для вложенных папок действует начиная с v2.1.309. При контексте 1M токенов это 150 000 символов (200 000 для Opus 4.6 и Sonnet 4.6). Claude Code читает AGENTS.md напрямую начиная с v2.1.277; AGENTS.md во вложенной папке читается, если в этой папке нет CLAUDE.md и Claude открывает там файл инструментом Read. Чтобы читались оба, задайте в /config параметру Project instructions значение claude-md-and-agents-md.

От папки запуска зависит, какие правила загрузятся

Даже в одном и том же репозитории результат зависит от места запуска. Если запустить из папки сайта, оба инструмента с самого начала читают правила этого сайта.

Откуда запускClaude CodeCodex
Корень репозиторияТолько правила корня; правила каждого сайта добавляются, когда Claude обращается к файлам этого сайтаТолько правила корня; правила сайтов автоматически не загружаются
sites/blog/При запуске читает правила blog и корня (правка файлов вне папки запуска запрашивает подтверждение)Читает корень, затем blog; правил shop нет на этом пути, поэтому автоматически они не загружаются

Легко упустить, что считается «обращением» в «загружается при обращении». В документации Claude Code чтением считаются чтение, запись или редактирование файла его инструментами, а также команды, выводящие один файл, например cat или head. Операции, которые меняют файлы иначе, например массовый поиск с заменой по папкам нескольких сайтов, в этот список не входят. Файлы сайта могут измениться раньше, чем будут прочитаны его правила.

Если в Codex запустить работу из корня репозитория и попросить «исправить и blog, и shop», AGENTS.md ни одного из сайтов автоматически не загрузится. В документации сказано, что Codex прекращает поиск, дойдя до текущей рабочей папки, поэтому правила вложенной папки надёжно попадают в контекст при запуске, только если запускать из этой папки или ниже.

При этом инструкции по умолчанию (base_instructions/default.md) в репозитории Codex по сути велят модели проверять применимые файлы AGENTS.md при работе ниже или вне текущей рабочей папки. ИИ может сам открыть AGENTS.md сайта, но это решение ИИ, а не гарантия механизма загрузки.

Файлы настроек в папках тоже наследуются по-разному

Помимо документов с правилами, инструменты по-разному работают с папками и для файлов настроек, например разрешений.

ПунктClaude CodeCodex
Файл настроек проекта.claude/settings.json.codex/config.toml
Из какой папки читается файлИз папки запуска (primary working directory); в отличие от CLAUDE.md, не наследуется от родительских папокОт корня проекта до папки запуска (более близкие имеют приоритет)
Связь с доверием (trust)Правила вроде allow действуют после того, как вы доверите папке; deny и ask действуют сразуЧитает .codex/ только в доверенных проектах

Источники: Claude Code settings и Monorepos and large repos от Anthropic, Config basics от OpenAI (проверено 1 ноября 2026 года).

3. Как проверить, что правила загрузились

Разложив правила, после запуска проверьте, загрузились ли они на самом деле. Способ зависит от инструмента, а в Claude Code правила, загруженные при запуске и позже, смотрят в разных местах.

Что проверитьClaude CodeCodex
Правила, загруженные при запускеСписок Memory files в /contextСпросить «Show which instruction files are active.» (это собственный отчёт ИИ; для надёжности используйте журнал ниже)
Правила, загруженные во время сеансаВ Memory files не показываются; при загрузке в терминале появляется строка Loaded с путёмВо время сеанса не добавляются (см. выше)
Сохранить записьХук InstructionsLoaded записывает, какие правила загружены, когда и почему (для AGENTS.md, прочитанного напрямую, он не срабатывает)Запустите codex -c log_dir=./.codex-log, чтобы писать журнал TUI (./.codex-log/codex-tui.log) и видеть, какие правила загружены

Источники: раздел об устранении неполадок в How Claude remembers your project от Anthropic и «Verify your setup» в Custom instructions with AGENTS.md от OpenAI (проверено 1 ноября 2026 года). Добавьте папку журнала в .gitignore, чтобы она не попала в git.

Чтобы проверить в Claude Code только что добавленный файл правил во вложенной папке, следуйте совету документации: создайте файл правил в оболочке, а не руками ИИ, затем попросите ИИ прочитать файл в этой папке и посмотрите, появится ли строка Loaded.

4. Обеспечивайте правила автоматическими проверками, а не документами

Как показал раздел 2, правила в папках могут не загрузиться — в зависимости от места запуска и инструмента. А даже загруженным правилам никто не гарантирует, что им последуют. Поэтому думайте о соблюдении правил в три слоя.

Документы с правилами
Объясняют причины и порядок действий CLAUDE.md и AGENTS.md. Они могут не загрузиться, а даже загруженным ничто не гарантирует соблюдения. Но они нужны ИИ, чтобы понять, почему что-то остановилось
Защита в инструменте
Останавливает действие до того, как оно произойдёт Хуки и настройки разрешений в ИИ-инструменте (в этой статье — «защита в инструменте»). В каждом инструменте они настраиваются по-своему и могут не сработать в зависимости от места запуска и настроек доверия
Проверка перед выпуском
Последний рубеж, каким бы инструментом ни делалась работа Если изменилось что-то за пределами закреплённой папки, останавливается сам процесс выпуска. Он не зависит от ИИ-инструмента

В нашей среде решающей защитой мы сделали нижний слой — проверку перед выпуском. Сменили ли вы ИИ-инструмент или работу делает человек напрямую — всё проходит через одну и ту же проверку.

Зона ответственности каждого агента — в настройке для каждого worktree

Дайте каждому сайту свой worktree (git worktree) и положите в верхнюю папку worktree небольшой файл настроек (.agent-owner) со списком папок, которые может менять работающий там агент. Если бы зона была записана в документе с правилами внутри репозитория, она была бы одинаковой во всех worktree и не могла бы различаться по месту. Не добавляйте файл настроек в git (впишите его в .git/info/exclude) и создавайте его вместе с worktree.

Обратите внимание: ИИ запускается не из верхней папки worktree, а из папки сайта внутри неё. Верхняя папка worktree совпадает с корнем репозитория, поэтому запуск оттуда даёт тот же результат, что и «корень репозитория» в разделе 2.

# Из основной копии (/srv/repo) создаём worktree для sites/blog в /srv/work-blog
cd /srv/repo
git worktree add /srv/work-blog -b blog-work
printf 'sites/blog/\n' > /srv/work-blog/.agent-owner
echo '.agent-owner' >> .git/info/exclude

# Запускаем ИИ из sites/blog/ внутри worktree
cd /srv/work-blog/sites/blog
claude        # или codex для Codex

# Перед выпуском запускаем проверку из основной копии, находясь в верхней папке worktree
cd /srv/work-blog
bash /srv/repo/tools/check-owner.sh origin/main

Запускайте скрипт проверки из основной копии (где ИИ не работает) или из CI, а не его копию внутри worktree. Если запускать копию из worktree, ИИ, переписавший сам скрипт проверки, пройдёт её беспрепятственно.

Останавливайте выпуск, если что-то изменилось вне зоны ответственности

Поставьте следующую проверку (tools/check-owner.sh выше) в начало процесса выпуска. Она исходит из того, что выпуск делается только из коммитов: останавливается, если остались незакоммиченные изменения, и останавливается, если закоммиченный diff относительно базы (origin/main или подобной) содержит хотя бы один файл вне закреплённых папок. Она читает .agent-owner, поэтому запускайте её в верхней папке worktree.

#!/usr/bin/env bash
# Запускать в верхней папке worktree перед выпуском: остановить, если изменилось что-то вне закреплённых папок
set -euo pipefail

base="${1:-origin/main}"
owner_file=".agent-owner"   # в верхней папке worktree, вне git

if [ ! -s "$owner_file" ]; then
  echo "Нет файла зоны ответственности ($owner_file). Выпуск остановлен" >&2
  exit 1
fi

# Остановить, если остались незакоммиченные изменения (выпуск только из коммитов)
if [ -n "$(git status --porcelain)" ]; then
  echo "Есть незакоммиченные изменения. Выпуск остановлен" >&2
  exit 1
fi

# --no-renames: перемещение из другой папки считается удалением и добавлением
# К каждой записи зоны добавляется / в конце (чтобы sites/blog не совпадал с sites/blog-old)
# Проверено с gawk (Git Bash). BSD awk может не сработать, если значение -v содержит переводы строк
outside=$(git diff --name-only --no-renames "$base"...HEAD |
  awk -v list="$(tr -d '\r' < "$owner_file")" '
    BEGIN { n = split(list, own, "\n")
            for (i = 1; i <= n; i++) if (own[i] != "" && substr(own[i], length(own[i])) != "/") own[i] = own[i] "/" }
    { ok = 0; for (i = 1; i <= n; i++) if (own[i] != "" && index($0, own[i]) == 1) ok = 1
      if (!ok) print }')

if [ -n "$outside" ]; then
  echo "Изменены файлы вне зоны ответственности. Выпуск остановлен:" >&2
  echo "$outside" >&2
  exit 1
fi
echo "Изменения только в зоне ответственности"

Ниже — результаты, когда Claude Code, написавший эту статью, 1 ноября 2026 года собрал тестовый репозиторий с двумя сайтами и общей папкой и запустил проверку с Git 2.56 (Git Bash в Windows).

Что пробовалиРезультат
Агент blog изменил только файлы blogПроходит
Перенесли файл shop в папку blogОстанавливается (в списке — исходный файл shop)
Изменили файл в общей папкеОстанавливается (общая папка вне зоны, если не указана)
Записали зону без / в конце и добавили sites/blog-old/Останавливается (версия без добавления / это пропускала)
Оставили незакоммиченные изменения в shopОстанавливается (версия, проверяющая только закоммиченный diff, это упускает)
Удалили файл зоны ответственностиОстанавливается

Именно --no-renames не даёт перемещениям проскочить. Без него git показывает изменение, которое считает перемещением, только под новым именем, и перенос файлов из другого сайта остаётся незамеченным. Кроме того, при отсутствии файла настроек проверка «останавливает», а не «пропускает», чтобы не прошёл worktree, для которого зона так и не была задана.

Эта проверка защищает от путаницы, а не от намеренных нарушений. Если ИИ перепишет .agent-owner, проверка пройдёт. Чтобы предотвратить и это, запретите правку этого файла настроек тоже — защитой в инструменте, описанной ниже.

Добавьте защиту в инструменте

Если останавливать только перед выпуском, вы узнаете о проблеме, когда ИИ уже переписал что-то вне зоны. Чтобы остановить его до записи, добавьте собственные возможности инструментов.

ПунктClaude CodeCodex
Запрет записи в файлыДобавить Edit(путь) в deny в настройках разрешений (действует на встроенные инструменты и на команды, которые распознаёт Claude Code, например sed, tee и перенаправления)В хуке PreToolUse проверить, куда пишет apply_patch (он также совпадает как Edit и Write), и вернуть deny в permissionDecision
Запрет командДобавить Bash(команда *) в deny или вернуть код выхода 2 либо JSON с отказом из хука PreToolUseПравило prefix_rule(pattern=[...], decision="forbidden") (экспериментальное) и хуки PreToolUse
Запрет для любого процессаПесочница (deny не остановит скрипт, который сам открывает и пишет файлы)Песочница (sandbox_mode = "workspace-write" ограничивает запись папкой запуска; writable roots добавляют места для записи, так что не добавляйте их без нужды)
Условия при размещении в проектеЧитает .claude/settings.json в папке запуска; deny действует ещё до того, как вы доверите папкеЧитает .codex/ проекта, только если проект доверенный; хуки не запускаются, пока вы их не просмотрите и не доверите им

Источники: Configure permissions и Hooks guide от Anthropic, Hooks и Rules от OpenAI (проверено 1 ноября 2026 года).

В Claude Code настройки, которые не дают worktree blog менять файл зоны ответственности (.agent-owner), скрипты проверки (tools/), правила корня, shop и общую папку, выглядят так (предполагается, что worktree находится в /srv/work-blog). Пути, начинающиеся с //, — абсолютные. Расположение worktree на каждой машине своё, поэтому добавляйте эти строки в пользовательские настройки этой машины (~/.claude/settings.json) при создании worktree, а не в настройки, хранящиеся в репозитории.

{
  "permissions": {
    "deny": [
      "Edit(//srv/work-blog/.agent-owner)",
      "Edit(//srv/work-blog/tools/**)",
      "Edit(//srv/work-blog/CLAUDE.md)",
      "Edit(//srv/work-blog/AGENTS.md)",
      "Edit(//srv/work-blog/sites/shop/**)",
      "Edit(//srv/work-blog/sites/shared/**)",
      "Edit(//srv/repo/**)"
    ]
  }
}

В Codex зарегистрируйте скрипт проверки в разделе PreToolUse конфигурации хуков (личный ~/.codex/hooks.json, .codex/hooks.json репозитория и т. п.) с apply_patch в качестве matcher. Хуки не запускаются, пока вы не просмотрите их и не доверите им через /hooks в Codex (после изменения им нужно доверить заново).

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "^apply_patch$",
        "hooks": [ { "type": "command", "command": "python3 ~/.codex/hooks/owner_guard.py" } ] }
    ]
  }
}

Скрипт проверки извлекает целевые пути из строк *** Add File:, *** Update File:, *** Delete File: и *** Move to: во входных данных apply_patch и возвращает deny, если хотя бы один путь вне зоны или защищён. Вот минимальный пример.

import json, posixpath, re, sys

# Хук PreToolUse для Codex: остановить apply_patch, если он меняет файлы вне зоны или защищённые файлы
OWN = ["/srv/work-blog/sites/blog/"]                  # зона ответственности (с / в конце)
PROTECT = ["/srv/work-blog/.agent-owner", "/srv/work-blog/tools/"]

event = json.load(sys.stdin)
command = event.get("tool_input", {}).get("command", "")
if isinstance(command, list):
    command = "\n".join(command)

bad = []
for m in re.finditer(r"^\*\*\* (?:Add File|Update File|Delete File|Move to): (.+)$", command, re.M):
    path = posixpath.normpath(posixpath.join(event.get("cwd", ""), m.group(1).strip()))
    if not any(path.startswith(o) for o in OWN) or any(path.startswith(p) for p in PROTECT):
        bad.append(path)

if bad:
    print(json.dumps({"hookSpecificOutput": {
        "hookEventName": "PreToolUse",
        "permissionDecision": "deny",
        "permissionDecisionReason": "Файлы вне зоны ответственности: " + ", ".join(bad)}}, ensure_ascii=False))

Claude Code, написавший эту статью, запустил этот скрипт на вручную составленных входных данных в формате, который передаёт Codex (в зоне, shop, .agent-owner, перемещение в shared и удаление внутри tools/), и убедился, что прошло только изменение в зоне. Внутри Codex мы его не запускали.

Команды Bash можно записать множеством способов, поэтому хук не может полностью определить, куда они пишут. Сама OpenAI называет хуки полезным ограждением, а не полной границей принуждения («a useful guardrail, not a complete enforcement boundary»). Команды, которые нужно остановить, например rm, запрещайте правилом с decision = "forbidden", а остальное пусть ловит проверка перед выпуском. Правила кладутся в папку rules/ слоя конфигурации, например ~/.codex/rules/default.rules. .codex/rules/ проекта читается, только если проект доверенный.

Защиту в инструменте приходится переписывать под каждый инструмент, и она может не сработать в зависимости от места запуска и настроек доверия. Поэтому опирайтесь на проверку перед выпуском, через которую в итоге проходит любое изменение, а защиту в инструменте добавляйте сверху, чтобы ловить проблемы раньше. О том, как писать хуки Claude Code, — в статье «Что такое хуки Claude Code? Запуск shell-команд детерминированно»; о настройках только для чтения — в статье «Codex и Claude Code в режиме только чтения: как ограничить работу исследованием и советами».

5. Ещё на что обратить внимание: путаница репозиториев и переменные окружения

В той же среде, когда ИИ передавали несколько репозиториев, случилось ещё два эпизода. Оба удалось поймать до того, как они стали серьёзными инцидентами, но, независимо от того, как вы раскладываете правила, заведите для них процедуры.

Различайте репозитории с похожими названиями по удалённому URL

ИИ решил, что репозиторий другого сервиса с очень похожим названием — «старая копия того же сервиса», и перенёс его в другое место (его сразу вернули, содержимое не изменилось). Довод был такой: «локальных изменений нет, последнее обновление давнее», но это лишь показывает, что «ничего не меняется прямо сейчас» и «недавно его никто не правил». Чем стабильнее работает сервис, тем реже он обновляется.

Прежде чем что-то переносить или удалять, выполните следующее и в целевой папке, и в папке, которая используется в продакшене, и сравните результаты рядом.

# Удалённый URL (перед выводом уберите токен или пароль, встроенный в URL)
git -C <папка> remote get-url origin | sed -E 's#://[^/@]+@#://#'

# Сначала убедитесь, что это не поверхностный клон (если true, следующий результат ненадёжен)
git -C <папка> rev-parse --is-shallow-repository

# Корневой коммит (у копий, ответвившихся от одной истории, он общий)
git -C <папка> rev-list --max-parents=0 HEAD
  • Сравнивайте удалённые URL по хосту и пути к репозиторию: https://github.com/org/app.git и git@github.com:org/app.git — один и тот же репозиторий, записанный по-разному; и наоборот, из-за зеркал или псевдонимов хостов один и тот же репозиторий может выглядеть по-разному
  • В поверхностном клоне корневой коммит — не настоящий первый коммит: в клоне, полученном с --depth 1, вы получите самый старый из загруженных коммитов (в нашем тесте — сам HEAD)
  • Не выводите токены, встроенные в URL: удалённый URL может содержать токен аутентификации, и его вывод как есть раскрывает секрет в выводе — так же, как с переменными окружения ниже

Даже если сравнение показало, что это «неиспользуемая копия», не удаляйте её сразу; сначала перенесите в другое место. Запишите, куда перенесли, где она лежала и команду для возврата, и удаляйте только после того, как какое-то время убедитесь, что ничего не сломалось. В нашей среде путаницу удалось сразу исправить именно потому, что папку перенесли, а не удалили.

Смотрите только имена переменных окружения

ИИ выполнил команду для просмотра конфигурации контейнера, которая вывела переменные окружения вместе со значениями, и в выводе оказалась строка подключения к базе данных (вместе с паролем). Значение, попавшее в вывод, остаётся в журнале разговора и к тому же отправляется модели. Если нужно лишь увидеть, что задано, достаточно имён.

Переменные окружения контейнера

Показывает значения (не использовать)

docker inspect <контейнер>
docker exec <контейнер> printenv
docker exec <контейнер> sh -c 'env | cut -d= -f1'

Только имена

docker inspect --format '{{range .Config.Env}}{{index (split . "=") 0}}{{println}}{{end}}' <контейнер>
docker exec <контейнер> awk 'BEGIN{for(k in ENVIRON) print k}'

Без параметров docker inspect выводит всю конфигурацию, и её Env содержит значения как есть. В контейнерах без awk используйте docker inspect --format.

Конфигурация Docker Compose

Показывает значения (не использовать)

docker compose config

Без подстановки переменных

docker compose config --no-interpolate

С --no-interpolate ${DB_URL} показывается как есть, а для env_file выводится только путь к файлу. Переменные, значения которых записаны прямо в compose.yaml, показываются.

Локальная оболочка

Показывает значения (не использовать)

env
printenv
Get-ChildItem Env:

Только имена

compgen -e                  # bash
(Get-ChildItem Env:).Name   # PowerShell

Ниже — результаты, когда Claude Code, написавший эту статью, 1 ноября 2026 года проверил это на фиктивных значениях с Docker 29.8 и Docker Compose v5.6. В контейнере, где одно значение содержало переводы строк (так передают содержимое файла ключа), команда env | cut -d= -f1 вывела вторую и третью строки значения как есть, вперемешку с именами переменных. ENVIRON в awk и docker inspect --format значений не показали. docker compose config вывел фиктивные значения, записанные в .env и env_file; с --no-interpolate ни те, ни другие не появились, и было показано только значение, записанное прямо в compose.yaml.

Для надёжности впишите «смотреть только имена переменных окружения» в документы с правилами, а также запретите команды, выводящие значения, защитой в инструменте из раздела 4. Если значение всё же вывелось, считайте его «увиденным» и решите, нужно ли его сменить. О настройке Codex, которая вообще не передаёт переменные окружения в команды ИИ, — в разделе 6 статьи «Как не дать Codex читать секретные файлы: разрешения, согласование и ограничения сети».

6. Чек-лист перед передачей работы

  • Решено, что для работы над сайтом ИИ запускается из папки сайта внутри worktree
  • После запуска подтверждено, что правила сайта включены: Memory files в /context для Claude Code, список активных файлов инструкций для Codex
  • Для работы, запущенной из корня, подготовлен способ увидеть, загрузились ли правила вложенных папок во время сеанса (строка Loaded в Claude Code, хук InstructionsLoaded)
  • Добавлена проверка, которая останавливает выпуск, если изменилось что-то вне закреплённых папок, и проверено, что она останавливается на намеренном изменении вне зоны
  • Зона ответственности каждого worktree записана с / в конце, и проверка останавливается, если файла зоны нет
  • Защитой в инструменте запрещена запись вне зоны и в файл зоны
  • В правила вписана процедура: перед переносом или удалением папки сравнить удалённый URL и корневой коммит с продакшеном и переносить, а не удалять
  • В правила вписаны команды, показывающие только имена переменных окружения, а команды, выводящие значения, запрещены защитой в инструменте
Пример текста для документов с правилами (можно использовать как есть)
## Правила при работе с несколькими проектами
- Зона ответственности этого worktree — только папки, перечисленные в .agent-owner. Не меняйте файлы вне её
  (изменения там останавливают проверку перед выпуском)
- Перед переносом или удалением папки сравните git remote get-url origin и
  git rev-list --max-parents=0 HEAD с продакшеном (учитывайте поверхностные клоны).
  Переносите, а не удаляйте, и записывайте, как вернуть
- Смотрите только имена переменных окружения. Не используйте env, printenv, docker inspect (без --format) и
  docker compose config (без --no-interpolate)

Пишите документы не как средство принуждения, а как объяснение — чтобы, когда что-то остановилось, ИИ понял причину и выбрал правильную процедуру.

Итоги

  • При запуске из корня правила в папке каждого сайта Claude Code не загружает, пока не обратится к файлам этой папки, а Codex не загружает автоматически (ИИ может открыть их сам, но гарантии нет)
  • В обоих инструментах запуск из папки сайта загружает правила этого сайта с самого начала (с worktree — запускайте из папки сайта внутри него)
  • Что загружено при запуске, проверяйте через /context в Claude Code или список активных файлов инструкций в Codex, а что Claude Code загрузил во время сеанса — по строке Loaded или хуку InstructionsLoaded
  • То, что обязательно к соблюдению, превратите в автоматическую проверку, останавливающую выпуск при изменениях вне закреплённых папок, а защиту в инструменте добавьте сверху, чтобы ловить проблемы раньше
  • Кроме того, различайте репозитории с похожими названиями по удалённому URL и корневому коммиту и смотрите только имена переменных окружения

Вопросы и ответы

В. Загружается ли CLAUDE.md во вложенной папке?

О. Да, но не при запуске. Claude Code загружает CLAUDE.md папки, когда Claude читает, записывает или редактирует файл внутри неё. В этот момент он не появляется в Memory files в /context; вместо этого в терминале появляется строка Loaded с путём. Если запустить из этой папки, файл загружается при запуске и отображается в Memory files.

В. Как заставить Codex прочитать AGENTS.md во вложенной папке?

О. Запустите Codex из этой папки (в CLI — codex --cd <папка>). При запуске Codex читает файлы AGENTS.md от корня проекта до папки запуска и ниже неё не ищет. Если запустить из корня, AGENTS.md вложенной папки будет прочитан, если ИИ откроет его сам, но официальная документация не предлагает настройки, которая гарантированно его загружает.

В. Стоит ли в монорепозитории собрать документы с правилами в один файл в корне?

О. Документация обоих инструментов рекомендует класть правила для всего репозитория в корень, а правила конкретного сайта — в папку сайта. Однако правила сайта могут не загрузиться, если не запускать из его папки, поэтому всё, игнорирование чего приведёт к проблемам, выносите из документов в проверку перед выпуском или защиту в инструменте.

В. Как заставить Claude Code читать и CLAUDE.md, и AGENTS.md?

О. По умолчанию, если в папке запуска или выше есть CLAUDE.md, .claude/CLAUDE.md или CLAUDE.local.md, AGENTS.md не читается. Либо импортируйте его одной строкой @AGENTS.md в CLAUDE.md, либо задайте в /config параметру Project instructions значение claude-md-and-agents-md.

Источники