Правила: инструкции, которые агент всегда читает (always / auto / agent / manual)
Что это
Правило (rule) — это короткая инструкция для агента: «всегда фильтруй SQL-запрос по organization_id», «не хардкодь строки, добавляй их в обе локали», «спрашивай подтверждение перед миграцией». В движке Quest правило — не абзац в общем промпте, а отдельный типизированный объект с телом и режимом активации. Режим отвечает на один вопрос: когда именно эту инструкцию класть в контекст модели.
Режимов ровно четыре (в схеме это ruleActivationEnum):
always— правило постоянно в контексте, в каждом запросе. Для фундамента: устав проекта, красные линии, стек.auto— подключается автоматически, когда агент работает с файлами по glob-паттернам (например**/*.tsили**/locales/*.json).agent— модель сама решает, релевантно ли правило, по егоdescription. Вы пишете описание-триггер вроде «когда добавляешь платёжный флоу», и агент подтягивает правило, когда узнаёт задачу.manual— молчит, пока вы явно не позовёте его (в Cursor — через@имя-правила).
Зачем так
Контекст модели — дефицит. Если сложить все правила в always, каждый токен тратится в каждом запросе, важное тонет в шуме, а слабая модель начинает игнорировать инструкции. Отраслевой консенсус прямой: always-правила держи короткими, всё остальное подключай условно (это ровно та же модель, что у Cursor Project Rules — и это честное совпадение, а не наше изобретение). Гранулярность = дисциплина без раздувания: правило про миграции включается только когда трогают миграции, правило про a11y — только на UI.
Когда какой режим
- Инвариант, нарушение которого ломает продукт (изоляция арендаторов, fail-closed биллинг-гейт, «секреты не в файлах») →
always. - Правило, привязанное к типу файла (SQL-слой, локали, миграции, компоненты) →
autoс точными globs. - Правило под класс задач, который не опознать по расширению файла («перед новой зависимостью — проверь reuse-first») →
agentс ясным description. - Редкий чек-лист, который нужен изредка и по требованию →
manual.
Worked-пример: одно правило → три таргета
Вход. В базовом движке Quest есть гранулярное правило tenancy (изоляция организаций), заданное так: activation: 'auto', globs: ['**/*.{ts,py,go,rb,java}'], тело — «каждый запрос фильтрует по тенант-скоупу, включая count/exists; сокеты — через auth; SQL параметризован; нашёл одну cross-tenant дыру → grep класс, чини все».
Что делает движок (компилятор детерминированно раскладывает под таргет):
- Cursor → отдельный файл
.cursor/rules/tenancy.mdcс обязательным frontmatter под режимauto:
---
description: Multi-tenant изоляция
globs: **/*.{ts,py,go,rb,java}
alwaysApply: false
---
Стоит открыть серверный .ts — Cursor сам подхватывает правило. (Важная деталь из ресёрча, вшитая в компилятор: .mdc без frontmatter Cursor молча игнорирует, а globs должны быть строкой, не массивом — иначе тоже не применятся. Движок это гарантирует.)
Claude Code → файл
.claude/rules/tenancy.md, где тело обёрнуто с указанием путей-globs.AGENTS.md (универсальный таргет для VS Code/Copilot и прочих) → секция правил в одном файле: тела
always-правил идут целиком,auto— тело плюс строка «Применяется к файлам:**/*.{ts,py,go,rb,java}», аagent/manual— кратко, чтобы не раздувать всегда-читаемый файл.
Результат. Один объект-правило из спеки превращается в родной механизм каждого редактора. Пишете правило один раз — работает в трёх средах, с правильным режимом активации в каждой.
Честная граница (ENFORCED vs ADVISORY)
Правило — это инструкция, а не физический барьер. Оно советует модели, но само по себе не блокирует нарушение кодом возврата. Жёсткая блокировка (ENFORCED) сегодня есть только в Claude Code через PreToolUse-hook для опасных команд (rm -rf, DROP TABLE, git push --force); на Cursor и в чистом AGENTS.md правила работают как строгая ADVISORY-инструкция. Переносимый git/CI-предохранитель (Portable Safety Floor), который сделал бы инварианты enforced и вне Claude, — в дорожной карте (roadmap), пока не выпущен. Смысл движка — сделать эти инструкции настолько буквальными и проверяемыми, чтобы даже слабая модель их исполняла, а не «догадывалась».
Sources: