Модуль 1 · Идея и спецификация · урок 4 из 13
Правила проекта с первого дня
В новом проекте нет истории, и агент берёт решения из головы — точнее, из обучающих данных. Пока кода мало, это незаметно. Через двадцать сессий в проекте оказываются три способа обработки ошибок и два формата дат. Правила, записанные в первый день, дешевле, чем уборка через месяц.
Зачем до первой фичи
Codex воспроизводит шаблоны, которые уже есть в репозитории, — в том числе неудачные. Первые срезы задают образец для всех следующих. Если в первом эндпоинте нет валидации, её не будет и в двадцатом: агент посмотрит на соседний код и сделает так же.
Базово AGENTS.md разобран в уроке курса «Codex с нуля». Здесь — что писать в него для молодого продукта.
Заготовка и правка
Команда /init создаёт стартовый AGENTS.md по содержимому репозитория. В пустом проекте она мало что найдёт, поэтому используйте её как черновик и допишите главное сами. Документация в разделе best practices перечисляет, что туда класть: устройство репозитория, как запускать проект, команды сборки, тестов и линта, соглашения, запреты и что значит «готово».
# Переговорки
Внутренний сервис брони переговорных. Что строим и правила (R1…R5) —
docs/SPEC.md. Порядок работ — docs/PLAN.md. Решения — docs/decisions/.
## Структура
- apps/api — Fastify + Prisma. Маршруты в src/routes, логика в src/services.
- apps/web — React + Vite. Страницы в src/pages, общие компоненты в src/ui.
- packages/shared — Zod-схемы запросов и ответов. Единственный источник типов API.
## Команды
- npm run dev — API и web локально (нужен docker compose up -d)
- npm run check — lint + typecheck + unit/интеграционные тесты
- npm run test:e2e — Playwright, требует запущенного dev
- npm run db:migrate -- --name <имя> — новая миграция
## Готово, когда
- npm run check зелёный, для изменений интерфейса — ещё test:e2e.
- Новое поведение покрыто тестом, тест ссылается на правило (R3) или сценарий (S2).
- В docs/PLAN.md отмечен пункт; если менялись правила — обновлён docs/SPEC.md.
## Соглашения
- Время в базе — timestamptz, в API — ISO 8601 с зоной, в интерфейсе —
Europe/Moscow. Даты считаем через date-fns, не вручную.
- Любой вход в API валидируется Zod-схемой из packages/shared.
- Ошибки API: { error: { code, message } }, коды — в shared/errors.ts.
- Без новых зависимостей без явной просьбы. Если очень нужна — спроси.
## Нельзя
- Править или удалять существующие тесты, чтобы они прошли. Сообщи о конфликте.
- Писать SQL строками с подстановкой значений. Только Prisma или $queryRaw с параметрами.
- Читать и создавать .env; секреты не печатать в логах и ответах.
- Менять применённые миграции — только новая миграция.
## Code Review Rules
- Каждый маршрут, меняющий данные, проверяет права (R4); без проверки — P1.
- Проверка пересечения броней только в базе (R3); проверка лишь в коде — гонка.Обратите внимание на ссылки на правила спецификации. Агенту не нужно пересказывать бизнес-логику — достаточно сказать, где она.
Держите файл коротким
AGENTS.md загружается в каждую сессию и занимает контекст. У Codex есть предел суммарного объёма инструкций — по умолчанию 32 KiB, сверх него файлы просто не добавляются (подробнее в документации AGENTS.md). Но проблема наступает раньше: когда важно всё, не важно ничего.
Рабочее правило из best practices: добавлять правило, когда видите повторяющуюся ошибку, а не на всякий случай. Если агент дважды сделал одно и то же неправильно — попросите ретроспективу:
Ты второй раз считаешь конец брони через getHours() вместо date-fns.
Разбери, почему так вышло, и предложи одну строку в AGENTS.md,
которая предотвратит это в будущих сессиях. Не меняй код.Проверьте, что правила загружены
После правки AGENTS.md перезапустите сессию — файлы читаются при старте. Проверить, что агент видит, можно так:
codex --sandbox read-only --ask-for-approval never "Summarize the current instructions."Если пересказ не совпадает с тем, что вы написали, ищите конфликт: другой AGENTS.md в подкаталоге или AGENTS.override.md.
От правила к проверке
Правило в AGENTS.md — просьба. Агент может её забыть или посчитать неприменимой. Всё, что можно проверить механически, переносите в инструменты. Тогда нарушение ловит npm run check, а сообщение об ошибке подсказывает, как исправить:
import tseslint from "typescript-eslint";
export default tseslint.config(...tseslint.configs.recommended, {
rules: {
"no-restricted-syntax": [
"error",
{
selector: "CallExpression[callee.property.name=/^(getHours|setHours)$/]",
message: "Время брони считаем через date-fns в зоне Europe/Moscow, см. AGENTS.md → Соглашения.",
},
],
"no-restricted-imports": [
"error",
{ patterns: [{ group: ["**/web/src/**"], message: "API не импортирует код интерфейса. Общее — в packages/shared." }] },
],
},
});В статье OpenAI о harness engineering описан тот же приём: сообщения линтеров пишутся как инструкции по исправлению, чтобы агент получал их прямо в контекст. Глубже эта идея разобрана в уроке об инвариантах.
Раздел для ревью
Раздел ## Code Review Rules читает ревью Codex в GitHub; как с ним работает GitLab-интеграция (она пока в бете), сверяйтесь с документацией по ревью. Документация советует начинать с двух-трёх правил, описывать, что именно считать проблемой и какой путь безопасен, а форматирование оставлять CI. Тот же раздел полезен и при локальном /review: попросите ревьюера сверяться с ним.
Попробуйте сами
10–15 мин на рабочем месте- Запустите
/initв своём проекте и перепишите результат по структуре выше: структура, команды, «готово», соглашения, запреты. Уложитесь в 60 строк. - Проверьте загрузку командой
codex --sandbox read-only --ask-for-approval never "Summarize the current instructions.". - Выберите одно правило из AGENTS.md, которое можно проверить машиной, и превратите его в правило линтера с понятным сообщением.
Коротко
- Первые срезы задают образец: агент копирует то, что видит в репозитории.
- AGENTS.md — короткая карта: структура, команды, «готово», соглашения, запреты.
- Ссылайтесь на спецификацию, а не пересказывайте её.
- Новое правило — после повторяющейся ошибки, через ретроспективу.
- Всё, что проверяется машиной, переносите в линтер и тесты с подсказкой в сообщении.